diff --git a/sdk/perfetto.cc b/sdk/perfetto.cc
new file mode 100644
index 0000000..489ae85
--- /dev/null
+++ b/sdk/perfetto.cc
@@ -0,0 +1,62692 @@
+// Copyright (C) 2019 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.
+//
+// This file is automatically generated by gen_amalgamated. Do not edit.
+
+// gen_amalgamated: predefined macros
+#if !defined(PERFETTO_IMPLEMENTATION)
+#define PERFETTO_IMPLEMENTATION
+#endif
+#include "perfetto.h"
+// gen_amalgamated begin source: src/base/default_platform.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/platform.h
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_PLATFORM_H_
+#define INCLUDE_PERFETTO_EXT_BASE_PLATFORM_H_
+
+namespace perfetto {
+namespace base {
+namespace platform {
+
+// Executed before entering a syscall (e.g. poll, read, write etc) which might
+// block.
+// This is overridden in Google internal builds for dealing with userspace
+// scheduling.
+void BeforeMaybeBlockingSyscall();
+
+// Executed after entering a syscall (e.g. poll, read, write etc) which might
+// block.
+// This is overridden in Google internal builds for dealing with userspace
+// scheduling.
+void AfterMaybeBlockingSyscall();
+
+}  // namespace platform
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_PLATFORM_H_
+/*
+ * Copyright (C) 2023 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
+
+namespace perfetto {
+namespace base {
+namespace platform {
+
+// This is a no-op outside of Google3 where we have some custom logic to deal
+// with the userspace scheduler.
+void BeforeMaybeBlockingSyscall() {}
+
+// This is a no-op outside of Google3 where we have some custom logic to deal
+// with the userspace scheduler.
+void AfterMaybeBlockingSyscall() {}
+
+}  // namespace platform
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/android_utils.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/android_utils.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+// Returns the value of the Android system property named `name`. If the
+// property does not exist, returns an empty string (a non-existing property is
+// the same as a property with an empty value for this API).
+std::string GetAndroidProp(const char* name);
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/android_utils.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <string>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/system_properties.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+std::string GetAndroidProp(const char* name) {
+  std::string ret;
+#if __ANDROID_API__ >= 26
+  const prop_info* pi = __system_property_find(name);
+  if (!pi) {
+    return ret;
+  }
+  __system_property_read_callback(
+      pi,
+      [](void* dst_void, const char*, const char* value, uint32_t) {
+        std::string& dst = *static_cast<std::string*>(dst_void);
+        dst = value;
+      },
+      &ret);
+#else  // __ANDROID_API__ < 26
+  char value_buf[PROP_VALUE_MAX];
+  int len = __system_property_get(name, value_buf);
+  if (len > 0 && static_cast<size_t>(len) < sizeof(value_buf)) {
+    ret = std::string(value_buf, static_cast<size_t>(len));
+  }
+#endif
+  return ret;
+}
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/base64.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/base64.h
+// gen_amalgamated begin header: include/perfetto/ext/base/string_view.h
+// gen_amalgamated begin header: include/perfetto/ext/base/hash.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_HASH_H_
+#define INCLUDE_PERFETTO_EXT_BASE_HASH_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string>
+#include <type_traits>
+#include <utility>
+
+namespace perfetto {
+namespace base {
+
+// A helper class which computes a 64-bit hash of the input data.
+// The algorithm used is FNV-1a as it is fast and easy to implement and has
+// relatively few collisions.
+// WARNING: This hash function should not be used for any cryptographic purpose.
+class Hasher {
+ public:
+  // Creates an empty hash object
+  Hasher() {}
+
+  // Hashes a numeric value.
+  template <
+      typename T,
+      typename std::enable_if<std::is_arithmetic<T>::value, bool>::type = true>
+  void Update(T data) {
+    Update(reinterpret_cast<const char*>(&data), sizeof(data));
+  }
+
+  // Using the loop instead of "Update(str, strlen(str))" to avoid looping twice
+  void Update(const char* str) {
+    for (const auto* p = str; *p; ++p)
+      Update(*p);
+  }
+
+  // Hashes a byte array.
+  void Update(const char* data, size_t size) {
+    for (size_t i = 0; i < size; i++) {
+      result_ ^= static_cast<uint8_t>(data[i]);
+      // Note: Arithmetic overflow of unsigned integers is well defined in C++
+      // standard unlike signed integers.
+      // https://stackoverflow.com/a/41280273
+      result_ *= kFnv1a64Prime;
+    }
+  }
+
+  // Allow hashing anything that has a |data| field, a |size| field,
+  // and has the kHashable trait (e.g., base::StringView).
+  template <typename T, typename = std::enable_if<T::kHashable>>
+  void Update(const T& t) {
+    Update(t.data(), t.size());
+  }
+
+  void Update(const std::string& s) { Update(s.data(), s.size()); }
+
+  uint64_t digest() const { return result_; }
+
+  // Usage:
+  // uint64_t hashed_value = Hash::Combine(33, false, "ABC", 458L, 3u, 'x');
+  template <typename... Ts>
+  static uint64_t Combine(Ts&&... args) {
+    Hasher hasher;
+    hasher.UpdateAll(std::forward<Ts>(args)...);
+    return hasher.digest();
+  }
+
+  // `hasher.UpdateAll(33, false, "ABC")` is shorthand for:
+  // `hasher.Update(33); hasher.Update(false); hasher.Update("ABC");`
+  void UpdateAll() {}
+
+  template <typename T, typename... Ts>
+  void UpdateAll(T&& arg, Ts&&... args) {
+    Update(arg);
+    UpdateAll(std::forward<Ts>(args)...);
+  }
+
+ private:
+  static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
+  static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
+
+  uint64_t result_ = kFnv1a64OffsetBasis;
+};
+
+// This is for using already-hashed key into std::unordered_map and avoid the
+// cost of re-hashing. Example:
+// unordered_map<uint64_t, Value, AlreadyHashed> my_map.
+template <typename T>
+struct AlreadyHashed {
+  size_t operator()(const T& x) const { return static_cast<size_t>(x); }
+};
+
+// base::Hash uses base::Hasher for integer values and falls base to std::hash
+// for other types. This is needed as std::hash for integers is just the
+// identity function and Perfetto uses open-addressing hash table, which are
+// very sensitive to hash quality and are known to degrade in performance
+// when using std::hash.
+template <typename T>
+struct Hash {
+  // Version for ints, using base::Hasher.
+  template <typename U = T>
+  auto operator()(const U& x) ->
+      typename std::enable_if<std::is_arithmetic<U>::value, size_t>::type
+      const {
+    Hasher hash;
+    hash.Update(x);
+    return static_cast<size_t>(hash.digest());
+  }
+
+  // Version for non-ints, falling back to std::hash.
+  template <typename U = T>
+  auto operator()(const U& x) ->
+      typename std::enable_if<!std::is_arithmetic<U>::value, size_t>::type
+      const {
+    return std::hash<U>()(x);
+  }
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_HASH_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
+#define INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
+
+#include <string.h>
+
+#include <algorithm>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+
+namespace perfetto {
+namespace base {
+
+// A string-like object that refers to a non-owned piece of memory.
+// Strings are internally NOT null terminated.
+class StringView {
+ public:
+  // Allow hashing with base::Hash.
+  static constexpr bool kHashable = true;
+  static constexpr size_t npos = static_cast<size_t>(-1);
+
+  StringView() : data_(nullptr), size_(0) {}
+  StringView(const StringView&) = default;
+  StringView& operator=(const StringView&) = default;
+  StringView(const char* data, size_t size) : data_(data), size_(size) {
+    PERFETTO_DCHECK(size == 0 || data != nullptr);
+  }
+
+  // Allow implicit conversion from any class that has a |data| and |size| field
+  // and has the kConvertibleToStringView trait (e.g., protozero::ConstChars).
+  template <typename T, typename = std::enable_if<T::kConvertibleToStringView>>
+  StringView(const T& x) : StringView(x.data, x.size) {
+    PERFETTO_DCHECK(x.size == 0 || x.data != nullptr);
+  }
+
+  // Creates a StringView from a null-terminated C string.
+  // Deliberately not "explicit".
+  StringView(const char* cstr) : data_(cstr), size_(strlen(cstr)) {
+    PERFETTO_DCHECK(cstr != nullptr);
+  }
+
+  // This instead has to be explicit, as creating a StringView out of a
+  // std::string can be subtle.
+  explicit StringView(const std::string& str)
+      : data_(str.data()), size_(str.size()) {}
+
+  bool empty() const { return size_ == 0; }
+  size_t size() const { return size_; }
+  const char* data() const { return data_; }
+  const char* begin() const { return data_; }
+  const char* end() const { return data_ + size_; }
+
+  char at(size_t pos) const {
+    PERFETTO_DCHECK(pos < size_);
+    return data_[pos];
+  }
+
+  size_t find(char c, size_t start_pos = 0) const {
+    for (size_t i = start_pos; i < size_; ++i) {
+      if (data_[i] == c)
+        return i;
+    }
+    return npos;
+  }
+
+  size_t find(const StringView& str, size_t start_pos = 0) const {
+    if (start_pos > size())
+      return npos;
+    auto it = std::search(begin() + start_pos, end(), str.begin(), str.end());
+    size_t pos = static_cast<size_t>(it - begin());
+    return pos + str.size() <= size() ? pos : npos;
+  }
+
+  size_t find(const char* str, size_t start_pos = 0) const {
+    return find(StringView(str), start_pos);
+  }
+
+  size_t rfind(char c) const {
+    for (size_t i = size_; i > 0; --i) {
+      if (data_[i - 1] == c)
+        return i - 1;
+    }
+    return npos;
+  }
+
+  StringView substr(size_t pos, size_t count = npos) const {
+    if (pos >= size_)
+      return StringView("", 0);
+    size_t rcount = std::min(count, size_ - pos);
+    return StringView(data_ + pos, rcount);
+  }
+
+  bool CaseInsensitiveEq(const StringView& other) const {
+    if (size() != other.size())
+      return false;
+    if (size() == 0)
+      return true;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    return _strnicmp(data(), other.data(), size()) == 0;
+#else
+    return strncasecmp(data(), other.data(), size()) == 0;
+#endif
+  }
+
+  bool StartsWith(const StringView& other) const {
+    if (other.size() == 0)
+      return true;
+    if (size() == 0)
+      return false;
+    if (other.size() > size())
+      return false;
+    return memcmp(data(), other.data(), other.size()) == 0;
+  }
+
+  bool EndsWith(const StringView& other) const {
+    if (other.size() == 0)
+      return true;
+    if (size() == 0)
+      return false;
+    if (other.size() > size())
+      return false;
+    size_t off = size() - other.size();
+    return memcmp(data() + off, other.data(), other.size()) == 0;
+  }
+
+  std::string ToStdString() const {
+    return size_ == 0 ? "" : std::string(data_, size_);
+  }
+
+  uint64_t Hash() const {
+    base::Hasher hasher;
+    hasher.Update(data_, size_);
+    return hasher.digest();
+  }
+
+ private:
+  const char* data_ = nullptr;
+  size_t size_ = 0;
+};
+
+inline bool operator==(const StringView& x, const StringView& y) {
+  if (x.size() != y.size())
+    return false;
+  if (x.size() == 0)
+    return true;
+  return memcmp(x.data(), y.data(), x.size()) == 0;
+}
+
+inline bool operator!=(const StringView& x, const StringView& y) {
+  return !(x == y);
+}
+
+inline bool operator<(const StringView& x, const StringView& y) {
+  auto size = std::min(x.size(), y.size());
+  if (size == 0)
+    return x.size() < y.size();
+  int result = memcmp(x.data(), y.data(), size);
+  return result < 0 || (result == 0 && x.size() < y.size());
+}
+
+inline bool operator>=(const StringView& x, const StringView& y) {
+  return !(x < y);
+}
+
+inline bool operator>(const StringView& x, const StringView& y) {
+  return y < x;
+}
+
+inline bool operator<=(const StringView& x, const StringView& y) {
+  return !(y < x);
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+template <>
+struct std::hash<::perfetto::base::StringView> {
+  size_t operator()(const ::perfetto::base::StringView& sv) const {
+    return static_cast<size_t>(sv.Hash());
+  }
+};
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
+// gen_amalgamated begin header: include/perfetto/ext/base/utils.h
+// gen_amalgamated begin header: include/perfetto/ext/base/sys_types.h
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
+#define INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
+
+// This headers deals with sys types commonly used in the codebase that are
+// missing on Windows.
+
+#include <sys/types.h>
+#include <cstdint>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
+// MinGW has these. clang-cl and MSVC, which use just the Windows SDK, don't.
+using uid_t = unsigned int;
+using pid_t = int;
+#endif  // !GCC
+
+#if defined(_WIN64)
+using ssize_t = int64_t;
+#else
+using ssize_t = long;
+#endif  // _WIN64
+
+#endif  // OS_WIN
+
+namespace perfetto {
+namespace base {
+
+// The machine ID used in the tracing core.
+using MachineID = uint32_t;
+// The default value reserved for the host trace.
+constexpr MachineID kDefaultMachineID = 0;
+
+constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
+constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <atomic>
+#include <functional>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// Even if Windows has errno.h, the all syscall-restart behavior does not apply.
+// Trying to handle EINTR can cause more harm than good if errno is left stale.
+// Chromium does the same.
+#define PERFETTO_EINTR(x) (x)
+#else
+#define PERFETTO_EINTR(x)                                   \
+  ([&] {                                                    \
+    decltype(x) eintr_wrapper_result;                       \
+    do {                                                    \
+      eintr_wrapper_result = (x);                           \
+    } while (eintr_wrapper_result == -1 && errno == EINTR); \
+    return eintr_wrapper_result;                            \
+  }())
+#endif
+
+namespace perfetto {
+namespace base {
+
+namespace internal {
+extern std::atomic<uint32_t> g_cached_page_size;
+uint32_t GetSysPageSizeSlowpath();
+}  // namespace internal
+
+// Returns the system's page size. Use this when dealing with mmap, madvise and
+// similar mm-related syscalls.
+// This function might be called in hot paths. Avoid calling getpagesize() all
+// the times, in many implementations getpagesize() calls sysconf() which is
+// not cheap.
+inline uint32_t GetSysPageSize() {
+  const uint32_t page_size =
+      internal::g_cached_page_size.load(std::memory_order_relaxed);
+  return page_size != 0 ? page_size : internal::GetSysPageSizeSlowpath();
+}
+
+template <typename T, size_t TSize>
+constexpr size_t ArraySize(const T (&)[TSize]) {
+  return TSize;
+}
+
+// Function object which invokes 'free' on its parameter, which must be
+// a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr:
+//
+// std::unique_ptr<int, base::FreeDeleter> foo_ptr(
+//     static_cast<int*>(malloc(sizeof(int))));
+struct FreeDeleter {
+  inline void operator()(void* ptr) const { free(ptr); }
+};
+
+template <typename T>
+constexpr T AssumeLittleEndian(T value) {
+#if !PERFETTO_IS_LITTLE_ENDIAN()
+  static_assert(false, "Unimplemented on big-endian archs");
+#endif
+  return value;
+}
+
+// Round up |size| to a multiple of |alignment| (must be a power of two).
+inline constexpr size_t AlignUp(size_t size, size_t alignment) {
+  return (size + alignment - 1) & ~(alignment - 1);
+}
+
+// TODO(primiano): clean this up and move all existing usages to the constexpr
+// version above.
+template <size_t alignment>
+constexpr size_t AlignUp(size_t size) {
+  static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
+  return AlignUp(size, alignment);
+}
+
+inline bool IsAgain(int err) {
+  return err == EAGAIN || err == EWOULDBLOCK;
+}
+
+// setenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
+void SetEnv(const std::string& key, const std::string& value);
+
+// unsetenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
+void UnsetEnv(const std::string& key);
+
+// Calls mallopt(M_PURGE, 0) on Android. Does nothing on other platforms.
+// This forces the allocator to release freed memory. This is used to work
+// around various Scudo inefficiencies. See b/170217718.
+void MaybeReleaseAllocatorMemToOS();
+
+// geteuid() on POSIX OSes, returns 0 on Windows (See comment in utils.cc).
+uid_t GetCurrentUserId();
+
+// Forks the process.
+// Parent: prints the PID of the child, calls |parent_cb| and exits from the
+//         process with its return value.
+// Child: redirects stdio onto /dev/null, chdirs into / and returns.
+void Daemonize(std::function<int()> parent_cb);
+
+// Returns the path of the current executable, e.g. /foo/bar/exe.
+std::string GetCurExecutablePath();
+
+// Returns the directory where the current executable lives in, e.g. /foo/bar.
+// This is independent of cwd().
+std::string GetCurExecutableDir();
+
+// Memory returned by AlignedAlloc() must be freed via AlignedFree() not just
+// free. It makes a difference on Windows where _aligned_malloc() and
+// _aligned_free() must be paired.
+// Prefer using the AlignedAllocTyped() below which takes care of the pairing.
+void* AlignedAlloc(size_t alignment, size_t size);
+void AlignedFree(void*);
+
+// A RAII version of the above, which takes care of pairing Aligned{Alloc,Free}.
+template <typename T>
+struct AlignedDeleter {
+  inline void operator()(T* ptr) const { AlignedFree(ptr); }
+};
+
+// The remove_extent<T> here and below is to allow defining unique_ptr<T[]>.
+// As per https://en.cppreference.com/w/cpp/memory/unique_ptr the Deleter takes
+// always a T*, not a T[]*.
+template <typename T>
+using AlignedUniquePtr =
+    std::unique_ptr<T, AlignedDeleter<typename std::remove_extent<T>::type>>;
+
+template <typename T>
+AlignedUniquePtr<T> AlignedAllocTyped(size_t n_membs) {
+  using TU = typename std::remove_extent<T>::type;
+  return AlignedUniquePtr<T>(
+      static_cast<TU*>(AlignedAlloc(alignof(TU), sizeof(TU) * n_membs)));
+}
+
+// A RAII wrapper to invoke a function when leaving a function/scope.
+template <typename Func>
+class OnScopeExitWrapper {
+ public:
+  explicit OnScopeExitWrapper(Func f) : f_(std::move(f)), active_(true) {}
+  OnScopeExitWrapper(OnScopeExitWrapper&& other) noexcept
+      : f_(std::move(other.f_)), active_(other.active_) {
+    other.active_ = false;
+  }
+  ~OnScopeExitWrapper() {
+    if (active_)
+      f_();
+  }
+
+ private:
+  Func f_;
+  bool active_;
+};
+
+template <typename Func>
+PERFETTO_WARN_UNUSED_RESULT OnScopeExitWrapper<Func> OnScopeExit(Func f) {
+  return OnScopeExitWrapper<Func>(std::move(f));
+}
+
+// Returns a xxd-style hex dump (hex + ascii chars) of the input data.
+std::string HexDump(const void* data, size_t len, size_t bytes_per_line = 16);
+inline std::string HexDump(const std::string& data,
+                           size_t bytes_per_line = 16) {
+  return HexDump(data.data(), data.size(), bytes_per_line);
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
+#define INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
+
+#include <optional>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"  // For ssize_t.
+
+namespace perfetto {
+namespace base {
+
+// Returns the length of the destination string (included '=' padding).
+// Does NOT include the size of the string null terminator.
+inline size_t Base64EncSize(size_t src_size) {
+  return (src_size + 2) / 3 * 4;
+}
+
+// Returns the upper bound on the length of the destination buffer.
+// The actual decoded length might be <= the number returned here.
+inline size_t Base64DecSize(size_t src_size) {
+  return (src_size + 3) / 4 * 3;
+}
+
+// Does NOT null-terminate |dst|.
+ssize_t Base64Encode(const void* src,
+                     size_t src_size,
+                     char* dst,
+                     size_t dst_size);
+
+std::string Base64Encode(const void* src, size_t src_size);
+
+inline std::string Base64Encode(StringView sv) {
+  return Base64Encode(sv.data(), sv.size());
+}
+
+// Returns -1 in case of failure.
+ssize_t Base64Decode(const char* src,
+                     size_t src_size,
+                     uint8_t* dst,
+                     size_t dst_size);
+
+std::optional<std::string> Base64Decode(const char* src, size_t src_size);
+
+inline std::optional<std::string> Base64Decode(StringView sv) {
+  return Base64Decode(sv.data(), sv.size());
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/base64.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+constexpr char kPadding = '=';
+
+constexpr char kEncTable[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static_assert(sizeof(kEncTable) == (1u << 6) + sizeof('\0'), "Bad table size");
+
+// Maps an ASCII character to its 6-bit value. It only contains translations
+// from '+' to 'z'. Supports the standard (+/) and URL-safe (-_) alphabets.
+constexpr uint8_t kX = 0xff;  // Value used for invalid characters
+constexpr uint8_t kDecTable[] = {
+    62, kX, 62, kX, 63, 52, 53, 54, 55, 56,  // 00 - 09
+    57, 58, 59, 60, 61, kX, kX, kX, 0,  kX,  // 10 - 19
+    kX, kX, 0,  1,  2,  3,  4,  5,  6,  7,   // 20 - 29
+    8,  9,  10, 11, 12, 13, 14, 15, 16, 17,  // 30 - 39
+    18, 19, 20, 21, 22, 23, 24, 25, kX, kX,  // 40 - 49
+    kX, kX, 63, kX, 26, 27, 28, 29, 30, 31,  // 50 - 59
+    32, 33, 34, 35, 36, 37, 38, 39, 40, 41,  // 60 - 69
+    42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  // 70 - 79
+};
+constexpr char kMinDecChar = '+';
+constexpr char kMaxDecChar = 'z';
+static_assert(kMaxDecChar - kMinDecChar <= sizeof(kDecTable), "Bad table size");
+
+inline uint8_t DecodeChar(char c) {
+  if (c < kMinDecChar || c > kMaxDecChar)
+    return kX;
+  return kDecTable[c - kMinDecChar];
+}
+
+}  // namespace
+
+ssize_t Base64Encode(const void* src,
+                     size_t src_size,
+                     char* dst,
+                     size_t dst_size) {
+  const size_t padded_dst_size = Base64EncSize(src_size);
+  if (dst_size < padded_dst_size)
+    return -1;  // Not enough space in output.
+
+  const uint8_t* rd = static_cast<const uint8_t*>(src);
+  const uint8_t* const end = rd + src_size;
+  size_t wr_size = 0;
+  while (rd < end) {
+    uint8_t s[3]{};
+    s[0] = *(rd++);
+    dst[wr_size++] = kEncTable[s[0] >> 2];
+
+    uint8_t carry0 = static_cast<uint8_t>((s[0] & 0x03) << 4);
+    if (PERFETTO_LIKELY(rd < end)) {
+      s[1] = *(rd++);
+      dst[wr_size++] = kEncTable[carry0 | (s[1] >> 4)];
+    } else {
+      dst[wr_size++] = kEncTable[carry0];
+      dst[wr_size++] = kPadding;
+      dst[wr_size++] = kPadding;
+      break;
+    }
+
+    uint8_t carry1 = static_cast<uint8_t>((s[1] & 0x0f) << 2);
+    if (PERFETTO_LIKELY(rd < end)) {
+      s[2] = *(rd++);
+      dst[wr_size++] = kEncTable[carry1 | (s[2] >> 6)];
+    } else {
+      dst[wr_size++] = kEncTable[carry1];
+      dst[wr_size++] = kPadding;
+      break;
+    }
+
+    dst[wr_size++] = kEncTable[s[2] & 0x3f];
+  }
+  PERFETTO_DCHECK(wr_size == padded_dst_size);
+  return static_cast<ssize_t>(padded_dst_size);
+}
+
+std::string Base64Encode(const void* src, size_t src_size) {
+  std::string dst;
+  dst.resize(Base64EncSize(src_size));
+  auto res = Base64Encode(src, src_size, &dst[0], dst.size());
+  PERFETTO_CHECK(res == static_cast<ssize_t>(dst.size()));
+  return dst;
+}
+
+ssize_t Base64Decode(const char* src,
+                     size_t src_size,
+                     uint8_t* dst,
+                     size_t dst_size) {
+  const size_t min_dst_size = Base64DecSize(src_size);
+  if (dst_size < min_dst_size)
+    return -1;
+
+  const char* rd = src;
+  const char* const end = src + src_size;
+  size_t wr_size = 0;
+
+  char s[4]{};
+  while (rd < end) {
+    uint8_t d[4];
+    for (uint32_t j = 0; j < 4; j++) {
+      // Padding is only feasible for the last 2 chars of each group of 4.
+      s[j] = rd < end ? *(rd++) : (j < 2 ? '\0' : kPadding);
+      d[j] = DecodeChar(s[j]);
+      if (d[j] == kX)
+        return -1;  // Invalid input char.
+    }
+    dst[wr_size] = static_cast<uint8_t>((d[0] << 2) | (d[1] >> 4));
+    dst[wr_size + 1] = static_cast<uint8_t>((d[1] << 4) | (d[2] >> 2));
+    dst[wr_size + 2] = static_cast<uint8_t>((d[2] << 6) | (d[3]));
+    wr_size += 3;
+  }
+
+  PERFETTO_CHECK(wr_size <= dst_size);
+  wr_size -= (s[3] == kPadding ? 1 : 0) + (s[2] == kPadding ? 1 : 0);
+  return static_cast<ssize_t>(wr_size);
+}
+
+std::optional<std::string> Base64Decode(const char* src, size_t src_size) {
+  std::string dst;
+  dst.resize(Base64DecSize(src_size));
+  auto res = Base64Decode(src, src_size, reinterpret_cast<uint8_t*>(&dst[0]),
+                          dst.size());
+  if (res < 0)
+    return std::nullopt;  // Decoding error.
+
+  PERFETTO_CHECK(res <= static_cast<ssize_t>(dst.size()));
+  dst.resize(static_cast<size_t>(res));
+  return std::make_optional(dst);
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/crash_keys.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/crash_keys.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
+
+#include <algorithm>
+#include <atomic>
+
+#include <stdint.h>
+#include <string.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+
+// Crash keys are very simple global variables with static-storage that
+// are reported on crash time for managed crashes (CHECK/FATAL/Watchdog).
+// - Translation units can define a CrashKey and register it at some point
+//   during initialization.
+// - CrashKey instances must be long-lived. They should really be just global
+//   static variable in the anonymous namespace.
+// Example:
+// subsystem_1.cc
+//   CrashKey g_client_id("ipc_client_id");
+//   ...
+//   OnIpcReceived(client_id) {
+//      g_client_id.Set(client_id);
+//      ... // Process the IPC
+//      g_client_id.Clear();
+//   }
+//   Or equivalently:
+//   OnIpcReceived(client_id) {
+//      auto scoped_key = g_client_id.SetScoped(client_id);
+//      ... // Process the IPC
+//   }
+//
+// If a crash happens while processing the IPC, the crash report will
+// have a line "ipc_client_id: 42".
+//
+// Thread safety considerations:
+// CrashKeys can be registered and set/cleared from any thread.
+// There is no compelling use-case to have full acquire/release consistency when
+// setting a key. This means that if a thread crashes immediately after a
+// crash key has been set on another thread, the value printed on the crash
+// report could be incomplete. The code guarantees defined behavior and does
+// not rely on null-terminated string (in the worst case 32 bytes of random
+// garbage will be printed out).
+
+// The tests live in logging_unittest.cc.
+
+namespace perfetto {
+namespace base {
+
+constexpr size_t kCrashKeyMaxStrSize = 32;
+
+// CrashKey instances must be long lived
+class CrashKey {
+ public:
+  class ScopedClear {
+   public:
+    explicit ScopedClear(CrashKey* k) : key_(k) {}
+    ~ScopedClear() {
+      if (key_)
+        key_->Clear();
+    }
+    ScopedClear(const ScopedClear&) = delete;
+    ScopedClear& operator=(const ScopedClear&) = delete;
+    ScopedClear& operator=(ScopedClear&&) = delete;
+    ScopedClear(ScopedClear&& other) noexcept : key_(other.key_) {
+      other.key_ = nullptr;
+    }
+
+   private:
+    CrashKey* key_;
+  };
+
+  // constexpr so it can be used in the anon namespace without requiring a
+  // global constructor.
+  // |name| must be a long-lived string.
+  constexpr explicit CrashKey(const char* name)
+      : registered_{}, type_(Type::kUnset), name_(name), str_value_{} {}
+  CrashKey(const CrashKey&) = delete;
+  CrashKey& operator=(const CrashKey&) = delete;
+  CrashKey(CrashKey&&) = delete;
+  CrashKey& operator=(CrashKey&&) = delete;
+
+  enum class Type : uint8_t { kUnset = 0, kInt, kStr };
+
+  void Clear() {
+    int_value_.store(0, std::memory_order_relaxed);
+    type_.store(Type::kUnset, std::memory_order_relaxed);
+  }
+
+  void Set(int64_t value) {
+    int_value_.store(value, std::memory_order_relaxed);
+    type_.store(Type::kInt, std::memory_order_relaxed);
+    if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
+      Register();
+  }
+
+  void Set(StringView sv) {
+    size_t len = std::min(sv.size(), sizeof(str_value_) - 1);
+    for (size_t i = 0; i < len; ++i)
+      str_value_[i].store(sv.data()[i], std::memory_order_relaxed);
+    str_value_[len].store('\0', std::memory_order_relaxed);
+    type_.store(Type::kStr, std::memory_order_relaxed);
+    if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
+      Register();
+  }
+
+  ScopedClear SetScoped(int64_t value) PERFETTO_WARN_UNUSED_RESULT {
+    Set(value);
+    return ScopedClear(this);
+  }
+
+  ScopedClear SetScoped(StringView sv) PERFETTO_WARN_UNUSED_RESULT {
+    Set(sv);
+    return ScopedClear(this);
+  }
+
+  void Register();
+
+  int64_t int_value() const {
+    return int_value_.load(std::memory_order_relaxed);
+  }
+  size_t ToString(char* dst, size_t len);
+
+ private:
+  std::atomic<bool> registered_;
+  std::atomic<Type> type_;
+  const char* const name_;
+  union {
+    std::atomic<char> str_value_[kCrashKeyMaxStrSize];
+    std::atomic<int64_t> int_value_;
+  };
+};
+
+// Fills |dst| with a string containing one line for each crash key
+// (excluding the unset ones).
+// Returns number of chars written, without counting the NUL terminator.
+// This is used in logging.cc when emitting the crash report abort message.
+size_t SerializeCrashKeys(char* dst, size_t len);
+
+void UnregisterAllCrashKeysForTesting();
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
+// gen_amalgamated begin header: include/perfetto/ext/base/string_utils.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <cinttypes>
+#include <optional>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+
+namespace perfetto {
+namespace base {
+
+inline char Lowercase(char c) {
+  return ('A' <= c && c <= 'Z') ? static_cast<char>(c - ('A' - 'a')) : c;
+}
+
+inline char Uppercase(char c) {
+  return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
+}
+
+inline std::optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
+  char* endptr = nullptr;
+  auto value = static_cast<uint32_t>(strtoul(s, &endptr, base));
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
+}
+
+inline std::optional<int32_t> CStringToInt32(const char* s, int base = 10) {
+  char* endptr = nullptr;
+  auto value = static_cast<int32_t>(strtol(s, &endptr, base));
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
+}
+
+// Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
+inline std::optional<int64_t> CStringToInt64(const char* s, int base = 10) {
+  char* endptr = nullptr;
+  auto value = static_cast<int64_t>(strtoll(s, &endptr, base));
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
+}
+
+inline std::optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
+  char* endptr = nullptr;
+  auto value = static_cast<uint64_t>(strtoull(s, &endptr, base));
+  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
+}
+
+double StrToD(const char* nptr, char** endptr);
+
+inline std::optional<double> CStringToDouble(const char* s) {
+  char* endptr = nullptr;
+  double value = StrToD(s, &endptr);
+  std::optional<double> result(std::nullopt);
+  if (*s != '\0' && *endptr == '\0')
+    result = value;
+  return result;
+}
+
+inline std::optional<uint32_t> StringToUInt32(const std::string& s,
+                                              int base = 10) {
+  return CStringToUInt32(s.c_str(), base);
+}
+
+inline std::optional<int32_t> StringToInt32(const std::string& s,
+                                            int base = 10) {
+  return CStringToInt32(s.c_str(), base);
+}
+
+inline std::optional<uint64_t> StringToUInt64(const std::string& s,
+                                              int base = 10) {
+  return CStringToUInt64(s.c_str(), base);
+}
+
+inline std::optional<int64_t> StringToInt64(const std::string& s,
+                                            int base = 10) {
+  return CStringToInt64(s.c_str(), base);
+}
+
+inline std::optional<double> StringToDouble(const std::string& s) {
+  return CStringToDouble(s.c_str());
+}
+
+bool StartsWith(const std::string& str, const std::string& prefix);
+bool EndsWith(const std::string& str, const std::string& suffix);
+bool StartsWithAny(const std::string& str,
+                   const std::vector<std::string>& prefixes);
+bool Contains(const std::string& haystack, const std::string& needle);
+bool Contains(const std::string& haystack, char needle);
+size_t Find(const StringView& needle, const StringView& haystack);
+bool CaseInsensitiveEqual(const std::string& first, const std::string& second);
+std::string Join(const std::vector<std::string>& parts,
+                 const std::string& delim);
+std::vector<std::string> SplitString(const std::string& text,
+                                     const std::string& delimiter);
+std::string StripPrefix(const std::string& str, const std::string& prefix);
+std::string StripSuffix(const std::string& str, const std::string& suffix);
+std::string TrimWhitespace(const std::string& str);
+std::string ToLower(const std::string& str);
+std::string ToUpper(const std::string& str);
+std::string StripChars(const std::string& str,
+                       const std::string& chars,
+                       char replacement);
+std::string ToHex(const char* data, size_t size);
+inline std::string ToHex(const std::string& s) {
+  return ToHex(s.c_str(), s.size());
+}
+std::string IntToHexString(uint32_t number);
+std::string Uint64ToHexString(uint64_t number);
+std::string Uint64ToHexStringNoPrefix(uint64_t number);
+std::string ReplaceAll(std::string str,
+                       const std::string& to_replace,
+                       const std::string& replacement);
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+bool WideToUTF8(const std::wstring& source, std::string& output);
+bool UTF8ToWide(const std::string& source, std::wstring& output);
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+// A BSD-style strlcpy without the return value.
+// Copies at most |dst_size|-1 characters. Unlike strncpy, it always \0
+// terminates |dst|, as long as |dst_size| is not 0.
+// Unlike strncpy and like strlcpy it does not zero-pad the rest of |dst|.
+// Returns nothing. The BSD strlcpy returns the size of |src|, which might
+// be > |dst_size|. Anecdotal experience suggests people assume the return value
+// is the number of bytes written in |dst|. That assumption can lead to
+// dangerous bugs.
+// In order to avoid being subtly uncompliant with strlcpy AND avoid misuse,
+// the choice here is to return nothing.
+inline void StringCopy(char* dst, const char* src, size_t dst_size) {
+  for (size_t i = 0; i < dst_size; ++i) {
+    if ((dst[i] = src[i]) == '\0') {
+      return;  // We hit and copied the null terminator.
+    }
+  }
+
+  // We were left off at dst_size. We over copied 1 byte. Null terminate.
+  if (PERFETTO_LIKELY(dst_size > 0))
+    dst[dst_size - 1] = 0;
+}
+
+// Like snprintf() but returns the number of chars *actually* written (without
+// counting the null terminator) NOT "the number of chars which would have been
+// written to the final string if enough  space had been available".
+// This should be used in almost all cases when the caller uses the return value
+// of snprintf(). If the return value is not used, there is no benefit in using
+// this wrapper, as this just calls snprintf() and mangles the return value.
+// It always null-terminates |dst| (even in case of errors), unless
+// |dst_size| == 0.
+// Examples:
+//   SprintfTrunc(x, 4, "123whatever"): returns 3 and writes "123\0".
+//   SprintfTrunc(x, 4, "123"): returns 3 and writes "123\0".
+//   SprintfTrunc(x, 3, "123"): returns 2 and writes "12\0".
+//   SprintfTrunc(x, 2, "123"): returns 1 and writes "1\0".
+//   SprintfTrunc(x, 1, "123"): returns 0 and writes "\0".
+//   SprintfTrunc(x, 0, "123"): returns 0 and writes nothing.
+// NOTE: This means that the caller has no way to tell when truncation happens
+//   vs the edge case of *just* fitting in the buffer.
+size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...)
+    PERFETTO_PRINTF_FORMAT(3, 4);
+
+// Line number starts from 1
+struct LineWithOffset {
+  base::StringView line;
+  uint32_t line_offset;
+  uint32_t line_num;
+};
+
+// For given string and offset Pfinds a line with character for
+// which offset points, what number is this line (starts from 1), and the offset
+// inside this line. returns std::nullopt if the offset points to
+// line break character or exceeds string length.
+std::optional<LineWithOffset> FindLineWithOffset(base::StringView str,
+                                                 uint32_t offset);
+
+// A helper class to facilitate construction and usage of write-once stack
+// strings.
+// Example usage:
+//   StackString<32> x("format %d %s", 42, string_arg);
+//   TakeString(x.c_str() | x.string_view() | x.ToStdString());
+// Rather than char x[32] + sprintf.
+// Advantages:
+// - Avoids useless zero-fills caused by people doing `char buf[32] {}` (mainly
+//   by fearing unknown snprintf failure modes).
+// - Makes the code more robust in case of snprintf truncations (len() and
+//  string_view() will return the truncated length, unlike snprintf).
+template <size_t N>
+class StackString {
+ public:
+  explicit PERFETTO_PRINTF_FORMAT(/* 1=this */ 2, 3)
+      StackString(const char* fmt, ...) {
+    buf_[0] = '\0';
+    va_list args;
+    va_start(args, fmt);
+    int res = vsnprintf(buf_, sizeof(buf_), fmt, args);
+    va_end(args);
+    buf_[sizeof(buf_) - 1] = '\0';
+    len_ = res < 0 ? 0 : std::min(static_cast<size_t>(res), sizeof(buf_) - 1);
+  }
+
+  StringView string_view() const { return StringView(buf_, len_); }
+  std::string ToStdString() const { return std::string(buf_, len_); }
+  const char* c_str() const { return buf_; }
+  size_t len() const { return len_; }
+  char* mutable_data() { return buf_; }
+
+ private:
+  char buf_[N];
+  size_t len_ = 0;  // Does not include the \0.
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
+
+#include <string.h>
+
+#include <atomic>
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+constexpr size_t kMaxKeys = 32;
+
+std::atomic<CrashKey*> g_keys[kMaxKeys]{};
+std::atomic<uint32_t> g_num_keys{};
+}  // namespace
+
+void CrashKey::Register() {
+  // If doesn't matter if we fail below. If there are no slots left, don't
+  // keep trying re-registering on every Set(), the outcome won't change.
+
+  // If two threads raced on the Register(), avoid registering the key twice.
+  if (registered_.exchange(true))
+    return;
+
+  uint32_t slot = g_num_keys.fetch_add(1);
+  if (slot >= kMaxKeys) {
+    PERFETTO_LOG("Too many crash keys registered");
+    return;
+  }
+  g_keys[slot].store(this);
+}
+
+// Returns the number of chars written, without counting the \0.
+size_t CrashKey::ToString(char* dst, size_t len) {
+  if (len > 0)
+    *dst = '\0';
+  switch (type_.load(std::memory_order_relaxed)) {
+    case Type::kUnset:
+      break;
+    case Type::kInt:
+      return SprintfTrunc(dst, len, "%s: %" PRId64 "\n", name_,
+                          int_value_.load(std::memory_order_relaxed));
+    case Type::kStr:
+      char buf[sizeof(str_value_)];
+      for (size_t i = 0; i < sizeof(str_value_); i++)
+        buf[i] = str_value_[i].load(std::memory_order_relaxed);
+
+      // Don't assume |str_value_| is properly null-terminated.
+      return SprintfTrunc(dst, len, "%s: %.*s\n", name_, int(sizeof(buf)), buf);
+  }
+  return 0;
+}
+
+void UnregisterAllCrashKeysForTesting() {
+  g_num_keys.store(0);
+  for (auto& key : g_keys)
+    key.store(nullptr);
+}
+
+size_t SerializeCrashKeys(char* dst, size_t len) {
+  size_t written = 0;
+  uint32_t num_keys = g_num_keys.load();
+  if (len > 0)
+    *dst = '\0';
+  for (uint32_t i = 0; i < num_keys && written < len; i++) {
+    CrashKey* key = g_keys[i].load();
+    if (!key)
+      continue;  // Can happen if we hit this between the add and the store.
+    written += key->ToString(dst + written, len - written);
+  }
+  PERFETTO_DCHECK(written <= len);
+  PERFETTO_DCHECK(len == 0 || dst[written] == '\0');
+  return written;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/ctrl_c_handler.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/ctrl_c_handler.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
+
+namespace perfetto {
+namespace base {
+
+// On Linux/Android/Mac: installs SIGINT + SIGTERM signal handlers.
+// On Windows: installs a SetConsoleCtrlHandler() handler.
+// The passed handler must be async safe.
+using CtrlCHandlerFunction = void (*)();
+void InstallCtrlCHandler(CtrlCHandlerFunction);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/ctrl_c_handler.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <io.h>
+#else
+#include <signal.h>
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+namespace {
+CtrlCHandlerFunction g_handler = nullptr;
+}
+
+void InstallCtrlCHandler(CtrlCHandlerFunction handler) {
+  PERFETTO_CHECK(g_handler == nullptr);
+  g_handler = handler;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  auto trampoline = [](DWORD type) -> int {
+    if (type == CTRL_C_EVENT) {
+      g_handler();
+      return true;
+    }
+    return false;
+  };
+  ::SetConsoleCtrlHandler(trampoline, true);
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  // Setup signal handler.
+  struct sigaction sa {};
+
+// Glibc headers for sa_sigaction trigger this.
+#pragma GCC diagnostic push
+#if defined(__clang__)
+#pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
+#endif
+  sa.sa_handler = [](int) { g_handler(); };
+  sa.sa_flags = static_cast<decltype(sa.sa_flags)>(SA_RESETHAND | SA_RESTART);
+#pragma GCC diagnostic pop
+  sigaction(SIGINT, &sa, nullptr);
+  sigaction(SIGTERM, &sa, nullptr);
+#else
+  // Do nothing on NaCL and Fuchsia.
+  ignore_result(handler);
+#endif
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/event_fd.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/event_fd.h
+// gen_amalgamated begin header: include/perfetto/ext/base/scoped_file.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
+#define INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <stdio.h>
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <dirent.h>  // For DIR* / opendir().
+#endif
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+
+namespace perfetto {
+namespace base {
+
+namespace internal {
+// Used for the most common cases of ScopedResource where there is only one
+// invalid value.
+template <typename T, T InvalidValue>
+struct DefaultValidityChecker {
+  static bool IsValid(T t) { return t != InvalidValue; }
+};
+}  // namespace internal
+
+// RAII classes for auto-releasing fds and dirs.
+// if T is a pointer type, InvalidValue must be nullptr. Doing otherwise
+// causes weird unexpected behaviors (See https://godbolt.org/z/5nGMW4).
+template <typename T,
+          int (*CloseFunction)(T),
+          T InvalidValue,
+          bool CheckClose = true,
+          class Checker = internal::DefaultValidityChecker<T, InvalidValue>>
+class ScopedResource {
+ public:
+  using ValidityChecker = Checker;
+  static constexpr T kInvalid = InvalidValue;
+
+  explicit ScopedResource(T t = InvalidValue) : t_(t) {}
+  ScopedResource(ScopedResource&& other) noexcept {
+    t_ = other.t_;
+    other.t_ = InvalidValue;
+  }
+  ScopedResource& operator=(ScopedResource&& other) {
+    reset(other.t_);
+    other.t_ = InvalidValue;
+    return *this;
+  }
+  T get() const { return t_; }
+  T operator*() const { return t_; }
+  explicit operator bool() const { return Checker::IsValid(t_); }
+  void reset(T r = InvalidValue) {
+    if (Checker::IsValid(t_)) {
+      int res = CloseFunction(t_);
+      if (CheckClose)
+        PERFETTO_CHECK(res == 0);
+    }
+    t_ = r;
+  }
+  T release() {
+    T t = t_;
+    t_ = InvalidValue;
+    return t;
+  }
+  ~ScopedResource() { reset(InvalidValue); }
+
+ private:
+  ScopedResource(const ScopedResource&) = delete;
+  ScopedResource& operator=(const ScopedResource&) = delete;
+  T t_;
+};
+
+// Declared in file_utils.h. Forward declared to avoid #include cycles.
+int PERFETTO_EXPORT_COMPONENT CloseFile(int fd);
+
+// Use this for file resources obtained via open() and similar APIs.
+using ScopedFile = ScopedResource<int, CloseFile, -1>;
+using ScopedFstream = ScopedResource<FILE*, fclose, nullptr>;
+
+// Use this for resources that are HANDLE on Windows. See comments in
+// platform_handle.h
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using ScopedPlatformHandle = ScopedResource<PlatformHandle,
+                                            ClosePlatformHandle,
+                                            /*InvalidValue=*/nullptr,
+                                            /*CheckClose=*/true,
+                                            PlatformHandleChecker>;
+#else
+// On non-windows systems we alias ScopedPlatformHandle to ScopedFile because
+// they are really the same. This is to allow assignments between the two in
+// Linux-specific code paths that predate ScopedPlatformHandle.
+static_assert(std::is_same<int, PlatformHandle>::value, "");
+using ScopedPlatformHandle = ScopedFile;
+
+// DIR* does not exist on Windows.
+using ScopedDir = ScopedResource<DIR*, closedir, nullptr>;
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
+#define INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+namespace perfetto {
+namespace base {
+
+// A waitable event that can be used with poll/select.
+// This is really a wrapper around eventfd_create with a pipe-based fallback
+// for other platforms where eventfd is not supported.
+class EventFd {
+ public:
+  EventFd();
+  ~EventFd();
+  EventFd(EventFd&&) noexcept = default;
+  EventFd& operator=(EventFd&&) = default;
+
+  // The non-blocking file descriptor that can be polled to wait for the event.
+  PlatformHandle fd() const { return event_handle_.get(); }
+
+  // Can be called from any thread.
+  void Notify();
+
+  // Can be called from any thread. If more Notify() are queued a Clear() call
+  // can clear all of them (up to 16 per call).
+  void Clear();
+
+ private:
+  // The eventfd, when eventfd is supported, otherwise this is the read end of
+  // the pipe for fallback mode.
+  ScopedPlatformHandle event_handle_;
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) &&   \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // On Mac and other non-Linux UNIX platforms a pipe-based fallback is used.
+  // The write end of the wakeup pipe.
+  ScopedFile write_fd_;
+#endif
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
+// gen_amalgamated begin header: include/perfetto/ext/base/pipe.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
+#define INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+namespace perfetto {
+namespace base {
+
+class Pipe {
+ public:
+  enum Flags {
+    kBothBlock = 0,
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    kBothNonBlock,
+    kRdNonBlock,
+    kWrNonBlock,
+#endif
+  };
+
+  static Pipe Create(Flags = kBothBlock);
+
+  Pipe();
+  Pipe(Pipe&&) noexcept;
+  Pipe& operator=(Pipe&&);
+
+  ScopedPlatformHandle rd;
+  ScopedPlatformHandle wr;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <errno.h>
+#include <stdint.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <synchapi.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/eventfd.h>
+#include <unistd.h>
+#else  // Mac, Fuchsia and other non-Linux UNIXes
+#include <unistd.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+EventFd::~EventFd() = default;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+EventFd::EventFd() {
+  event_handle_.reset(
+      CreateEventA(/*lpEventAttributes=*/nullptr, /*bManualReset=*/true,
+                   /*bInitialState=*/false, /*bInitialState=*/nullptr));
+}
+
+void EventFd::Notify() {
+  if (!SetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
+    PERFETTO_DFATAL("EventFd::Notify()");
+}
+
+void EventFd::Clear() {
+  if (!ResetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
+    PERFETTO_DFATAL("EventFd::Clear()");
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+EventFd::EventFd() {
+  event_handle_.reset(eventfd(/*initval=*/0, EFD_CLOEXEC | EFD_NONBLOCK));
+  PERFETTO_CHECK(event_handle_);
+}
+
+void EventFd::Notify() {
+  const uint64_t value = 1;
+  ssize_t ret = write(event_handle_.get(), &value, sizeof(value));
+  if (ret <= 0 && errno != EAGAIN)
+    PERFETTO_DFATAL("EventFd::Notify()");
+}
+
+void EventFd::Clear() {
+  uint64_t value;
+  ssize_t ret =
+      PERFETTO_EINTR(read(event_handle_.get(), &value, sizeof(value)));
+  if (ret <= 0 && errno != EAGAIN)
+    PERFETTO_DFATAL("EventFd::Clear()");
+}
+
+#else
+
+EventFd::EventFd() {
+  // Make the pipe non-blocking so that we never block the waking thread (either
+  // the main thread or another one) when scheduling a wake-up.
+  Pipe pipe = Pipe::Create(Pipe::kBothNonBlock);
+  event_handle_ = ScopedPlatformHandle(std::move(pipe.rd).release());
+  write_fd_ = std::move(pipe.wr);
+}
+
+void EventFd::Notify() {
+  const uint64_t value = 1;
+  ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t));
+  if (ret <= 0 && errno != EAGAIN)
+    PERFETTO_DFATAL("EventFd::Notify()");
+}
+
+void EventFd::Clear() {
+  // Drain the byte(s) written to the wake-up pipe. We can potentially read
+  // more than one byte if several wake-ups have been scheduled.
+  char buffer[16];
+  ssize_t ret =
+      PERFETTO_EINTR(read(event_handle_.get(), &buffer[0], sizeof(buffer)));
+  if (ret <= 0 && errno != EAGAIN)
+    PERFETTO_DFATAL("EventFd::Clear()");
+}
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/file_utils.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/file_utils.h
+// gen_amalgamated begin header: include/perfetto/base/status.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_STATUS_H_
+#define INCLUDE_PERFETTO_BASE_STATUS_H_
+
+#include <optional>
+#include <string>
+#include <string_view>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+// Represents either the success or the failure message of a function.
+// This can used as the return type of functions which would usually return an
+// bool for success or int for errno but also wants to add some string context
+// (ususally for logging).
+//
+// Similar to absl::Status, an optional "payload" can also be included with more
+// context about the error. This allows passing additional metadata about the
+// error (e.g. location of errors, potential mitigations etc).
+class PERFETTO_EXPORT_COMPONENT Status {
+ public:
+  Status() : ok_(true) {}
+  explicit Status(std::string msg) : ok_(false), message_(std::move(msg)) {
+    PERFETTO_CHECK(!message_.empty());
+  }
+
+  // Copy operations.
+  Status(const Status&) = default;
+  Status& operator=(const Status&) = default;
+
+  // Move operations. The moved-from state is valid but unspecified.
+  Status(Status&&) noexcept = default;
+  Status& operator=(Status&&) = default;
+
+  bool ok() const { return ok_; }
+
+  // When ok() is false this returns the error message. Returns the empty string
+  // otherwise.
+  const std::string& message() const { return message_; }
+  const char* c_message() const { return message_.c_str(); }
+
+  //////////////////////////////////////////////////////////////////////////////
+  // Payload Management APIs
+  //////////////////////////////////////////////////////////////////////////////
+
+  // Payloads can be attached to error statuses to provide additional context.
+  //
+  // Payloads are (key, value) pairs, where the key is a string acting as a
+  // unique "type URL" and the value is an opaque string. The "type URL" should
+  // be unique, follow the format of a URL and, ideally, documentation on how to
+  // interpret its associated data should be available.
+  //
+  // To attach a payload to a status object, call `Status::SetPayload()`.
+  // Similarly, to extract the payload from a status, call
+  // `Status::GetPayload()`.
+  //
+  // Note: the payload APIs are only meaningful to call when the status is an
+  // error. Otherwise, all methods are noops.
+
+  // Gets the payload for the given |type_url| if one exists.
+  //
+  // Will always return std::nullopt if |ok()|.
+  std::optional<std::string_view> GetPayload(std::string_view type_url) const;
+
+  // Sets the payload for the given key. The key should
+  //
+  // Will always do nothing if |ok()|.
+  void SetPayload(std::string_view type_url, std::string value);
+
+  // Erases the payload for the given string and returns true if the payload
+  // existed and was erased.
+  //
+  // Will always do nothing if |ok()|.
+  bool ErasePayload(std::string_view type_url);
+
+ private:
+  struct Payload {
+    std::string type_url;
+    std::string payload;
+  };
+
+  bool ok_ = false;
+  std::string message_;
+  std::vector<Payload> payloads_;
+};
+
+// Returns a status object which represents the Ok status.
+inline Status OkStatus() {
+  return Status();
+}
+
+PERFETTO_PRINTF_FORMAT(1, 2) Status ErrStatus(const char* format, ...);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_STATUS_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
+
+#include <fcntl.h>  // For mode_t & O_RDONLY/RDWR. Exists also on Windows.
+#include <stddef.h>
+
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/status.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using FileOpenMode = int;
+#else
+using FileOpenMode = mode_t;
+#endif
+
+constexpr FileOpenMode kFileModeInvalid = static_cast<FileOpenMode>(-1);
+
+bool ReadPlatformHandle(PlatformHandle, std::string* out);
+bool ReadFileDescriptor(int fd, std::string* out);
+bool ReadFileStream(FILE* f, std::string* out);
+bool ReadFile(const std::string& path, std::string* out);
+
+// A wrapper around read(2). It deals with Linux vs Windows includes. It also
+// deals with handling EINTR. Has the same semantics of UNIX's read(2).
+ssize_t Read(int fd, void* dst, size_t dst_size);
+
+// Call write until all data is written or an error is detected.
+//
+// man 2 write:
+//   If a write() is interrupted by a signal handler before any bytes are
+//   written, then the call fails with the error EINTR; if it is
+//   interrupted after at least one byte has been written, the call
+//   succeeds, and returns the number of bytes written.
+ssize_t WriteAll(int fd, const void* buf, size_t count);
+
+ssize_t WriteAllHandle(PlatformHandle, const void* buf, size_t count);
+
+ScopedFile OpenFile(const std::string& path,
+                    int flags,
+                    FileOpenMode = kFileModeInvalid);
+ScopedFstream OpenFstream(const char* path, const char* mode);
+
+// This is an alias for close(). It's to avoid leaking Windows.h in headers.
+// Exported because ScopedFile is used in the /include/ext API by Chromium
+// component builds.
+int PERFETTO_EXPORT_COMPONENT CloseFile(int fd);
+
+bool FlushFile(int fd);
+
+// Returns true if mkdir succeeds, false if it fails (see errno in that case).
+bool Mkdir(const std::string& path);
+
+// Calls rmdir() on UNIX, _rmdir() on Windows.
+bool Rmdir(const std::string& path);
+
+// Wrapper around access(path, F_OK).
+bool FileExists(const std::string& path);
+
+// Gets the extension for a filename. If the file has two extensions, returns
+// only the last one (foo.pb.gz => .gz). Returns empty string if there is no
+// extension.
+std::string GetFileExtension(const std::string& filename);
+
+// Puts the path to all files under |dir_path| in |output|, recursively walking
+// subdirectories. File paths are relative to |dir_path|. Only files are
+// included, not directories. Path separator is always '/', even on windows (not
+// '\').
+base::Status ListFilesRecursive(const std::string& dir_path,
+                                std::vector<std::string>& output);
+
+// Sets |path|'s owner group to |group_name| and permission mode bits to
+// |mode_bits|.
+base::Status SetFilePermissions(const std::string& path,
+                                const std::string& group_name,
+                                const std::string& mode_bits);
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <algorithm>
+#include <deque>
+#include <optional>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+// gen_amalgamated expanded: #include "perfetto/base/status.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <direct.h>
+#include <io.h>
+#include <stringapiset.h>
+#else
+#include <dirent.h>
+#include <unistd.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#define PERFETTO_SET_FILE_PERMISSIONS
+#include <fcntl.h>
+#include <grp.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+namespace {
+constexpr size_t kBufSize = 2048;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// Wrap FindClose to: (1) make the return unix-style; (2) deal with stdcall.
+int CloseFindHandle(HANDLE h) {
+  return FindClose(h) ? 0 : -1;
+}
+
+std::optional<std::wstring> ToUtf16(const std::string str) {
+  int len = MultiByteToWideChar(CP_UTF8, 0, str.data(),
+                                static_cast<int>(str.size()), nullptr, 0);
+  if (len < 0) {
+    return std::nullopt;
+  }
+  std::vector<wchar_t> tmp;
+  tmp.resize(static_cast<std::vector<wchar_t>::size_type>(len));
+  len =
+      MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()),
+                          tmp.data(), static_cast<int>(tmp.size()));
+  if (len < 0) {
+    return std::nullopt;
+  }
+  PERFETTO_CHECK(static_cast<std::vector<wchar_t>::size_type>(len) ==
+                 tmp.size());
+  return std::wstring(tmp.data(), tmp.size());
+}
+
+#endif
+
+}  // namespace
+
+ssize_t Read(int fd, void* dst, size_t dst_size) {
+  ssize_t ret;
+  platform::BeforeMaybeBlockingSyscall();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  ret = _read(fd, dst, static_cast<unsigned>(dst_size));
+#else
+  ret = PERFETTO_EINTR(read(fd, dst, dst_size));
+#endif
+  platform::AfterMaybeBlockingSyscall();
+  return ret;
+}
+
+bool ReadFileDescriptor(int fd, std::string* out) {
+  // Do not override existing data in string.
+  size_t i = out->size();
+
+  struct stat buf {};
+  if (fstat(fd, &buf) != -1) {
+    if (buf.st_size > 0)
+      out->resize(i + static_cast<size_t>(buf.st_size));
+  }
+
+  ssize_t bytes_read;
+  for (;;) {
+    if (out->size() < i + kBufSize)
+      out->resize(out->size() + kBufSize);
+
+    bytes_read = Read(fd, &((*out)[i]), kBufSize);
+    if (bytes_read > 0) {
+      i += static_cast<size_t>(bytes_read);
+    } else {
+      out->resize(i);
+      return bytes_read == 0;
+    }
+  }
+}
+
+bool ReadPlatformHandle(PlatformHandle h, std::string* out) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Do not override existing data in string.
+  size_t i = out->size();
+
+  for (;;) {
+    if (out->size() < i + kBufSize)
+      out->resize(out->size() + kBufSize);
+    DWORD bytes_read = 0;
+    auto res = ::ReadFile(h, &((*out)[i]), kBufSize, &bytes_read, nullptr);
+    if (res && bytes_read > 0) {
+      i += static_cast<size_t>(bytes_read);
+    } else {
+      out->resize(i);
+      const bool is_eof = res && bytes_read == 0;
+      auto err = res ? 0 : GetLastError();
+      // The "Broken pipe" error on Windows is slighly different than Unix:
+      // On Unix: a "broken pipe" error can happen only on the writer side. On
+      // the reader there is no broken pipe, just a EOF.
+      // On windows: the reader also sees a broken pipe error.
+      // Here we normalize on the Unix behavior, treating broken pipe as EOF.
+      return is_eof || err == ERROR_BROKEN_PIPE;
+    }
+  }
+#else
+  return ReadFileDescriptor(h, out);
+#endif
+}
+
+bool ReadFileStream(FILE* f, std::string* out) {
+  return ReadFileDescriptor(fileno(f), out);
+}
+
+bool ReadFile(const std::string& path, std::string* out) {
+  base::ScopedFile fd = base::OpenFile(path, O_RDONLY);
+  if (!fd)
+    return false;
+
+  return ReadFileDescriptor(*fd, out);
+}
+
+ssize_t WriteAll(int fd, const void* buf, size_t count) {
+  size_t written = 0;
+  while (written < count) {
+    // write() on windows takes an unsigned int size.
+    uint32_t bytes_left = static_cast<uint32_t>(
+        std::min(count - written, static_cast<size_t>(UINT32_MAX)));
+    platform::BeforeMaybeBlockingSyscall();
+    ssize_t wr = PERFETTO_EINTR(
+        write(fd, static_cast<const char*>(buf) + written, bytes_left));
+    platform::AfterMaybeBlockingSyscall();
+    if (wr == 0)
+      break;
+    if (wr < 0)
+      return wr;
+    written += static_cast<size_t>(wr);
+  }
+  return static_cast<ssize_t>(written);
+}
+
+ssize_t WriteAllHandle(PlatformHandle h, const void* buf, size_t count) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  DWORD wsize = 0;
+  if (::WriteFile(h, buf, static_cast<DWORD>(count), &wsize, nullptr)) {
+    return wsize;
+  } else {
+    return -1;
+  }
+#else
+  return WriteAll(h, buf, count);
+#endif
+}
+
+bool FlushFile(int fd) {
+  PERFETTO_DCHECK(fd != 0);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  return !PERFETTO_EINTR(fdatasync(fd));
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return !PERFETTO_EINTR(_commit(fd));
+#else
+  return !PERFETTO_EINTR(fsync(fd));
+#endif
+}
+
+bool Mkdir(const std::string& path) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return _mkdir(path.c_str()) == 0;
+#else
+  return mkdir(path.c_str(), 0755) == 0;
+#endif
+}
+
+bool Rmdir(const std::string& path) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return _rmdir(path.c_str()) == 0;
+#else
+  return rmdir(path.c_str()) == 0;
+#endif
+}
+
+int CloseFile(int fd) {
+  return close(fd);
+}
+
+ScopedFile OpenFile(const std::string& path, int flags, FileOpenMode mode) {
+  // If a new file might be created, ensure that the permissions for the new
+  // file are explicitly specified.
+  PERFETTO_CHECK((flags & O_CREAT) == 0 || mode != kFileModeInvalid);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Always use O_BINARY on Windows, to avoid silly EOL translations.
+  ScopedFile fd(_open(path.c_str(), flags | O_BINARY, mode));
+#else
+  // Always open a ScopedFile with O_CLOEXEC so we can safely fork and exec.
+  ScopedFile fd(open(path.c_str(), flags | O_CLOEXEC, mode));
+#endif
+  return fd;
+}
+
+ScopedFstream OpenFstream(const char* path, const char* mode) {
+  ScopedFstream file;
+// On Windows fopen interprets filename using the ANSI or OEM codepage but
+// sqlite3_value_text returns a UTF-8 string. To make sure we interpret the
+// filename correctly we use _wfopen and a UTF-16 string on windows.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  auto w_path = ToUtf16(path);
+  auto w_mode = ToUtf16(mode);
+  if (w_path && w_mode) {
+    file.reset(_wfopen(w_path->c_str(), w_mode->c_str()));
+  }
+#else
+  file.reset(fopen(path, mode));
+#endif
+  return file;
+}
+
+bool FileExists(const std::string& path) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return _access(path.c_str(), 0) == 0;
+#else
+  return access(path.c_str(), F_OK) == 0;
+#endif
+}
+
+// Declared in base/platform_handle.h.
+int ClosePlatformHandle(PlatformHandle handle) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Make the return value UNIX-style.
+  return CloseHandle(handle) ? 0 : -1;
+#else
+  return close(handle);
+#endif
+}
+
+base::Status ListFilesRecursive(const std::string& dir_path,
+                                std::vector<std::string>& output) {
+  std::string root_dir_path = dir_path;
+  if (root_dir_path.back() == '\\') {
+    root_dir_path.back() = '/';
+  } else if (root_dir_path.back() != '/') {
+    root_dir_path.push_back('/');
+  }
+
+  // dir_queue contains full paths to the directories. The paths include the
+  // root_dir_path at the beginning and the trailing slash at the end.
+  std::deque<std::string> dir_queue;
+  dir_queue.push_back(root_dir_path);
+
+  while (!dir_queue.empty()) {
+    const std::string cur_dir = std::move(dir_queue.front());
+    dir_queue.pop_front();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+    return base::ErrStatus("ListFilesRecursive not supported yet");
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    std::string glob_path = cur_dir + "*";
+    // + 1 because we also have to count the NULL terminator.
+    if (glob_path.length() + 1 > MAX_PATH)
+      return base::ErrStatus("Directory path %s is too long", dir_path.c_str());
+    WIN32_FIND_DATAA ffd;
+
+    base::ScopedResource<HANDLE, CloseFindHandle, nullptr, false,
+                         base::PlatformHandleChecker>
+        hFind(FindFirstFileA(glob_path.c_str(), &ffd));
+    if (!hFind) {
+      // For empty directories, there should be at least one entry '.'.
+      // If FindFirstFileA returns INVALID_HANDLE_VALUE, this means directory
+      // couldn't be accessed.
+      return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
+    }
+    do {
+      if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0)
+        continue;
+      if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+        std::string subdir_path = cur_dir + ffd.cFileName + '/';
+        dir_queue.push_back(subdir_path);
+      } else {
+        const std::string full_path = cur_dir + ffd.cFileName;
+        PERFETTO_CHECK(full_path.length() > root_dir_path.length());
+        output.push_back(full_path.substr(root_dir_path.length()));
+      }
+    } while (FindNextFileA(*hFind, &ffd));
+#else
+    ScopedDir dir = ScopedDir(opendir(cur_dir.c_str()));
+    if (!dir) {
+      return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
+    }
+    for (auto* dirent = readdir(dir.get()); dirent != nullptr;
+         dirent = readdir(dir.get())) {
+      if (strcmp(dirent->d_name, ".") == 0 ||
+          strcmp(dirent->d_name, "..") == 0) {
+        continue;
+      }
+      if (dirent->d_type == DT_DIR) {
+        dir_queue.push_back(cur_dir + dirent->d_name + '/');
+      } else if (dirent->d_type == DT_REG) {
+        const std::string full_path = cur_dir + dirent->d_name;
+        PERFETTO_CHECK(full_path.length() > root_dir_path.length());
+        output.push_back(full_path.substr(root_dir_path.length()));
+      }
+    }
+#endif
+  }
+  return base::OkStatus();
+}
+
+std::string GetFileExtension(const std::string& filename) {
+  auto ext_idx = filename.rfind('.');
+  if (ext_idx == std::string::npos)
+    return std::string();
+  return filename.substr(ext_idx);
+}
+
+base::Status SetFilePermissions(const std::string& file_path,
+                                const std::string& group_name_or_id,
+                                const std::string& mode_bits) {
+#ifdef PERFETTO_SET_FILE_PERMISSIONS
+  PERFETTO_CHECK(!file_path.empty());
+  PERFETTO_CHECK(!group_name_or_id.empty());
+
+  // Default |group_id| to -1 for not changing the group ownership.
+  gid_t group_id = static_cast<gid_t>(-1);
+  auto maybe_group_id = base::StringToUInt32(group_name_or_id);
+  if (maybe_group_id) {  // A numerical group ID.
+    group_id = *maybe_group_id;
+  } else {  // A group name.
+    struct group* file_group = nullptr;
+    // Query the group ID of |group|.
+    do {
+      file_group = getgrnam(group_name_or_id.c_str());
+    } while (file_group == nullptr && errno == EINTR);
+    if (file_group == nullptr) {
+      return base::ErrStatus("Failed to get group information of %s ",
+                             group_name_or_id.c_str());
+    }
+    group_id = file_group->gr_gid;
+  }
+
+  if (PERFETTO_EINTR(chown(file_path.c_str(), geteuid(), group_id))) {
+    return base::ErrStatus("Failed to chown %s ", file_path.c_str());
+  }
+
+  // |mode| accepts values like "0660" as "rw-rw----" mode bits.
+  auto mode_value = base::StringToInt32(mode_bits, 8);
+  if (!(mode_bits.size() == 4 && mode_value.has_value())) {
+    return base::ErrStatus(
+        "The chmod mode bits must be a 4-digit octal number, e.g. 0660");
+  }
+  if (PERFETTO_EINTR(
+          chmod(file_path.c_str(), static_cast<mode_t>(mode_value.value())))) {
+    return base::ErrStatus("Failed to chmod %s", file_path.c_str());
+  }
+  return base::OkStatus();
+#else
+  base::ignore_result(file_path);
+  base::ignore_result(group_name_or_id);
+  base::ignore_result(mode_bits);
+  return base::ErrStatus(
+      "Setting file permissions is not supported on this platform");
+#endif
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/getopt_compat.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/getopt_compat.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
+#define INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
+
+#include <cstddef>  // For std::nullptr_t
+
+// No translation units other than base/getopt.h and getopt_compat_unittest.cc
+// should directly include this file. Use base/getopt.h instead.
+
+namespace perfetto {
+namespace base {
+namespace getopt_compat {
+
+// A tiny getopt() replacement for Windows, which doesn't have <getopt.h>.
+// This implementation is based on the subset of features that we use in the
+// Perfetto codebase. It doesn't even try to deal with the full surface of GNU's
+// getopt().
+// Limitations:
+// - getopt_long_only() is not supported.
+// - optional_argument is not supported. That is extremely subtle and caused us
+//   problems in the past with GNU's getopt.
+// - It does not reorder non-option arguments. It behaves like MacOS getopt, or
+//   GNU's when POSIXLY_CORRECT=1.
+// - Doesn't expose optopt or opterr.
+// - option.flag and longindex are not supported and must be nullptr.
+
+enum {
+  no_argument = 0,
+  required_argument = 1,
+};
+
+struct option {
+  const char* name;
+  int has_arg;
+  std::nullptr_t flag;  // Only nullptr is supported.
+  int val;
+};
+
+extern char* optarg;
+extern int optind;
+extern int optopt;
+extern int opterr;
+
+int getopt_long(int argc,
+                char** argv,
+                const char* shortopts,
+                const option* longopts,
+                std::nullptr_t /*longindex is not supported*/);
+
+int getopt(int argc, char** argv, const char* shortopts);
+
+}  // namespace getopt_compat
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/getopt_compat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+namespace getopt_compat {
+
+char* optarg = nullptr;
+int optind = 0;
+int optopt = 0;
+int opterr = 1;
+
+namespace {
+
+char* nextchar = nullptr;
+
+const option* LookupLongOpt(const std::vector<option>& opts,
+                            const char* name,
+                            size_t len) {
+  for (const option& opt : opts) {
+    if (strncmp(opt.name, name, len) == 0 && strlen(opt.name) == len)
+      return &opt;
+  }
+  return nullptr;
+}
+
+const option* LookupShortOpt(const std::vector<option>& opts, char c) {
+  for (const option& opt : opts) {
+    if (!*opt.name && opt.val == c)
+      return &opt;
+  }
+  return nullptr;
+}
+
+bool ParseOpts(const char* shortopts,
+               const option* longopts,
+               std::vector<option>* res) {
+  // Parse long options first.
+  for (const option* lopt = longopts; lopt && lopt->name; lopt++) {
+    PERFETTO_CHECK(lopt->flag == nullptr);
+    PERFETTO_CHECK(lopt->has_arg == no_argument ||
+                   lopt->has_arg == required_argument);
+    res->emplace_back(*lopt);
+  }
+
+  // Merge short options.
+  for (const char* sopt = shortopts; sopt && *sopt;) {
+    const size_t idx = static_cast<size_t>(sopt - shortopts);
+    char c = *sopt++;
+    bool valid = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
+                 (c >= '0' && c <= '9');
+    if (!valid) {
+      fprintf(stderr,
+              "Error parsing shortopts. Unexpected char '%c' at offset %zu\n",
+              c, idx);
+      return false;
+    }
+    res->emplace_back();
+    option& opt = res->back();
+    opt.name = "";
+    opt.val = c;
+    opt.has_arg = no_argument;
+    if (*sopt == ':') {
+      opt.has_arg = required_argument;
+      ++sopt;
+    }
+  }
+  return true;
+}
+
+}  // namespace
+
+int getopt_long(int argc,
+                char** argv,
+                const char* shortopts,
+                const option* longopts,
+                std::nullptr_t /*longind*/) {
+  std::vector<option> opts;
+  optarg = nullptr;
+
+  if (optind == 0)
+    optind = 1;
+
+  if (optind >= argc)
+    return -1;
+
+  if (!ParseOpts(shortopts, longopts, &opts))
+    return '?';
+
+  char* arg = argv[optind];
+  optopt = 0;
+
+  if (!nextchar) {
+    // If |nextchar| is null we are NOT in the middle of a short option and we
+    // should parse the next argv.
+    if (strncmp(arg, "--", 2) == 0 && strlen(arg) > 2) {
+      // A --long option.
+      arg += 2;
+      char* sep = strchr(arg, '=');
+      optind++;
+
+      size_t len = sep ? static_cast<size_t>(sep - arg) : strlen(arg);
+      const option* opt = LookupLongOpt(opts, arg, len);
+
+      if (!opt) {
+        if (opterr)
+          fprintf(stderr, "unrecognized option '--%s'\n", arg);
+        return '?';
+      }
+
+      optopt = opt->val;
+      if (opt->has_arg == no_argument) {
+        if (sep) {
+          fprintf(stderr, "option '--%s' doesn't allow an argument\n", arg);
+          return '?';
+        } else {
+          return opt->val;
+        }
+      } else if (opt->has_arg == required_argument) {
+        if (sep) {
+          optarg = sep + 1;
+          return opt->val;
+        } else if (optind >= argc) {
+          if (opterr)
+            fprintf(stderr, "option '--%s' requires an argument\n", arg);
+          return '?';
+        } else {
+          optarg = argv[optind++];
+          return opt->val;
+        }
+      }
+      // has_arg must be either |no_argument| or |required_argument|. We
+      // shoulnd't get here unless the check in ParseOpts() has a bug.
+      PERFETTO_CHECK(false);
+    }  // if (arg ~= "--*").
+
+    if (strlen(arg) > 1 && arg[0] == '-' && arg[1] != '-') {
+      // A sequence of short options. Parsing logic continues below.
+      nextchar = &arg[1];
+    }
+  }  // if(!nextchar)
+
+  if (nextchar) {
+    // At this point either:
+    // 1. This is the first char of a sequence of short options, and we fell
+    //    through here from the lines above.
+    // 2. This is the N (>1) char of a sequence of short options, and we got
+    //    here from a new getopt() call to getopt().
+    const char cur_char = *nextchar;
+    PERFETTO_CHECK(cur_char != '\0');
+
+    // Advance the option char in any case, before we start reasoning on them.
+    // if we got to the end of the "-abc" sequence, increment optind so the next
+    // getopt() call resumes from the next argv argument.
+    if (*(++nextchar) == '\0') {
+      nextchar = nullptr;
+      ++optind;
+    }
+
+    const option* opt = LookupShortOpt(opts, cur_char);
+    optopt = cur_char;
+    if (!opt) {
+      if (opterr)
+        fprintf(stderr, "invalid option -- '%c'\n", cur_char);
+      return '?';
+    }
+    if (opt->has_arg == no_argument) {
+      return cur_char;
+    } else if (opt->has_arg == required_argument) {
+      // This is a subtle getopt behavior. Say you call `tar -fx`, there are
+      // two cases:
+      // 1. If 'f' is no_argument then 'x' (and anything else after) is
+      //    interpreted as an independent argument (like `tar -f -x`).
+      // 2. If 'f' is required_argument, than everything else after the 'f'
+      //    is interpreted as the option argument (like `tar -f x`)
+      if (!nextchar) {
+        // Case 1.
+        if (optind >= argc) {
+          if (opterr)
+            fprintf(stderr, "option requires an argument -- '%c'\n", cur_char);
+          return '?';
+        } else {
+          optarg = argv[optind++];
+          return cur_char;
+        }
+      } else {
+        // Case 2.
+        optarg = nextchar;
+        nextchar = nullptr;
+        optind++;
+        return cur_char;
+      }
+    }
+    PERFETTO_CHECK(false);
+  }  // if (nextchar)
+
+  // If we get here, we found the first non-option argument. Stop here.
+
+  if (strcmp(arg, "--") == 0)
+    optind++;
+
+  return -1;
+}
+
+int getopt(int argc, char** argv, const char* shortopts) {
+  return getopt_long(argc, argv, shortopts, nullptr, nullptr);
+}
+
+}  // namespace getopt_compat
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/logging.cc
+// gen_amalgamated begin header: src/base/log_ring_buffer.h
+// gen_amalgamated begin header: include/perfetto/ext/base/thread_annotations.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// Windows TSAN doesn't currently support these annotations.
+#if defined(THREAD_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+extern "C" {
+void AnnotateBenignRaceSized(const char* file,
+                             int line,
+                             const volatile void* address,
+                             size_t size,
+                             const char* description);
+}
+
+#define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description) \
+  AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, size, description);
+#else  // defined(ADDRESS_SANITIZER)
+#define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)
+#endif  // defined(ADDRESS_SANITIZER)
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
+/*
+ * 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.
+ */
+
+#ifndef SRC_BASE_LOG_RING_BUFFER_H_
+#define SRC_BASE_LOG_RING_BUFFER_H_
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include <array>
+#include <atomic>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
+
+namespace perfetto {
+namespace base {
+
+// Defined out of line because a static constexpr requires static storage if
+// ODR-used, not worth adding a .cc file just for tests.
+constexpr size_t kLogRingBufEntries = 8;
+constexpr size_t kLogRingBufMsgLen = 256;
+
+// A static non-allocating ring-buffer to hold the most recent log events.
+// This class is really an implementation detail of logging.cc. The only reason
+// why is fully defined in a dedicated header is for allowing unittesting,
+// without leaking extra headers into logging.h (which is a high-fanout header).
+// This is used to report the last logs in a crash report when a CHECK/FATAL
+// is encountered.
+// This class has just an Append() method to insert events into the buffer and
+// a Read() to read the events in FIFO order. Read() is non-destructive.
+//
+// Thread safety considerations:
+// - The Append() method can be called concurrently by several threads, unless
+//   there are > kLogRingBufEntries concurrent threads. Even if that happens,
+//   case some events will contain a mix of strings but the behavior of
+//   futher Append() and Read() is still defined.
+// - The Read() method is not thread safe but it's fine in practice. Even if
+//   it's called concurrently with other Append(), it only causes some partial
+//   events to be emitted in output.
+// In both cases, we never rely purely on \0, all operations are size-bound.
+//
+// See logging_unittest.cc for tests.
+class LogRingBuffer {
+ public:
+  LogRingBuffer() = default;
+  LogRingBuffer(const LogRingBuffer&) = delete;
+  LogRingBuffer& operator=(const LogRingBuffer&) = delete;
+  LogRingBuffer(LogRingBuffer&&) = delete;
+  LogRingBuffer& operator=(LogRingBuffer&&) = delete;
+
+  // This takes three arguments because it fits its only caller (logging.cc).
+  // The args are just concatenated together (plus one space before the msg).
+  void Append(StringView tstamp, StringView source, StringView log_msg) {
+    // Reserve atomically a slot in the ring buffer, so any concurrent Append()
+    // won't overlap (unless too many concurrent Append() happen together).
+    // There is no strict synchronization here, |event_slot_| is atomic only for
+    // the sake of avoiding colliding on the same slot but does NOT guarantee
+    // full consistency and integrity of the log messages written in each slot.
+    // A release-store (or acq+rel) won't be enough for full consistency. Two
+    // threads that race on Append() and take the N+1 and N+2 slots could finish
+    // the write in reverse order. So Read() would need to synchronize with
+    // something else (either a per-slot atomic flag or with a second atomic
+    // counter which is incremented after the snprintf). Both options increase
+    // the cost of Append() with no huge benefits (90% of the perfetto services
+    // where we use it is single thread, and the log ring buffer is disabled
+    // on non-standalone builds like the SDK).
+    uint32_t slot = event_slot_.fetch_add(1, std::memory_order_relaxed);
+    slot = slot % kLogRingBufEntries;
+
+    char* const msg = events_[slot];
+    PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(msg, kLogRingBufMsgLen,
+                                        "see comments in log_ring_buffer.h")
+    snprintf(msg, kLogRingBufMsgLen, "%.*s%.*s %.*s",
+             static_cast<int>(tstamp.size()), tstamp.data(),
+             static_cast<int>(source.size()), source.data(),
+             static_cast<int>(log_msg.size()), log_msg.data());
+  }
+
+  // Reads back the buffer in FIFO order, up to |len - 1| characters at most
+  // (the -1 is because a NUL terminator is always appended, unless |len| == 0).
+  // The string written in |dst| is guaranteed to be NUL-terminated, even if
+  // |len| < buffer contents length.
+  // Returns the number of bytes written in output, excluding the \0 terminator.
+  size_t Read(char* dst, size_t len) {
+    if (len == 0)
+      return 0;
+    // This is a relaxed-load because we don't need to fully synchronize on the
+    // writing path for the reasons described in the fetch_add() above.
+    const uint32_t event_slot = event_slot_.load(std::memory_order_relaxed);
+    size_t dst_written = 0;
+    for (uint32_t pos = 0; pos < kLogRingBufEntries; ++pos) {
+      const uint32_t slot = (event_slot + pos) % kLogRingBufEntries;
+      const char* src = events_[slot];
+      if (*src == '\0')
+        continue;  // Empty slot. Skip.
+      char* const wptr = dst + dst_written;
+      // |src| might not be null terminated. This can happen if some
+      // thread-race happened. Limit the copy length.
+      const size_t limit = std::min(len - dst_written, kLogRingBufMsgLen);
+      for (size_t i = 0; i < limit; ++i) {
+        const char c = src[i];
+        ++dst_written;
+        if (c == '\0' || i == limit - 1) {
+          wptr[i] = '\n';
+          break;
+        }
+        // Skip non-printable ASCII characters to avoid confusing crash reports.
+        // Note that this deliberately mangles \n. Log messages should not have
+        // a \n in the middle and are NOT \n terminated. The trailing \n between
+        // each line is appended by the if () branch above.
+        const bool is_printable = c >= ' ' && c <= '~';
+        wptr[i] = is_printable ? c : '?';
+      }
+    }
+    // Ensure that the output string is null-terminated.
+    PERFETTO_DCHECK(dst_written <= len);
+    if (dst_written == len) {
+      // In case of truncation we replace the last char with \0. But the return
+      // value is the number of chars without \0, hence the --.
+      dst[--dst_written] = '\0';
+    } else {
+      dst[dst_written] = '\0';
+    }
+    return dst_written;
+  }
+
+ private:
+  using EventBuf = char[kLogRingBufMsgLen];
+  EventBuf events_[kLogRingBufEntries]{};
+
+  static_assert((kLogRingBufEntries & (kLogRingBufEntries - 1)) == 0,
+                "kLogRingBufEntries must be a power of two");
+
+  // A monotonically increasing counter incremented on each event written.
+  // It determines which of the kLogRingBufEntries indexes in |events_| should
+  // be used next.
+  // It grows >> kLogRingBufEntries, it's supposed to be always used
+  // mod(kLogRingBufEntries). A static_assert in the .cc file ensures that
+  // kLogRingBufEntries is a power of two so wraps are aligned.
+  std::atomic<uint32_t> event_slot_{};
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // SRC_BASE_LOG_RING_BUFFER_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <unistd.h>  // For isatty()
+#endif
+
+#include <atomic>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+// gen_amalgamated expanded: #include "src/base/log_ring_buffer.h"
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER() && PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <android/set_abort_message.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+namespace {
+const char kReset[] = "\x1b[0m";
+const char kDefault[] = "\x1b[39m";
+const char kDim[] = "\x1b[2m";
+const char kRed[] = "\x1b[31m";
+const char kBoldGreen[] = "\x1b[1m\x1b[32m";
+const char kLightGray[] = "\x1b[90m";
+
+std::atomic<LogMessageCallback> g_log_callback{};
+
+#if PERFETTO_BUILDFLAG(PERFETTO_STDERR_CRASH_DUMP)
+// __attribute__((constructor)) causes a static initializer that automagically
+// early runs this function before the main().
+void PERFETTO_EXPORT_COMPONENT __attribute__((constructor))
+InitDebugCrashReporter() {
+  // This function is defined in debug_crash_stack_trace.cc.
+  // The dynamic initializer is in logging.cc because logging.cc is included
+  // in virtually any target that depends on base. Having it in
+  // debug_crash_stack_trace.cc would require figuring out -Wl,whole-archive
+  // which is not worth it.
+  EnableStacktraceOnCrashForDebug();
+}
+#endif
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+LogRingBuffer g_log_ring_buffer{};
+
+// This is global to avoid allocating memory or growing too much the stack
+// in MaybeSerializeLastLogsForCrashReporting(), which is called from
+// arbitrary code paths hitting PERFETTO_CHECK()/FATAL().
+char g_crash_buf[kLogRingBufEntries * kLogRingBufMsgLen];
+#endif
+
+}  // namespace
+
+void SetLogMessageCallback(LogMessageCallback callback) {
+  g_log_callback.store(callback, std::memory_order_relaxed);
+}
+
+void LogMessage(LogLev level,
+                const char* fname,
+                int line,
+                const char* fmt,
+                ...) {
+  char stack_buf[512];
+  std::unique_ptr<char[]> large_buf;
+  char* log_msg = &stack_buf[0];
+  size_t log_msg_len = 0;
+
+  // By default use a stack allocated buffer because most log messages are quite
+  // short. In rare cases they can be larger (e.g. --help). In those cases we
+  // pay the cost of allocating the buffer on the heap.
+  for (size_t max_len = sizeof(stack_buf);;) {
+    va_list args;
+    va_start(args, fmt);
+    int res = vsnprintf(log_msg, max_len, fmt, args);
+    va_end(args);
+
+    // If for any reason the print fails, overwrite the message but still print
+    // it. The code below will attach the filename and line, which is still
+    // useful.
+    if (res < 0) {
+      snprintf(log_msg, max_len, "%s", "[printf format error]");
+      break;
+    }
+
+    // if res == max_len, vsnprintf saturated the input buffer. Retry with a
+    // larger buffer in that case (within reasonable limits).
+    if (res < static_cast<int>(max_len) || max_len >= 128 * 1024) {
+      // In case of truncation vsnprintf returns the len that "would have been
+      // written if the string was longer", not the actual chars written.
+      log_msg_len = std::min(static_cast<size_t>(res), max_len - 1);
+      break;
+    }
+    max_len *= 4;
+    large_buf.reset(new char[max_len]);
+    log_msg = &large_buf[0];
+  }
+
+  LogMessageCallback cb = g_log_callback.load(std::memory_order_relaxed);
+  if (cb) {
+    cb({level, line, fname, log_msg});
+    return;
+  }
+
+  const char* color = kDefault;
+  switch (level) {
+    case kLogDebug:
+      color = kDim;
+      break;
+    case kLogInfo:
+      color = kDefault;
+      break;
+    case kLogImportant:
+      color = kBoldGreen;
+      break;
+    case kLogError:
+      color = kRed;
+      break;
+  }
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&  \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+  static const bool use_colors = isatty(STDERR_FILENO);
+#else
+  static const bool use_colors = false;
+#endif
+
+  // Formats file.cc:line as a space-padded fixed width string. If the file name
+  // |fname| is too long, truncate it on the left-hand side.
+  StackString<10> line_str("%d", line);
+
+  // 24 will be the width of the file.cc:line column in the log event.
+  static constexpr size_t kMaxNameAndLine = 24;
+  size_t fname_len = strlen(fname);
+  size_t fname_max = kMaxNameAndLine - line_str.len() - 2;  // 2 = ':' + '\0'.
+  size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
+  StackString<kMaxNameAndLine> file_and_line(
+      "%*s:%s", static_cast<int>(fname_max), &fname[fname_offset],
+      line_str.c_str());
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // Logcat has already timestamping, don't re-emit it.
+  __android_log_print(int{ANDROID_LOG_DEBUG} + level, "perfetto", "%s %s",
+                      file_and_line.c_str(), log_msg);
+#endif
+
+  // When printing on stderr, print also the timestamp. We don't really care
+  // about the actual time. We just need some reference clock that can be used
+  // to correlated events across differrent processses (e.g. traced and
+  // traced_probes). The wall time % 1000 is good enough.
+  uint32_t t_ms = static_cast<uint32_t>(GetWallTimeMs().count());
+  uint32_t t_sec = t_ms / 1000;
+  t_ms -= t_sec * 1000;
+  t_sec = t_sec % 1000;
+  StackString<32> timestamp("[%03u.%03u] ", t_sec, t_ms);
+
+  if (use_colors) {
+    fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp.c_str(),
+            file_and_line.c_str(), kReset, color, log_msg, kReset);
+  } else {
+    fprintf(stderr, "%s%s %s\n", timestamp.c_str(), file_and_line.c_str(),
+            log_msg);
+  }
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+  // Append the message to the ring buffer for crash reporting postmortems.
+  StringView timestamp_sv = timestamp.string_view();
+  StringView file_and_line_sv = file_and_line.string_view();
+  StringView log_msg_sv(log_msg, static_cast<size_t>(log_msg_len));
+  g_log_ring_buffer.Append(timestamp_sv, file_and_line_sv, log_msg_sv);
+#else
+  ignore_result(log_msg_len);
+#endif
+}
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+void MaybeSerializeLastLogsForCrashReporting() {
+  // Keep this function minimal. This is called from the watchdog thread, often
+  // when the system is thrashing.
+
+  // This is racy because two threads could hit a CHECK/FATAL at the same time.
+  // But if that happens we have bigger problems, not worth designing around it.
+  // The behaviour is still defined in the race case (the string attached to
+  // the crash report will contain a mixture of log strings).
+  size_t wr = 0;
+  wr += SerializeCrashKeys(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
+  wr += g_log_ring_buffer.Read(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
+
+  // Read() null-terminates the string properly. This is just to avoid UB when
+  // two threads race on each other (T1 writes a shorter string, T2
+  // overwrites the \0 writing a longer string. T1 continues here before T2
+  // finishes writing the longer string with the \0 -> boom.
+  g_crash_buf[sizeof(g_crash_buf) - 1] = '\0';
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // android_set_abort_message() will cause debuggerd to report the message
+  // in the tombstone and in the crash log in logcat.
+  // NOTE: android_set_abort_message() can be called only once. This should
+  // be called only when we are sure we are about to crash.
+  android_set_abort_message(g_crash_buf);
+#else
+  // Print out the message on stderr on Linux/Mac/Win.
+  fputs("\n-----BEGIN PERFETTO PRE-CRASH LOG-----\n", stderr);
+  fputs(g_crash_buf, stderr);
+  fputs("\n-----END PERFETTO PRE-CRASH LOG-----\n", stderr);
+#endif
+}
+#endif  // PERFETTO_ENABLE_LOG_RING_BUFFER
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/metatrace.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/metatrace.h
+// gen_amalgamated begin header: include/perfetto/ext/base/metatrace_events.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
+
+#include <stdint.h>
+
+namespace perfetto {
+namespace metatrace {
+
+enum Tags : uint32_t {
+  TAG_NONE = 0,
+  TAG_ANY = uint32_t(-1),
+  TAG_FTRACE = 1 << 0,
+  TAG_PROC_POLLERS = 1 << 1,
+  TAG_TRACE_WRITER = 1 << 2,
+  TAG_TRACE_SERVICE = 1 << 3,
+  TAG_PRODUCER = 1 << 4,
+};
+
+// The macros below generate matching enums and arrays of string literals.
+// This is to avoid maintaining string maps manually.
+
+// clang-format off
+
+// DO NOT remove or reshuffle items in this list, only append. The ID of these
+// events are an ABI, the trace processor relies on these to open old traces.
+#define PERFETTO_METATRACE_EVENTS(F) \
+  F(EVENT_ZERO_UNUSED), \
+  F(FTRACE_CPU_READER_READ), /*unused*/ \
+  F(FTRACE_DRAIN_CPUS), /*unused*/ \
+  F(FTRACE_UNBLOCK_READERS), /*unused*/ \
+  F(FTRACE_CPU_READ_NONBLOCK), /*unused*/ \
+  F(FTRACE_CPU_READ_BLOCK), /*unused*/ \
+  F(FTRACE_CPU_SPLICE_NONBLOCK), /*unused*/ \
+  F(FTRACE_CPU_SPLICE_BLOCK), /*unused*/ \
+  F(FTRACE_CPU_WAIT_CMD), /*unused*/ \
+  F(FTRACE_CPU_RUN_CYCLE), /*unused*/ \
+  F(FTRACE_CPU_FLUSH), \
+  F(FTRACE_CPU_DRAIN), /*unused*/ \
+  F(READ_SYS_STATS), \
+  F(PS_WRITE_ALL_PROCESSES), \
+  F(PS_ON_PIDS), \
+  F(PS_ON_RENAME_PIDS), \
+  F(PS_WRITE_ALL_PROCESS_STATS), \
+  F(TRACE_WRITER_COMMIT_STARTUP_WRITER_BATCH), \
+  F(FTRACE_READ_TICK), \
+  F(FTRACE_CPU_READ_CYCLE), \
+  F(FTRACE_CPU_READ_BATCH), \
+  F(KALLSYMS_PARSE), \
+  F(PROFILER_READ_TICK), \
+  F(PROFILER_READ_CPU), \
+  F(PROFILER_UNWIND_TICK), \
+  F(PROFILER_UNWIND_SAMPLE), \
+  F(PROFILER_UNWIND_INITIAL_ATTEMPT), \
+  F(PROFILER_UNWIND_ATTEMPT), \
+  F(PROFILER_MAPS_PARSE), \
+  F(PROFILER_MAPS_REPARSE), \
+  F(PROFILER_UNWIND_CACHE_CLEAR)
+
+// Append only, see above.
+//
+// Values that aren't used as counters:
+// * FTRACE_SERVICE_COMMIT_DATA is a bit-packed representation of an event, see
+//   tracing_service_impl.cc for the format.
+// * PROFILER_UNWIND_CURRENT_PID represents the PID that is being unwound.
+//
+#define PERFETTO_METATRACE_COUNTERS(F) \
+  F(COUNTER_ZERO_UNUSED),\
+  F(FTRACE_PAGES_DRAINED), \
+  F(PS_PIDS_SCANNED), \
+  F(TRACE_SERVICE_COMMIT_DATA), \
+  F(PROFILER_UNWIND_QUEUE_SZ), \
+  F(PROFILER_UNWIND_CURRENT_PID)
+
+// clang-format on
+
+#define PERFETTO_METATRACE_IDENTITY(name) name
+#define PERFETTO_METATRACE_TOSTRING(name) #name
+
+enum Events : uint16_t {
+  PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_IDENTITY),
+  EVENTS_MAX
+};
+constexpr char const* kEventNames[] = {
+    PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_TOSTRING)};
+
+enum Counters : uint16_t {
+  PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_IDENTITY),
+  COUNTERS_MAX
+};
+constexpr char const* kCounterNames[] = {
+    PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_TOSTRING)};
+
+inline void SuppressUnusedVarsInAmalgamatedBuild() {
+  (void)kCounterNames;
+  (void)kEventNames;
+}
+
+}  // namespace metatrace
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
+#define INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
+
+#include <array>
+#include <atomic>
+#include <functional>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace_events.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+// A facility to trace execution of the perfetto codebase itself.
+// The meta-tracing framework is organized into three layers:
+//
+// 1. A static ring-buffer in base/ (this file) that supports concurrent writes
+//    and a single reader.
+//    The responsibility of this layer is to store events and counters as
+//    efficiently as possible without re-entering any tracing code.
+//    This is really a static-storage-based ring-buffer based on a POD array.
+//    This layer does NOT deal with serializing the meta-trace buffer.
+//    It posts a task when it's half full and expects something outside of
+//    base/ to drain the ring-buffer and serialize it, eventually writing it
+//    into the trace itself, before it gets 100% full.
+//
+// 2. A class in tracing/core which takes care of serializing the meta-trace
+//    buffer into the trace using a TraceWriter. See metatrace_writer.h .
+//
+// 3. A data source in traced_probes that, when be enabled via the trace config,
+//    injects metatrace events into the trace. See metatrace_data_source.h .
+//
+// The available events and tags are defined in metatrace_events.h .
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace metatrace {
+
+// Meta-tracing is organized in "tags" that can be selectively enabled. This is
+// to enable meta-tracing only of one sub-system. This word has one "enabled"
+// bit for each tag. 0 -> meta-tracing off.
+extern std::atomic<uint32_t> g_enabled_tags;
+
+// Time of the Enable() call. Used as a reference for keeping delta timestmaps
+// in Record.
+extern std::atomic<uint64_t> g_enabled_timestamp;
+
+// Enables meta-tracing for one or more tags. Once enabled it will discard any
+// further Enable() calls and return false until disabled,
+// |read_task| is a closure that will be called enqueued |task_runner| when the
+// meta-tracing ring buffer is half full. The task is expected to read the ring
+// buffer using RingBuffer::GetReadIterator() and serialize the contents onto a
+// file or into the trace itself.
+// Must be called on the |task_runner| passed.
+// |task_runner| must have static lifetime.
+bool Enable(std::function<void()> read_task, base::TaskRunner*, uint32_t tags);
+
+// Disables meta-tracing.
+// Must be called on the same |task_runner| as Enable().
+void Disable();
+
+inline uint64_t TraceTimeNowNs() {
+  return static_cast<uint64_t>(base::GetBootTimeNs().count());
+}
+
+// Returns a relaxed view of whether metatracing is enabled for the given tag.
+// Useful for skipping unnecessary argument computation if metatracing is off.
+inline bool IsEnabled(uint32_t tag) {
+  auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
+  return PERFETTO_UNLIKELY((enabled_tags & tag) != 0);
+}
+
+// Holds the data for a metatrace event or counter.
+struct Record {
+  static constexpr uint16_t kTypeMask = 0x8000;
+  static constexpr uint16_t kTypeCounter = 0x8000;
+  static constexpr uint16_t kTypeEvent = 0;
+
+  uint64_t timestamp_ns() const {
+    auto base_ns = g_enabled_timestamp.load(std::memory_order_relaxed);
+    PERFETTO_DCHECK(base_ns);
+    return base_ns + ((static_cast<uint64_t>(timestamp_ns_high) << 32) |
+                      timestamp_ns_low);
+  }
+
+  void set_timestamp(uint64_t ts) {
+    auto t_start = g_enabled_timestamp.load(std::memory_order_relaxed);
+    uint64_t diff = ts - t_start;
+    PERFETTO_DCHECK(diff < (1ull << 48));
+    timestamp_ns_low = static_cast<uint32_t>(diff);
+    timestamp_ns_high = static_cast<uint16_t>(diff >> 32);
+  }
+
+  // We can't just memset() this class because on MSVC std::atomic<> is not
+  // trivially constructible anymore. Also std::atomic<> has a deleted copy
+  // constructor so we cant just do "*this = Record()" either.
+  // See http://bit.ly/339Jlzd .
+  void clear() {
+    this->~Record();
+    new (this) Record();
+  }
+
+  // This field holds the type (counter vs event) in the MSB and event ID (as
+  // defined in metatrace_events.h) in the lowest 15 bits. It is also used also
+  // as a linearization point: this is always written after all the other
+  // fields with a release-store. This is so the reader can determine whether it
+  // can safely process the other event fields after a load-acquire.
+  std::atomic<uint16_t> type_and_id{};
+
+  // Timestamp is stored as a 48-bits value diffed against g_enabled_timestamp.
+  // This gives us 78 hours from Enabled().
+  uint16_t timestamp_ns_high = 0;
+  uint32_t timestamp_ns_low = 0;
+
+  uint32_t thread_id = 0;
+
+  union {
+    // Only one of the two elements can be zero initialized, clang complains
+    // about "initializing multiple members of union" otherwise.
+    uint32_t duration_ns = 0;  // If type == event.
+    int32_t counter_value;     // If type == counter.
+  };
+};
+
+// Hold the meta-tracing data into a statically allocated array.
+// This class uses static storage (as opposite to being a singleton) to:
+// - Have the guarantee of always valid storage, so that meta-tracing can be
+//   safely used in any part of the codebase, including base/ itself.
+// - Avoid barriers that thread-safe static locals would require.
+class RingBuffer {
+ public:
+  static constexpr size_t kCapacity = 4096;  // 4096 * 16 bytes = 64K.
+
+  // This iterator is not idempotent and will bump the read index in the buffer
+  // at the end of the reads. There can be only one reader at any time.
+  // Usage: for (auto it = RingBuffer::GetReadIterator(); it; ++it) { it->... }
+  class ReadIterator {
+   public:
+    ReadIterator(ReadIterator&& other) {
+      PERFETTO_DCHECK(other.valid_);
+      cur_ = other.cur_;
+      end_ = other.end_;
+      valid_ = other.valid_;
+      other.valid_ = false;
+    }
+
+    ~ReadIterator() {
+      if (!valid_)
+        return;
+      PERFETTO_DCHECK(cur_ >= RingBuffer::rd_index_);
+      PERFETTO_DCHECK(cur_ <= RingBuffer::wr_index_);
+      RingBuffer::rd_index_.store(cur_, std::memory_order_release);
+    }
+
+    explicit operator bool() const { return cur_ < end_; }
+    const Record* operator->() const { return RingBuffer::At(cur_); }
+    const Record& operator*() const { return *operator->(); }
+
+    // This is for ++it. it++ is deliberately not supported.
+    ReadIterator& operator++() {
+      PERFETTO_DCHECK(cur_ < end_);
+      // Once a record has been read, mark it as free clearing its type_and_id,
+      // so if we encounter it in another read iteration while being written
+      // we know it's not fully written yet.
+      // The memory_order_relaxed below is enough because:
+      // - The reader is single-threaded and doesn't re-read the same records.
+      // - Before starting a read batch, the reader has an acquire barrier on
+      //   |rd_index_|.
+      // - After terminating a read batch, the ~ReadIterator dtor updates the
+      //   |rd_index_| with a release-store.
+      // - Reader and writer are typically kCapacity/2 apart. So unless an
+      //   overrun happens a writer won't reuse a newly released record any time
+      //   soon. If an overrun happens, everything is busted regardless.
+      At(cur_)->type_and_id.store(0, std::memory_order_relaxed);
+      ++cur_;
+      return *this;
+    }
+
+   private:
+    friend class RingBuffer;
+    ReadIterator(uint64_t begin, uint64_t end)
+        : cur_(begin), end_(end), valid_(true) {}
+    ReadIterator& operator=(const ReadIterator&) = delete;
+    ReadIterator(const ReadIterator&) = delete;
+
+    uint64_t cur_;
+    uint64_t end_;
+    bool valid_;
+  };
+
+  static Record* At(uint64_t index) {
+    // Doesn't really have to be pow2, but if not the compiler will emit
+    // arithmetic operations to compute the modulo instead of a bitwise AND.
+    static_assert(!(kCapacity & (kCapacity - 1)), "kCapacity must be pow2");
+    PERFETTO_DCHECK(index >= rd_index_);
+    PERFETTO_DCHECK(index <= wr_index_);
+    return &records_[index % kCapacity];
+  }
+
+  // Must be called on the same task runner passed to Enable()
+  static ReadIterator GetReadIterator() {
+    PERFETTO_DCHECK(RingBuffer::IsOnValidTaskRunner());
+    return ReadIterator(rd_index_.load(std::memory_order_acquire),
+                        wr_index_.load(std::memory_order_acquire));
+  }
+
+  static Record* AppendNewRecord();
+  static void Reset();
+
+  static bool has_overruns() {
+    return has_overruns_.load(std::memory_order_acquire);
+  }
+
+  // Can temporarily return a value >= kCapacity but is eventually consistent.
+  // This would happen in case of overruns until threads hit the --wr_index_
+  // in AppendNewRecord().
+  static uint64_t GetSizeForTesting() {
+    auto wr_index = wr_index_.load(std::memory_order_relaxed);
+    auto rd_index = rd_index_.load(std::memory_order_relaxed);
+    PERFETTO_DCHECK(wr_index >= rd_index);
+    return wr_index - rd_index;
+  }
+
+ private:
+  friend class ReadIterator;
+
+  // Returns true if the caller is on the task runner passed to Enable().
+  // Used only for DCHECKs.
+  static bool IsOnValidTaskRunner();
+
+  static std::array<Record, kCapacity> records_;
+  static std::atomic<bool> read_task_queued_;
+  static std::atomic<uint64_t> wr_index_;
+  static std::atomic<uint64_t> rd_index_;
+  static std::atomic<bool> has_overruns_;
+  static Record bankruptcy_record_;  // Used in case of overruns.
+};
+
+inline void TraceCounter(uint32_t tag, uint16_t id, int32_t value) {
+  // memory_order_relaxed is okay because the storage has static lifetime.
+  // It is safe to accidentally log an event soon after disabling.
+  auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
+  if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
+    return;
+  Record* record = RingBuffer::AppendNewRecord();
+  record->thread_id = static_cast<uint32_t>(base::GetThreadId());
+  record->set_timestamp(TraceTimeNowNs());
+  record->counter_value = value;
+  record->type_and_id.store(Record::kTypeCounter | id,
+                            std::memory_order_release);
+}
+
+class ScopedEvent {
+ public:
+  ScopedEvent(uint32_t tag, uint16_t event_id) {
+    auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
+    if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
+      return;
+    event_id_ = event_id;
+    record_ = RingBuffer::AppendNewRecord();
+    record_->thread_id = static_cast<uint32_t>(base::GetThreadId());
+    record_->set_timestamp(TraceTimeNowNs());
+  }
+
+  ~ScopedEvent() {
+    if (PERFETTO_LIKELY(!record_))
+      return;
+    auto now = TraceTimeNowNs();
+    record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns());
+    record_->type_and_id.store(Record::kTypeEvent | event_id_,
+                               std::memory_order_release);
+  }
+
+ private:
+  Record* record_ = nullptr;
+  uint16_t event_id_ = 0;
+  ScopedEvent(const ScopedEvent&) = delete;
+  ScopedEvent& operator=(const ScopedEvent&) = delete;
+};
+
+// Boilerplate to derive a unique variable name for the event.
+#define PERFETTO_METATRACE_UID2(a, b) a##b
+#define PERFETTO_METATRACE_UID(x) PERFETTO_METATRACE_UID2(metatrace_, x)
+
+#define PERFETTO_METATRACE_SCOPED(TAG, ID)                                \
+  ::perfetto::metatrace::ScopedEvent PERFETTO_METATRACE_UID(__COUNTER__)( \
+      ::perfetto::metatrace::TAG, ::perfetto::metatrace::ID)
+
+#define PERFETTO_METATRACE_COUNTER(TAG, ID, VALUE)                \
+  ::perfetto::metatrace::TraceCounter(::perfetto::metatrace::TAG, \
+                                      ::perfetto::metatrace::ID,  \
+                                      static_cast<int32_t>(VALUE))
+
+}  // namespace metatrace
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
+// gen_amalgamated begin header: include/perfetto/base/task_runner.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
+#define INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
+
+#include <stdint.h>
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+
+namespace perfetto {
+namespace base {
+
+// A generic interface to allow the library clients to interleave the execution
+// of the tracing internals in their runtime environment.
+// The expectation is that all tasks, which are queued either via PostTask() or
+// AddFileDescriptorWatch(), are executed on the same sequence (either on the
+// same thread, or on a thread pool that gives sequencing guarantees).
+//
+// Tasks are never executed synchronously inside PostTask and there is a full
+// memory barrier between tasks.
+//
+// All methods of this interface can be called from any thread.
+class PERFETTO_EXPORT_COMPONENT TaskRunner {
+ public:
+  virtual ~TaskRunner();
+
+  // Schedule a task for immediate execution. Immediate tasks are always
+  // executed in the order they are posted. Can be called from any thread.
+  virtual void PostTask(std::function<void()>) = 0;
+
+  // Schedule a task for execution after |delay_ms|. Note that there is no
+  // strict ordering guarantee between immediate and delayed tasks. Can be
+  // called from any thread.
+  virtual void PostDelayedTask(std::function<void()>, uint32_t delay_ms) = 0;
+
+  // Schedule a task to run when the handle becomes readable. The same handle
+  // can only be monitored by one function. Note that this function only needs
+  // to be implemented on platforms where the built-in ipc framework is used.
+  // Can be called from any thread.
+  // TODO(skyostil): Refactor this out of the shared interface.
+  virtual void AddFileDescriptorWatch(PlatformHandle,
+                                      std::function<void()>) = 0;
+
+  // Remove a previously scheduled watch for the handle. If this is run on the
+  // target thread of this TaskRunner, guarantees that the task registered to
+  // this handle will not be executed after this function call.
+  // Can be called from any thread.
+  virtual void RemoveFileDescriptorWatch(PlatformHandle) = 0;
+
+  // Checks if the current thread is the same thread where the TaskRunner's task
+  // run. This allows single threaded task runners (like the ones used in
+  // perfetto) to inform the caller that anything posted will run on the same
+  // thread/sequence. This can allow some callers to skip PostTask and instead
+  // directly execute the code. Can be called from any thread.
+  virtual bool RunsTasksOnCurrentThread() const = 0;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
+
+namespace perfetto {
+namespace metatrace {
+
+std::atomic<uint32_t> g_enabled_tags{0};
+std::atomic<uint64_t> g_enabled_timestamp{0};
+
+// static members
+std::array<Record, RingBuffer::kCapacity> RingBuffer::records_;
+std::atomic<bool> RingBuffer::read_task_queued_;
+std::atomic<uint64_t> RingBuffer::wr_index_;
+std::atomic<uint64_t> RingBuffer::rd_index_;
+std::atomic<bool> RingBuffer::has_overruns_;
+Record RingBuffer::bankruptcy_record_;
+
+namespace {
+
+// std::function<> is not trivially de/constructible. This struct wraps it in a
+// heap-allocated struct to avoid static initializers.
+struct Delegate {
+  static Delegate* GetInstance() {
+    static Delegate* instance = new Delegate();
+    return instance;
+  }
+
+  base::TaskRunner* task_runner = nullptr;
+  std::function<void()> read_task;
+};
+
+}  // namespace
+
+bool Enable(std::function<void()> read_task,
+            base::TaskRunner* task_runner,
+            uint32_t tags) {
+  PERFETTO_DCHECK(read_task);
+  PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
+  if (g_enabled_tags.load(std::memory_order_acquire))
+    return false;
+
+  Delegate* dg = Delegate::GetInstance();
+  dg->task_runner = task_runner;
+  dg->read_task = std::move(read_task);
+  RingBuffer::Reset();
+  g_enabled_timestamp.store(TraceTimeNowNs(), std::memory_order_relaxed);
+  g_enabled_tags.store(tags, std::memory_order_release);
+  return true;
+}
+
+void Disable() {
+  g_enabled_tags.store(0, std::memory_order_release);
+  Delegate* dg = Delegate::GetInstance();
+  PERFETTO_DCHECK(!dg->task_runner ||
+                  dg->task_runner->RunsTasksOnCurrentThread());
+  dg->task_runner = nullptr;
+  dg->read_task = nullptr;
+}
+
+// static
+void RingBuffer::Reset() {
+  bankruptcy_record_.clear();
+  for (Record& record : records_)
+    record.clear();
+  wr_index_ = 0;
+  rd_index_ = 0;
+  has_overruns_ = false;
+  read_task_queued_ = false;
+}
+
+// static
+Record* RingBuffer::AppendNewRecord() {
+  auto wr_index = wr_index_.fetch_add(1, std::memory_order_acq_rel);
+
+  // rd_index can only monotonically increase, we don't care if we read an
+  // older value, we'll just hit the slow-path a bit earlier if it happens.
+  auto rd_index = rd_index_.load(std::memory_order_relaxed);
+
+  PERFETTO_DCHECK(wr_index >= rd_index);
+  auto size = wr_index - rd_index;
+  if (PERFETTO_LIKELY(size < kCapacity / 2))
+    return At(wr_index);
+
+  // Slow-path: Enqueue the read task and handle overruns.
+  bool expected = false;
+  if (RingBuffer::read_task_queued_.compare_exchange_strong(expected, true)) {
+    Delegate* dg = Delegate::GetInstance();
+    if (dg->task_runner) {
+      dg->task_runner->PostTask([] {
+        // Meta-tracing might have been disabled in the meantime.
+        auto read_task = Delegate::GetInstance()->read_task;
+        if (read_task)
+          read_task();
+        RingBuffer::read_task_queued_ = false;
+      });
+    }
+  }
+
+  if (PERFETTO_LIKELY(size < kCapacity))
+    return At(wr_index);
+
+  has_overruns_.store(true, std::memory_order_release);
+  wr_index_.fetch_sub(1, std::memory_order_acq_rel);
+
+  // In the case of overflows, threads will race writing on the same memory
+  // location and TSan will rightly complain. This is fine though because nobody
+  // will read the bankruptcy record and it's designed to contain garbage.
+  PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&bankruptcy_record_, sizeof(Record),
+                                      "nothing reads bankruptcy_record_")
+  return &bankruptcy_record_;
+}
+
+// static
+bool RingBuffer::IsOnValidTaskRunner() {
+  auto* task_runner = Delegate::GetInstance()->task_runner;
+  return task_runner && task_runner->RunsTasksOnCurrentThread();
+}
+
+}  // namespace metatrace
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/paged_memory.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/paged_memory.h
+// gen_amalgamated begin header: include/perfetto/ext/base/container_annotations.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// Windows ASAN doesn't currently support these annotations.
+#if defined(ADDRESS_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !defined(ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION)
+
+#include <sanitizer/common_interface_defs.h>
+
+#define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)                      \
+  if (buffer) {                                                              \
+    __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
+                                              (buffer) + (capacity),         \
+                                              (buffer) + (new_size));        \
+  }
+#define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)                   \
+  if (buffer) {                                                              \
+    __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
+                                              (buffer) + (old_size),         \
+                                              (buffer) + (capacity));        \
+  }
+#define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)           \
+  if (buffer) {                                                              \
+    __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
+                                              (buffer) + (old_size),         \
+                                              (buffer) + (new_size));        \
+  }
+#define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
+                                 new_capacity)                      \
+  ANNOTATE_DELETE_BUFFER(buffer, old_capacity, buffer_size);        \
+  ANNOTATE_NEW_BUFFER(buffer, new_capacity, buffer_size);
+// Annotations require buffers to begin on an 8-byte boundary.
+#else  // defined(ADDRESS_SANITIZER)
+#define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)
+#define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)
+#define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)
+#define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
+                                 new_capacity)
+#endif  // defined(ADDRESS_SANITIZER)
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
+#define INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
+
+#include <cstddef>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
+
+// We need to track the committed size on windows and when ASAN is enabled.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || defined(ADDRESS_SANITIZER)
+#define TRACK_COMMITTED_SIZE() 1
+#else
+#define TRACK_COMMITTED_SIZE() 0
+#endif
+
+namespace perfetto {
+namespace base {
+
+class PagedMemory {
+ public:
+  // Initializes an invalid PagedMemory pointing to nullptr.
+  PagedMemory();
+
+  ~PagedMemory();
+
+  PagedMemory(PagedMemory&& other) noexcept;
+  PagedMemory& operator=(PagedMemory&& other);
+
+  enum AllocationFlags {
+    // By default, Allocate() crashes if the underlying mmap fails (e.g., if out
+    // of virtual address space). When this flag is provided, an invalid
+    // PagedMemory pointing to nullptr is returned in this case instead.
+    kMayFail = 1 << 0,
+
+    // By default, Allocate() commits the allocated memory immediately. When
+    // this flag is provided, the memory virtual address space may only be
+    // reserved and the user should call EnsureCommitted() before writing to
+    // memory addresses.
+    kDontCommit = 1 << 1,
+  };
+
+  // Allocates |size| bytes using mmap(MAP_ANONYMOUS). The returned memory is
+  // guaranteed to be page-aligned and guaranteed to be zeroed.
+  // For |flags|, see the AllocationFlags enum above.
+  static PagedMemory Allocate(size_t size, int flags = 0);
+
+  // Hint to the OS that the memory range is not needed and can be discarded.
+  // The memory remains accessible and its contents may be retained, or they
+  // may be zeroed. This function may be a NOP on some platforms. Returns true
+  // if implemented.
+  bool AdviseDontNeed(void* p, size_t size);
+
+  // Ensures that at least the first |committed_size| bytes of the allocated
+  // memory region are committed. The implementation may commit memory in larger
+  // chunks above |committed_size|. Crashes if the memory couldn't be committed.
+#if TRACK_COMMITTED_SIZE()
+  void EnsureCommitted(size_t committed_size);
+#else   // TRACK_COMMITTED_SIZE()
+  void EnsureCommitted(size_t /*committed_size*/) {}
+#endif  // TRACK_COMMITTED_SIZE()
+
+  inline void* Get() const noexcept { return p_; }
+  inline bool IsValid() const noexcept { return !!p_; }
+  inline size_t size() const noexcept { return size_; }
+
+ private:
+  PagedMemory(char* p, size_t size);
+
+  PagedMemory(const PagedMemory&) = delete;
+  // Defaulted for implementation of move constructor + assignment.
+  PagedMemory& operator=(const PagedMemory&) = default;
+
+  char* p_ = nullptr;
+
+  // The size originally passed to Allocate(). The actual virtual memory
+  // reservation will be larger due to: (i) guard pages; (ii) rounding up to
+  // the system page size.
+  size_t size_ = 0;
+
+#if TRACK_COMMITTED_SIZE()
+  size_t committed_size_ = 0u;
+#endif  // TRACK_COMMITTED_SIZE()
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
+
+#include <algorithm>
+#include <cmath>
+#include <cstddef>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <sys/mman.h>
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+#if TRACK_COMMITTED_SIZE()
+constexpr size_t kCommitChunkSize = 4 * 1024 * 1024;  // 4MB
+#endif
+
+size_t RoundUpToSysPageSize(size_t req_size) {
+  const size_t page_size = GetSysPageSize();
+  return (req_size + page_size - 1) & ~(page_size - 1);
+}
+
+size_t GuardSize() {
+  return GetSysPageSize();
+}
+
+}  // namespace
+
+// static
+PagedMemory PagedMemory::Allocate(size_t req_size, int flags) {
+  size_t rounded_up_size = RoundUpToSysPageSize(req_size);
+  PERFETTO_CHECK(rounded_up_size >= req_size);
+  size_t outer_size = rounded_up_size + GuardSize() * 2;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  void* ptr = VirtualAlloc(nullptr, outer_size, MEM_RESERVE, PAGE_NOACCESS);
+  if (!ptr && (flags & kMayFail))
+    return PagedMemory();
+  PERFETTO_CHECK(ptr);
+  char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
+#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  void* ptr = mmap(nullptr, outer_size, PROT_READ | PROT_WRITE,
+                   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (ptr == MAP_FAILED && (flags & kMayFail))
+    return PagedMemory();
+  PERFETTO_CHECK(ptr && ptr != MAP_FAILED);
+  char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
+  int res = mprotect(ptr, GuardSize(), PROT_NONE);
+  res |= mprotect(usable_region + rounded_up_size, GuardSize(), PROT_NONE);
+  PERFETTO_CHECK(res == 0);
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+  auto memory = PagedMemory(usable_region, req_size);
+#if TRACK_COMMITTED_SIZE()
+  size_t initial_commit = req_size;
+  if (flags & kDontCommit)
+    initial_commit = std::min(initial_commit, kCommitChunkSize);
+  memory.EnsureCommitted(initial_commit);
+#endif  // TRACK_COMMITTED_SIZE()
+  return memory;
+}
+
+PagedMemory::PagedMemory() {}
+
+// clang-format off
+PagedMemory::PagedMemory(char* p, size_t size) : p_(p), size_(size) {
+  ANNOTATE_NEW_BUFFER(p_, size_, committed_size_)
+}
+
+PagedMemory::PagedMemory(PagedMemory&& other) noexcept {
+  *this = other;
+  other.p_ = nullptr;
+}
+// clang-format on
+
+PagedMemory& PagedMemory::operator=(PagedMemory&& other) {
+  this->~PagedMemory();
+  new (this) PagedMemory(std::move(other));
+  return *this;
+}
+
+PagedMemory::~PagedMemory() {
+  if (!p_)
+    return;
+  PERFETTO_CHECK(size_);
+  char* start = p_ - GuardSize();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  BOOL res = VirtualFree(start, 0, MEM_RELEASE);
+  PERFETTO_CHECK(res != 0);
+#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  const size_t outer_size = RoundUpToSysPageSize(size_) + GuardSize() * 2;
+  int res = munmap(start, outer_size);
+  PERFETTO_CHECK(res == 0);
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  ANNOTATE_DELETE_BUFFER(p_, size_, committed_size_)
+}
+
+bool PagedMemory::AdviseDontNeed(void* p, size_t size) {
+  PERFETTO_DCHECK(p_);
+  PERFETTO_DCHECK(p >= p_);
+  PERFETTO_DCHECK(static_cast<char*>(p) + size <= p_ + size_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+  // Discarding pages on Windows has more CPU cost than is justified for the
+  // possible memory savings.
+  return false;
+#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
+        // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+  // http://man7.org/linux/man-pages/man2/madvise.2.html
+  int res = madvise(p, size, MADV_DONTNEED);
+  PERFETTO_DCHECK(res == 0);
+  return true;
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
+        // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+}
+
+#if TRACK_COMMITTED_SIZE()
+void PagedMemory::EnsureCommitted(size_t committed_size) {
+  PERFETTO_DCHECK(committed_size <= size_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if (committed_size_ >= committed_size)
+    return;
+  // Rounding up.
+  size_t delta = committed_size - committed_size_;
+  size_t num_additional_chunks =
+      (delta + kCommitChunkSize - 1) / kCommitChunkSize;
+  PERFETTO_DCHECK(num_additional_chunks * kCommitChunkSize >= delta);
+  // Don't commit more than the total size.
+  size_t commit_size = std::min(num_additional_chunks * kCommitChunkSize,
+                                size_ - committed_size_);
+  void* res = VirtualAlloc(p_ + committed_size_, commit_size, MEM_COMMIT,
+                           PAGE_READWRITE);
+  PERFETTO_CHECK(res);
+  ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_,
+                       committed_size_ + commit_size)
+  committed_size_ += commit_size;
+#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // mmap commits automatically as needed, so we only track here for ASAN.
+  committed_size = std::max(committed_size_, committed_size);
+  ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_, committed_size)
+  committed_size_ = committed_size;
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+}
+#endif  // TRACK_COMMITTED_SIZE()
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/periodic_task.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/periodic_task.h
+// gen_amalgamated begin header: include/perfetto/ext/base/thread_checker.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <pthread.h>
+#endif
+#include <atomic>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using ThreadID = unsigned long;
+#else
+using ThreadID = pthread_t;
+#endif
+
+class PERFETTO_EXPORT_COMPONENT ThreadChecker {
+ public:
+  ThreadChecker();
+  ~ThreadChecker();
+  ThreadChecker(const ThreadChecker&);
+  ThreadChecker& operator=(const ThreadChecker&);
+  bool CalledOnValidThread() const PERFETTO_WARN_UNUSED_RESULT;
+  void DetachFromThread();
+
+ private:
+  mutable std::atomic<ThreadID> thread_id_;
+};
+
+#if PERFETTO_DCHECK_IS_ON() && !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+// TODO(primiano) Use Chromium's thread checker in Chromium.
+#define PERFETTO_THREAD_CHECKER(name) base::ThreadChecker name;
+#define PERFETTO_DCHECK_THREAD(name) \
+  PERFETTO_DCHECK((name).CalledOnValidThread())
+#define PERFETTO_DETACH_FROM_THREAD(name) (name).DetachFromThread()
+#else
+#define PERFETTO_THREAD_CHECKER(name)
+#define PERFETTO_DCHECK_THREAD(name)
+#define PERFETTO_DETACH_FROM_THREAD(name)
+#endif  // PERFETTO_DCHECK_IS_ON()
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
+// gen_amalgamated begin header: include/perfetto/ext/base/weak_ptr.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
+#define INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+
+#include <memory>
+
+namespace perfetto {
+namespace base {
+
+// A simple WeakPtr for single-threaded cases.
+// Generally keep the WeakPtrFactory as last fields in classes: it makes the
+// WeakPtr(s) invalidate as first thing in the class dtor.
+// Usage:
+// class MyClass {
+//  MyClass() : weak_factory_(this) {}
+//  WeakPtr<MyClass> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
+//
+// private:
+//  WeakPtrFactory<MyClass> weak_factory_;
+// }
+//
+// int main() {
+//  std::unique_ptr<MyClass> foo(new MyClass);
+//  auto wptr = foo.GetWeakPtr();
+//  ASSERT_TRUE(wptr);
+//  ASSERT_EQ(foo.get(), wptr->get());
+//  foo.reset();
+//  ASSERT_FALSE(wptr);
+//  ASSERT_EQ(nullptr, wptr->get());
+// }
+
+template <typename T>
+class WeakPtrFactory;  // Forward declaration, defined below.
+
+template <typename T>
+class WeakPtr {
+ public:
+  WeakPtr() {}
+  WeakPtr(const WeakPtr&) = default;
+  WeakPtr& operator=(const WeakPtr&) = default;
+  WeakPtr(WeakPtr&&) = default;
+  WeakPtr& operator=(WeakPtr&&) = default;
+
+  T* get() const {
+    PERFETTO_DCHECK_THREAD(thread_checker);
+    return handle_ ? *handle_.get() : nullptr;
+  }
+  T* operator->() const { return get(); }
+  T& operator*() const { return *get(); }
+
+  explicit operator bool() const { return !!get(); }
+
+ private:
+  friend class WeakPtrFactory<T>;
+  explicit WeakPtr(const std::shared_ptr<T*>& handle) : handle_(handle) {}
+
+  std::shared_ptr<T*> handle_;
+  PERFETTO_THREAD_CHECKER(thread_checker)
+};
+
+template <typename T>
+class WeakPtrFactory {
+ public:
+  explicit WeakPtrFactory(T* owner)
+      : weak_ptr_(std::shared_ptr<T*>(new T* {owner})) {
+    PERFETTO_DCHECK_THREAD(thread_checker);
+  }
+
+  ~WeakPtrFactory() {
+    PERFETTO_DCHECK_THREAD(thread_checker);
+    *(weak_ptr_.handle_.get()) = nullptr;
+  }
+
+  // Can be safely called on any thread, since it simply copies |weak_ptr_|.
+  // Note that any accesses to the returned pointer need to be made on the
+  // thread that created/reset the factory.
+  WeakPtr<T> GetWeakPtr() const { return weak_ptr_; }
+
+  // Reset the factory to a new owner & thread. May only be called before any
+  // weak pointers were passed out. Future weak pointers will be valid on the
+  // calling thread.
+  void Reset(T* owner) {
+    // Reset thread checker to current thread.
+    PERFETTO_DETACH_FROM_THREAD(thread_checker);
+    PERFETTO_DCHECK_THREAD(thread_checker);
+
+    // We should not have passed out any weak pointers yet at this point.
+    PERFETTO_DCHECK(weak_ptr_.handle_.use_count() == 1);
+
+    weak_ptr_ = WeakPtr<T>(std::shared_ptr<T*>(new T* {owner}));
+  }
+
+ private:
+  WeakPtrFactory(const WeakPtrFactory&) = delete;
+  WeakPtrFactory& operator=(const WeakPtrFactory&) = delete;
+
+  WeakPtr<T> weak_ptr_;
+  PERFETTO_THREAD_CHECKER(thread_checker)
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
+#define INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+
+namespace perfetto {
+namespace base {
+
+class TaskRunner;
+
+// A periodic task utility class. It wraps the logic necessary to do periodic
+// tasks using a TaskRunner, taking care of subtleties like ensuring that
+// outstanding tasks are cancelled after reset/dtor.
+// Tasks are aligned on wall time (unless they are |one_shot|). This is to
+// ensure that when using multiple periodic tasks, they happen at the same time,
+// minimizing context switches.
+// On Linux/Android it also supports suspend-aware mode (via timerfd). On other
+// operating systems it falls back to PostDelayedTask, which is not
+// suspend-aware.
+// TODO(primiano): this should probably become a periodic timer scheduler, so we
+// can use one FD for everything rather than one FD per task. For now we take
+// the hit of a FD-per-task to keep this low-risk.
+// TODO(primiano): consider renaming this class to TimerTask. When |one_shot|
+// is set, the "Periodic" part of the class name becomes a lie.
+class PeriodicTask {
+ public:
+  explicit PeriodicTask(base::TaskRunner*);
+  ~PeriodicTask();  // Calls Reset().
+
+  struct Args {
+    uint32_t period_ms = 0;
+    std::function<void()> task = nullptr;
+    bool start_first_task_immediately = false;
+    bool use_suspend_aware_timer = false;
+    bool one_shot = false;
+  };
+
+  void Start(Args);
+
+  // Safe to be called multiple times, even without calling Start():
+  void Reset();
+
+  // No copy or move. WeakPtr-wrapped pointers to |this| are posted on the
+  // task runner, this class is not easily movable.
+  PeriodicTask(const PeriodicTask&) = delete;
+  PeriodicTask& operator=(const PeriodicTask&) = delete;
+  PeriodicTask(PeriodicTask&&) = delete;
+  PeriodicTask& operator=(PeriodicTask&&) = delete;
+
+  base::PlatformHandle timer_fd_for_testing() { return *timer_fd_; }
+
+ private:
+  static void RunTaskAndPostNext(base::WeakPtr<PeriodicTask>,
+                                 uint32_t generation);
+  void PostNextTask();
+  void ResetTimerFd();
+
+  base::TaskRunner* const task_runner_;
+  Args args_;
+  uint32_t generation_ = 0;
+  base::ScopedPlatformHandle timer_fd_;
+
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+  base::WeakPtrFactory<PeriodicTask> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"
+
+#include <limits>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
+#include <sys/timerfd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+uint32_t GetNextDelayMs(const TimeMillis& now_ms,
+                        const PeriodicTask::Args& args) {
+  if (args.one_shot)
+    return args.period_ms;
+
+  return args.period_ms -
+         static_cast<uint32_t>(now_ms.count() % args.period_ms);
+}
+
+ScopedPlatformHandle CreateTimerFd(const PeriodicTask::Args& args) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
+  ScopedPlatformHandle tfd(
+      timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK));
+  uint32_t phase_ms = GetNextDelayMs(GetBootTimeMs(), args);
+
+  struct itimerspec its {};
+  // The "1 +" is to make sure that we never pass a zero it_value in the
+  // unlikely case of phase_ms being 0. That would cause the timer to be
+  // considered disarmed by timerfd_settime.
+  its.it_value.tv_sec = static_cast<time_t>(phase_ms / 1000u);
+  its.it_value.tv_nsec = 1 + static_cast<long>((phase_ms % 1000u) * 1000000u);
+  if (args.one_shot) {
+    its.it_interval.tv_sec = 0;
+    its.it_interval.tv_nsec = 0;
+  } else {
+    const uint32_t period_ms = args.period_ms;
+    its.it_interval.tv_sec = static_cast<time_t>(period_ms / 1000u);
+    its.it_interval.tv_nsec = static_cast<long>((period_ms % 1000u) * 1000000u);
+  }
+  if (timerfd_settime(*tfd, 0, &its, nullptr) < 0)
+    return ScopedPlatformHandle();
+  return tfd;
+#else
+  ignore_result(args);
+  return ScopedPlatformHandle();
+#endif
+}
+
+}  // namespace
+
+PeriodicTask::PeriodicTask(TaskRunner* task_runner)
+    : task_runner_(task_runner), weak_ptr_factory_(this) {}
+
+PeriodicTask::~PeriodicTask() {
+  Reset();
+}
+
+void PeriodicTask::Start(Args args) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  Reset();
+  if (args.period_ms == 0 || !args.task) {
+    PERFETTO_DCHECK(args.period_ms > 0);
+    PERFETTO_DCHECK(args.task);
+    return;
+  }
+  args_ = std::move(args);
+  if (args_.use_suspend_aware_timer) {
+    timer_fd_ = CreateTimerFd(args_);
+    if (timer_fd_) {
+      auto weak_this = weak_ptr_factory_.GetWeakPtr();
+      task_runner_->AddFileDescriptorWatch(
+          *timer_fd_,
+          std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_));
+    } else {
+      PERFETTO_DPLOG("timerfd not supported, falling back on PostDelayedTask");
+    }
+  }  // if (use_suspend_aware_timer).
+
+  if (!timer_fd_)
+    PostNextTask();
+
+  if (args_.start_first_task_immediately)
+    args_.task();
+}
+
+void PeriodicTask::PostNextTask() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(args_.period_ms > 0);
+  PERFETTO_DCHECK(!timer_fd_);
+  uint32_t delay_ms = GetNextDelayMs(GetWallTimeMs(), args_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_),
+      delay_ms);
+}
+
+// static
+// This function can be called in two ways (both from the TaskRunner):
+// 1. When using a timerfd, this task is registered as a FD watch.
+// 2. When using PostDelayedTask, this is the task posted on the TaskRunner.
+void PeriodicTask::RunTaskAndPostNext(WeakPtr<PeriodicTask> thiz,
+                                      uint32_t generation) {
+  if (!thiz || !thiz->args_.task || generation != thiz->generation_)
+    return;  // Destroyed or Reset() in the meanwhile.
+  PERFETTO_DCHECK_THREAD(thiz->thread_checker_);
+  if (thiz->timer_fd_) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    PERFETTO_FATAL("timerfd for periodic tasks unsupported on Windows");
+#else
+    // If we are using a timerfd there is no need to repeatedly call
+    // PostDelayedTask(). The kernel will wakeup the timer fd periodically. We
+    // just need to read() it.
+    uint64_t ignored = 0;
+    errno = 0;
+    auto rsize = Read(*thiz->timer_fd_, &ignored, sizeof(&ignored));
+    if (rsize != sizeof(uint64_t)) {
+      if (errno == EAGAIN)
+        return;  // A spurious wakeup. Rare, but can happen, just ignore.
+      PERFETTO_PLOG("read(timerfd) failed, falling back on PostDelayedTask");
+      thiz->ResetTimerFd();
+    }
+#endif
+  }
+
+  // Create a copy of the task to deal with either:
+  // 1. one_shot causing a Reset().
+  // 2. task() invoking internally Reset().
+  // That would cause a reset of the args_.task itself, which would invalidate
+  // the task bind state while we are invoking it.
+  auto task = thiz->args_.task;
+
+  // The repetition of the if() is to deal with the ResetTimerFd() case above.
+  if (thiz->args_.one_shot) {
+    thiz->Reset();
+  } else if (!thiz->timer_fd_) {
+    thiz->PostNextTask();
+  }
+
+  task();
+}
+
+void PeriodicTask::Reset() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  ++generation_;
+  args_ = Args();
+  PERFETTO_DCHECK(!args_.task);
+  ResetTimerFd();
+}
+
+void PeriodicTask::ResetTimerFd() {
+  if (!timer_fd_)
+    return;
+  task_runner_->RemoveFileDescriptorWatch(*timer_fd_);
+  timer_fd_.reset();
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/pipe.cc
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <fcntl.h>  // For O_BINARY (Windows) and F_SETxx (UNIX)
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <namedpipeapi.h>
+#else
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+Pipe::Pipe() = default;
+Pipe::Pipe(Pipe&&) noexcept = default;
+Pipe& Pipe::operator=(Pipe&&) = default;
+
+Pipe Pipe::Create(Flags flags) {
+  PlatformHandle fds[2];
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  PERFETTO_CHECK(::CreatePipe(&fds[0], &fds[1], /*lpPipeAttributes=*/nullptr,
+                              0 /*default size*/));
+#else
+  PERFETTO_CHECK(pipe(fds) == 0);
+  PERFETTO_CHECK(fcntl(fds[0], F_SETFD, FD_CLOEXEC) == 0);
+  PERFETTO_CHECK(fcntl(fds[1], F_SETFD, FD_CLOEXEC) == 0);
+#endif
+  Pipe p;
+  p.rd.reset(fds[0]);
+  p.wr.reset(fds[1]);
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if (flags == kBothNonBlock || flags == kRdNonBlock) {
+    int cur_flags = fcntl(*p.rd, F_GETFL, 0);
+    PERFETTO_CHECK(cur_flags >= 0);
+    PERFETTO_CHECK(fcntl(*p.rd, F_SETFL, cur_flags | O_NONBLOCK) == 0);
+  }
+
+  if (flags == kBothNonBlock || flags == kWrNonBlock) {
+    int cur_flags = fcntl(*p.wr, F_GETFL, 0);
+    PERFETTO_CHECK(cur_flags >= 0);
+    PERFETTO_CHECK(fcntl(*p.wr, F_SETFL, cur_flags | O_NONBLOCK) == 0);
+  }
+#else
+  PERFETTO_CHECK(flags == kBothBlock);
+#endif
+  return p;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/status.cc
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/status.h"
+
+#include <stdarg.h>
+#include <algorithm>
+
+namespace perfetto {
+namespace base {
+
+Status ErrStatus(const char* format, ...) {
+  char buffer[1024];
+  va_list ap;
+  va_start(ap, format);
+  vsnprintf(buffer, sizeof(buffer), format, ap);
+  va_end(ap);
+  Status status(buffer);
+  return status;
+}
+
+std::optional<std::string_view> Status::GetPayload(
+    std::string_view type_url) const {
+  if (ok()) {
+    return std::nullopt;
+  }
+  for (const auto& kv : payloads_) {
+    if (kv.type_url == type_url) {
+      return kv.payload;
+    }
+  }
+  return std::nullopt;
+}
+
+void Status::SetPayload(std::string_view type_url, std::string value) {
+  if (ok()) {
+    return;
+  }
+  for (auto& kv : payloads_) {
+    if (kv.type_url == type_url) {
+      kv.payload = value;
+      return;
+    }
+  }
+  payloads_.push_back(Payload{std::string(type_url), std::move(value)});
+}
+
+bool Status::ErasePayload(std::string_view type_url) {
+  if (ok()) {
+    return false;
+  }
+  auto it = std::remove_if(
+      payloads_.begin(), payloads_.end(),
+      [type_url](const Payload& p) { return p.type_url == type_url; });
+  bool erased = it != payloads_.end();
+  payloads_.erase(it, payloads_.end());
+  return erased;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/string_splitter.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/string_splitter.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
+
+#include <string>
+
+namespace perfetto {
+namespace base {
+
+// C++ version of strtok(). Splits a string without making copies or any heap
+// allocations. Destructs the original string passed in input.
+// Supports the special case of using \0 as a delimiter.
+// The token returned in output are valid as long as the input string is valid.
+class StringSplitter {
+ public:
+  // Whether an empty string (two delimiters side-to-side) is a valid token.
+  enum class EmptyTokenMode {
+    DISALLOW_EMPTY_TOKENS,
+    ALLOW_EMPTY_TOKENS,
+
+    DEFAULT = DISALLOW_EMPTY_TOKENS,
+  };
+
+  // Can take ownership of the string if passed via std::move(), e.g.:
+  // StringSplitter(std::move(str), '\n');
+  StringSplitter(std::string,
+                 char delimiter,
+                 EmptyTokenMode empty_token_mode = EmptyTokenMode::DEFAULT);
+
+  // Splits a C-string. The input string will be forcefully null-terminated (so
+  // str[size - 1] should be == '\0' or the last char will be truncated).
+  StringSplitter(char* str,
+                 size_t size,
+                 char delimiter,
+                 EmptyTokenMode empty_token_mode = EmptyTokenMode::DEFAULT);
+
+  // Splits the current token from an outer StringSplitter instance. This is to
+  // chain splitters as follows:
+  // for (base::StringSplitter lines(x, '\n'); ss.Next();)
+  //   for (base::StringSplitter words(&lines, ' '); words.Next();)
+  StringSplitter(StringSplitter*,
+                 char delimiter,
+                 EmptyTokenMode empty_token_mode = EmptyTokenMode::DEFAULT);
+
+  // Returns true if a token is found (in which case it will be stored in
+  // cur_token()), false if no more tokens are found.
+  bool Next();
+
+  // Returns the current token iff last call to Next() returned true. In this
+  // case it guarantees that the returned string is always null terminated.
+  // In all other cases (before the 1st call to Next() and after Next() returns
+  // false) returns nullptr.
+  char* cur_token() { return cur_; }
+
+  // Returns the length of the current token (excluding the null terminator).
+  size_t cur_token_size() const { return cur_size_; }
+
+ private:
+  StringSplitter(const StringSplitter&) = delete;
+  StringSplitter& operator=(const StringSplitter&) = delete;
+  void Initialize(char* str, size_t size);
+
+  std::string str_;
+  char* cur_;
+  size_t cur_size_;
+  char* next_;
+  char* end_;  // STL-style, points one past the last char.
+  const char delimiter_;
+  const EmptyTokenMode empty_token_mode_;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
+
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+StringSplitter::StringSplitter(std::string str,
+                               char delimiter,
+                               EmptyTokenMode empty_token_mode)
+    : str_(std::move(str)),
+      delimiter_(delimiter),
+      empty_token_mode_(empty_token_mode) {
+  // It's legal to access str[str.size()] in C++11 (it always returns \0),
+  // hence the +1 (which becomes just size() after the -1 in Initialize()).
+  Initialize(&str_[0], str_.size() + 1);
+}
+
+StringSplitter::StringSplitter(char* str,
+                               size_t size,
+                               char delimiter,
+                               EmptyTokenMode empty_token_mode)
+    : delimiter_(delimiter), empty_token_mode_(empty_token_mode) {
+  Initialize(str, size);
+}
+
+StringSplitter::StringSplitter(StringSplitter* outer,
+                               char delimiter,
+                               EmptyTokenMode empty_token_mode)
+    : delimiter_(delimiter), empty_token_mode_(empty_token_mode) {
+  Initialize(outer->cur_token(), outer->cur_token_size() + 1);
+}
+
+void StringSplitter::Initialize(char* str, size_t size) {
+  PERFETTO_DCHECK(!size || str);
+  next_ = str;
+  end_ = str + size;
+  cur_ = nullptr;
+  cur_size_ = 0;
+  if (size)
+    next_[size - 1] = '\0';
+}
+
+bool StringSplitter::Next() {
+  for (; next_ < end_; next_++) {
+    if (*next_ == delimiter_ &&
+        empty_token_mode_ == EmptyTokenMode::DISALLOW_EMPTY_TOKENS) {
+      // If empty tokens are disallowed, find fist non-delimiter character.
+      continue;
+    }
+    cur_ = next_;
+    for (;; next_++) {
+      if (*next_ == delimiter_) {
+        cur_size_ = static_cast<size_t>(next_ - cur_);
+        *(next_++) = '\0';
+        break;
+      }
+      if (*next_ == '\0') {
+        cur_size_ = static_cast<size_t>(next_ - cur_);
+        next_ = end_;
+        break;
+      }
+    }
+    if (*cur_ || empty_token_mode_ == EmptyTokenMode::ALLOW_EMPTY_TOKENS)
+      return true;
+    break;
+  }
+  cur_ = nullptr;
+  cur_size_ = 0;
+  return false;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/string_utils.cc
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+#include <locale.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <algorithm>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <xlocale.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#endif
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace base {
+
+// Locale-independant as possible version of strtod.
+double StrToD(const char* nptr, char** endptr) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  static auto c_locale = newlocale(LC_ALL, "C", nullptr);
+  return strtod_l(nptr, endptr, c_locale);
+#else
+  return strtod(nptr, endptr);
+#endif
+}
+
+bool StartsWith(const std::string& str, const std::string& prefix) {
+  return str.compare(0, prefix.length(), prefix) == 0;
+}
+
+bool StartsWithAny(const std::string& str,
+                   const std::vector<std::string>& prefixes) {
+  return std::any_of(
+      prefixes.begin(), prefixes.end(),
+      [&str](const std::string& prefix) { return StartsWith(str, prefix); });
+}
+
+bool EndsWith(const std::string& str, const std::string& suffix) {
+  if (suffix.size() > str.size())
+    return false;
+  return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+bool Contains(const std::string& haystack, const std::string& needle) {
+  return haystack.find(needle) != std::string::npos;
+}
+
+bool Contains(const std::string& haystack, const char needle) {
+  return haystack.find(needle) != std::string::npos;
+}
+
+size_t Find(const StringView& needle, const StringView& haystack) {
+  if (needle.empty())
+    return 0;
+  if (needle.size() > haystack.size())
+    return std::string::npos;
+  for (size_t i = 0; i < haystack.size() - (needle.size() - 1); ++i) {
+    if (strncmp(haystack.data() + i, needle.data(), needle.size()) == 0)
+      return i;
+  }
+  return std::string::npos;
+}
+
+bool CaseInsensitiveEqual(const std::string& first, const std::string& second) {
+  return first.size() == second.size() &&
+         std::equal(
+             first.begin(), first.end(), second.begin(),
+             [](char a, char b) { return Lowercase(a) == Lowercase(b); });
+}
+
+std::string Join(const std::vector<std::string>& parts,
+                 const std::string& delim) {
+  std::string acc;
+  for (size_t i = 0; i < parts.size(); ++i) {
+    acc += parts[i];
+    if (i + 1 != parts.size()) {
+      acc += delim;
+    }
+  }
+  return acc;
+}
+
+std::vector<std::string> SplitString(const std::string& text,
+                                     const std::string& delimiter) {
+  PERFETTO_CHECK(!delimiter.empty());
+
+  std::vector<std::string> output;
+  size_t start = 0;
+  size_t next;
+  for (;;) {
+    next = std::min(text.find(delimiter, start), text.size());
+    if (next > start)
+      output.emplace_back(&text[start], next - start);
+    start = next + delimiter.size();
+    if (start >= text.size())
+      break;
+  }
+  return output;
+}
+
+std::string TrimWhitespace(const std::string& str) {
+  std::string whitespaces = "\t\n ";
+
+  size_t front_idx = str.find_first_not_of(whitespaces);
+  std::string front_trimmed =
+      front_idx == std::string::npos ? "" : str.substr(front_idx);
+
+  size_t end_idx = front_trimmed.find_last_not_of(whitespaces);
+  return end_idx == std::string::npos ? ""
+                                      : front_trimmed.substr(0, end_idx + 1);
+}
+
+std::string StripPrefix(const std::string& str, const std::string& prefix) {
+  return StartsWith(str, prefix) ? str.substr(prefix.size()) : str;
+}
+
+std::string StripSuffix(const std::string& str, const std::string& suffix) {
+  return EndsWith(str, suffix) ? str.substr(0, str.size() - suffix.size())
+                               : str;
+}
+
+std::string ToUpper(const std::string& str) {
+  // Don't use toupper(), it depends on the locale.
+  std::string res(str);
+  auto end = res.end();
+  for (auto c = res.begin(); c != end; ++c)
+    *c = Uppercase(*c);
+  return res;
+}
+
+std::string ToLower(const std::string& str) {
+  // Don't use tolower(), it depends on the locale.
+  std::string res(str);
+  auto end = res.end();
+  for (auto c = res.begin(); c != end; ++c)
+    *c = Lowercase(*c);
+  return res;
+}
+
+std::string ToHex(const char* data, size_t size) {
+  std::string hex(2 * size + 1, 'x');
+  for (size_t i = 0; i < size; ++i) {
+    // snprintf prints 3 characters, the two hex digits and a null byte. As we
+    // write left to right, we keep overwriting the nullbytes, except for the
+    // last call to snprintf.
+    snprintf(&(hex[2 * i]), 3, "%02hhx", data[i]);
+  }
+  // Remove the trailing nullbyte produced by the last snprintf.
+  hex.resize(2 * size);
+  return hex;
+}
+
+std::string IntToHexString(uint32_t number) {
+  size_t max_size = 11;  // Max uint32 is 0xFFFFFFFF + 1 for null byte.
+  std::string buf;
+  buf.resize(max_size);
+  size_t final_len = SprintfTrunc(&buf[0], max_size, "0x%02x", number);
+  buf.resize(static_cast<size_t>(final_len));  // Cuts off the final null byte.
+  return buf;
+}
+
+std::string Uint64ToHexString(uint64_t number) {
+  return "0x" + Uint64ToHexStringNoPrefix(number);
+}
+
+std::string Uint64ToHexStringNoPrefix(uint64_t number) {
+  size_t max_size = 17;  // Max uint64 is FFFFFFFFFFFFFFFF + 1 for null byte.
+  std::string buf;
+  buf.resize(max_size);
+  size_t final_len = SprintfTrunc(&buf[0], max_size, "%" PRIx64 "", number);
+  buf.resize(static_cast<size_t>(final_len));  // Cuts off the final null byte.
+  return buf;
+}
+
+std::string StripChars(const std::string& str,
+                       const std::string& chars,
+                       char replacement) {
+  std::string res(str);
+  const char* start = res.c_str();
+  const char* remove = chars.c_str();
+  for (const char* c = strpbrk(start, remove); c; c = strpbrk(c + 1, remove))
+    res[static_cast<uintptr_t>(c - start)] = replacement;
+  return res;
+}
+
+std::string ReplaceAll(std::string str,
+                       const std::string& to_replace,
+                       const std::string& replacement) {
+  PERFETTO_CHECK(!to_replace.empty());
+  size_t pos = 0;
+  while ((pos = str.find(to_replace, pos)) != std::string::npos) {
+    str.replace(pos, to_replace.length(), replacement);
+    pos += replacement.length();
+  }
+  return str;
+}
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+bool WideToUTF8(const std::wstring& source, std::string& output) {
+  if (source.empty() ||
+      source.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
+    return false;
+  }
+  int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0],
+                                   static_cast<int>(source.size()), nullptr, 0,
+                                   nullptr, nullptr);
+  output.assign(static_cast<size_t>(size), '\0');
+  if (::WideCharToMultiByte(CP_UTF8, 0, &source[0],
+                            static_cast<int>(source.size()), &output[0], size,
+                            nullptr, nullptr) != size) {
+    return false;
+  }
+  return true;
+}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+bool UTF8ToWide(const std::string& source, std::wstring& output) {
+  if (source.empty() ||
+      source.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
+    return false;
+  }
+  int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0],
+                                   static_cast<int>(source.size()), nullptr, 0);
+  output.assign(static_cast<size_t>(size), L'\0');
+  if (::MultiByteToWideChar(CP_UTF8, 0, &source[0],
+                            static_cast<int>(source.size()), &output[0],
+                            size) != size) {
+    return false;
+  }
+  return true;
+}
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...) {
+  if (PERFETTO_UNLIKELY(dst_size) == 0)
+    return 0;
+
+  va_list args;
+  va_start(args, fmt);
+  int src_size = vsnprintf(dst, dst_size, fmt, args);
+  va_end(args);
+
+  if (PERFETTO_UNLIKELY(src_size) <= 0) {
+    dst[0] = '\0';
+    return 0;
+  }
+
+  size_t res;
+  if (PERFETTO_LIKELY(src_size < static_cast<int>(dst_size))) {
+    // Most common case.
+    res = static_cast<size_t>(src_size);
+  } else {
+    // Truncation case.
+    res = dst_size - 1;
+  }
+
+  PERFETTO_DCHECK(res < dst_size);
+  PERFETTO_DCHECK(dst[res] == '\0');
+  return res;
+}
+
+std::optional<LineWithOffset> FindLineWithOffset(base::StringView str,
+                                                 uint32_t offset) {
+  static constexpr char kNewLine = '\n';
+  uint32_t line_offset = 0;
+  uint32_t line_count = 1;
+  for (uint32_t i = 0; i < str.size(); ++i) {
+    if (str.at(i) == kNewLine) {
+      line_offset = i + 1;
+      line_count++;
+      continue;
+    }
+    if (i == offset) {
+      size_t end_offset = str.find(kNewLine, i);
+      if (end_offset == std::string::npos) {
+        end_offset = str.size();
+      }
+      base::StringView line = str.substr(line_offset, end_offset - line_offset);
+      return LineWithOffset{line, offset - line_offset, line_count};
+    }
+  }
+  return std::nullopt;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/string_view.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+
+namespace perfetto {
+namespace base {
+
+// Without ignoring this warning we get the message:
+//   error: out-of-line definition of constexpr static data member is redundant
+//   in C++17 and is deprecated
+// when using clang-cl in Windows.
+#if defined(__GNUC__)  // GCC & clang
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+#endif  // __GNUC__
+
+// static
+constexpr size_t StringView::npos;
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/temp_file.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/temp_file.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
+#define INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+namespace perfetto {
+namespace base {
+
+std::string GetSysTempDir();
+
+class TempFile {
+ public:
+  static TempFile CreateUnlinked();
+  static TempFile Create();
+
+  TempFile(TempFile&&) noexcept;
+  TempFile& operator=(TempFile&&);
+  ~TempFile();
+
+  const std::string& path() const { return path_; }
+  int fd() const { return *fd_; }
+  int operator*() const { return *fd_; }
+
+  // Unlinks the file from the filesystem but keeps the fd() open.
+  // It is safe to call this multiple times.
+  void Unlink();
+
+  // Releases the underlying file descriptor. Will unlink the file from the
+  // filesystem if it was created via CreateUnlinked().
+  ScopedFile ReleaseFD();
+
+ private:
+  TempFile();
+  TempFile(const TempFile&) = delete;
+  TempFile& operator=(const TempFile&) = delete;
+
+  ScopedFile fd_;
+  std::string path_;
+};
+
+class TempDir {
+ public:
+  static TempDir Create();
+
+  TempDir(TempDir&&) noexcept;
+  TempDir& operator=(TempDir&&);
+  ~TempDir();
+
+  const std::string& path() const { return path_; }
+
+ private:
+  TempDir();
+  TempDir(const TempDir&) = delete;
+  TempDir& operator=(const TempDir&) = delete;
+
+  std::string path_;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <direct.h>
+#include <fileapi.h>
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+namespace {
+std::string GetTempFilePathWin() {
+  std::string tmplt = GetSysTempDir() + "\\perfetto-XXXXXX";
+  StackString<255> name("%s\\perfetto-XXXXXX", GetSysTempDir().c_str());
+  PERFETTO_CHECK(_mktemp_s(name.mutable_data(), name.len() + 1) == 0);
+  return name.ToStdString();
+}
+}  // namespace
+#endif
+
+std::string GetSysTempDir() {
+  const char* tmpdir = nullptr;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if ((tmpdir = getenv("TMP")))
+    return tmpdir;
+  if ((tmpdir = getenv("TEMP")))
+    return tmpdir;
+  return "C:\\TEMP";
+#else
+  if ((tmpdir = getenv("TMPDIR")))
+    return base::StripSuffix(tmpdir, "/");
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  return "/data/local/tmp";
+#else
+  return "/tmp";
+#endif  // !OS_ANDROID
+#endif  // !OS_WIN
+}
+
+// static
+TempFile TempFile::Create() {
+  TempFile temp_file;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  temp_file.path_ = GetTempFilePathWin();
+  // Several tests want to read-back the temp file while still open. On Windows,
+  // that requires FILE_SHARE_READ. FILE_SHARE_READ is NOT settable when using
+  // the POSIX-compat equivalent function _open(). Hence the CreateFileA +
+  // _open_osfhandle dance here.
+  HANDLE h =
+      ::CreateFileA(temp_file.path_.c_str(), GENERIC_READ | GENERIC_WRITE,
+                    FILE_SHARE_DELETE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
+                    FILE_ATTRIBUTE_TEMPORARY, nullptr);
+  PERFETTO_CHECK(PlatformHandleChecker::IsValid(h));
+  // According to MSDN, when using _open_osfhandle the caller must not call
+  // CloseHandle(). Ownership is moved to the file descriptor, which then needs
+  // to be closed with just with _close().
+  temp_file.fd_.reset(_open_osfhandle(reinterpret_cast<intptr_t>(h), 0));
+#else
+  temp_file.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
+  temp_file.fd_.reset(mkstemp(&temp_file.path_[0]));
+#endif
+  if (PERFETTO_UNLIKELY(!temp_file.fd_)) {
+    PERFETTO_FATAL("Could not create temp file %s", temp_file.path_.c_str());
+  }
+  return temp_file;
+}
+
+// static
+TempFile TempFile::CreateUnlinked() {
+  TempFile temp_file = TempFile::Create();
+  temp_file.Unlink();
+  return temp_file;
+}
+
+TempFile::TempFile() = default;
+
+TempFile::~TempFile() {
+  Unlink();
+}
+
+ScopedFile TempFile::ReleaseFD() {
+  Unlink();
+  return std::move(fd_);
+}
+
+void TempFile::Unlink() {
+  if (path_.empty())
+    return;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // If the FD is still open DeleteFile will mark the file as pending deletion
+  // and delete it only when the process exists.
+  PERFETTO_CHECK(DeleteFileA(path_.c_str()));
+#else
+  PERFETTO_CHECK(unlink(path_.c_str()) == 0);
+#endif
+  path_.clear();
+}
+
+TempFile::TempFile(TempFile&&) noexcept = default;
+TempFile& TempFile::operator=(TempFile&&) = default;
+
+// static
+TempDir TempDir::Create() {
+  TempDir temp_dir;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  temp_dir.path_ = GetTempFilePathWin();
+  PERFETTO_CHECK(_mkdir(temp_dir.path_.c_str()) == 0);
+#else
+  temp_dir.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
+  PERFETTO_CHECK(mkdtemp(&temp_dir.path_[0]));
+#endif
+  return temp_dir;
+}
+
+TempDir::TempDir() = default;
+TempDir::TempDir(TempDir&&) noexcept = default;
+TempDir& TempDir::operator=(TempDir&&) = default;
+
+TempDir::~TempDir() {
+  if (path_.empty())
+    return;  // For objects that get std::move()d.
+  PERFETTO_CHECK(Rmdir(path_));
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/thread_checker.cc
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+namespace {
+constexpr ThreadID kDetached{};
+
+ThreadID CurrentThreadId() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return ::GetCurrentThreadId();
+#else
+  return pthread_self();
+#endif
+}
+}  // namespace
+
+ThreadChecker::ThreadChecker() {
+  thread_id_.store(CurrentThreadId());
+}
+
+ThreadChecker::~ThreadChecker() = default;
+
+ThreadChecker::ThreadChecker(const ThreadChecker& other) {
+  thread_id_ = other.thread_id_.load();
+}
+
+ThreadChecker& ThreadChecker::operator=(const ThreadChecker& other) {
+  thread_id_ = other.thread_id_.load();
+  return *this;
+}
+
+bool ThreadChecker::CalledOnValidThread() const {
+  auto self = CurrentThreadId();
+
+  // Will re-attach if previously detached using DetachFromThread().
+  auto prev_value = kDetached;
+  if (thread_id_.compare_exchange_strong(prev_value, self))
+    return true;
+  return prev_value == self;
+}
+
+void ThreadChecker::DetachFromThread() {
+  thread_id_.store(kDetached);
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/thread_utils.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/thread_utils.h
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <pthread.h>
+#include <string.h>
+#include <algorithm>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/prctl.h>
+#endif
+
+// Internal implementation utils that aren't as widely useful/supported as
+// base/thread_utils.h.
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+// Sets the "comm" of the calling thread to the first 15 chars of the given
+// string.
+inline bool MaybeSetThreadName(const std::string& name) {
+  char buf[16] = {};
+  StringCopy(buf, name.c_str(), sizeof(buf));
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  return pthread_setname_np(buf) == 0;
+#else
+  return pthread_setname_np(pthread_self(), buf) == 0;
+#endif
+}
+
+inline bool GetThreadName(std::string& out_result) {
+  char buf[16] = {};
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  if (prctl(PR_GET_NAME, buf) != 0)
+    return false;
+#else
+  if (pthread_getname_np(pthread_self(), buf, sizeof(buf)) != 0)
+    return false;
+#endif
+  out_result = std::string(buf);
+  return true;
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+PERFETTO_EXPORT_COMPONENT bool MaybeSetThreadName(const std::string& name);
+PERFETTO_EXPORT_COMPONENT bool GetThreadName(std::string& out_result);
+
+#else
+inline bool MaybeSetThreadName(const std::string&) {
+  return false;
+}
+inline bool GetThreadName(std::string&) {
+  return false;
+}
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
+/*
+ * Copyright (C) 2022 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <zircon/process.h>
+#include <zircon/syscalls.h>
+#include <zircon/types.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+static PlatformThreadId ResolveThreadId() {
+  zx_info_handle_basic_t basic;
+  return (zx_object_get_info(zx_thread_self(), ZX_INFO_HANDLE_BASIC, &basic,
+                             sizeof(basic), nullptr, nullptr) == ZX_OK)
+             ? basic.koid
+             : ZX_KOID_INVALID;
+}
+PlatformThreadId GetThreadId() {
+  thread_local static PlatformThreadId thread_id = ResolveThreadId();
+  return thread_id;
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+// The SetThreadDescription API was brought in version 1607 of Windows 10.
+typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread,
+                                              PCWSTR lpThreadDescription);
+
+// The SetThreadDescription API was brought in version 1607 of Windows 10.
+typedef HRESULT(WINAPI* GetThreadDescription)(HANDLE hThread,
+                                              PWSTR* ppszThreadDescription);
+
+bool MaybeSetThreadName(const std::string& name) {
+  // The SetThreadDescription API works even if no debugger is attached.
+  static auto set_thread_description_func =
+      reinterpret_cast<SetThreadDescription>(
+          reinterpret_cast<void*>(::GetProcAddress(
+              ::GetModuleHandleA("Kernel32.dll"), "SetThreadDescription")));
+  if (!set_thread_description_func) {
+    return false;
+  }
+  std::wstring wide_thread_name;
+  if (!UTF8ToWide(name, wide_thread_name)) {
+    return false;
+  }
+  HRESULT result = set_thread_description_func(::GetCurrentThread(),
+                                               wide_thread_name.c_str());
+  return !FAILED(result);
+}
+
+bool GetThreadName(std::string& out_result) {
+  static auto get_thread_description_func =
+      reinterpret_cast<GetThreadDescription>(
+          reinterpret_cast<void*>(::GetProcAddress(
+              ::GetModuleHandleA("Kernel32.dll"), "GetThreadDescription")));
+  if (!get_thread_description_func) {
+    return false;
+  }
+  wchar_t* wide_thread_name;
+  HRESULT result =
+      get_thread_description_func(::GetCurrentThread(), &wide_thread_name);
+  if (SUCCEEDED(result)) {
+    bool success = WideToUTF8(std::wstring(wide_thread_name), out_result);
+    LocalFree(wide_thread_name);
+    return success;
+  }
+  return false;
+}
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/time.cc
+/*
+ * Copyright (C) 2018 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 <atomic>
+
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#else
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#if !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+namespace {
+
+// Returns the current value of the performance counter.
+int64_t QPCNowRaw() {
+  LARGE_INTEGER perf_counter_now = {};
+  // According to the MSDN documentation for QueryPerformanceCounter(), this
+  // will never fail on systems that run XP or later.
+  // https://msdn.microsoft.com/library/windows/desktop/ms644904.aspx
+  ::QueryPerformanceCounter(&perf_counter_now);
+  return perf_counter_now.QuadPart;
+}
+
+double TSCTicksPerSecond() {
+  // The value returned by QueryPerformanceFrequency() cannot be used as the TSC
+  // frequency, because there is no guarantee that the TSC frequency is equal to
+  // the performance counter frequency.
+  // The TSC frequency is cached in a static variable because it takes some time
+  // to compute it.
+  static std::atomic<double> tsc_ticks_per_second = 0;
+  double value = tsc_ticks_per_second.load(std::memory_order_relaxed);
+  if (value != 0)
+    return value;
+
+  // Increase the thread priority to reduces the chances of having a context
+  // switch during a reading of the TSC and the performance counter.
+  const int previous_priority = ::GetThreadPriority(::GetCurrentThread());
+  ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+
+  // The first time that this function is called, make an initial reading of the
+  // TSC and the performance counter. Initialization of static variable is
+  // thread-safe. Threads can race initializing tsc_initial vs
+  // perf_counter_initial, although they should be storing very similar values.
+
+  static const uint64_t tsc_initial = __rdtsc();
+  static const int64_t perf_counter_initial = QPCNowRaw();
+
+  // Make a another reading of the TSC and the performance counter every time
+  // that this function is called.
+  const uint64_t tsc_now = __rdtsc();
+  const int64_t perf_counter_now = QPCNowRaw();
+
+  // Reset the thread priority.
+  ::SetThreadPriority(::GetCurrentThread(), previous_priority);
+
+  // Make sure that at least 50 ms elapsed between the 2 readings. The first
+  // time that this function is called, we don't expect this to be the case.
+  // Note: The longer the elapsed time between the 2 readings is, the more
+  //   accurate the computed TSC frequency will be. The 50 ms value was
+  //   chosen because local benchmarks show that it allows us to get a
+  //   stddev of less than 1 tick/us between multiple runs.
+  // Note: According to the MSDN documentation for QueryPerformanceFrequency(),
+  //   this will never fail on systems that run XP or later.
+  //   https://msdn.microsoft.com/library/windows/desktop/ms644905.aspx
+  LARGE_INTEGER perf_counter_frequency = {};
+  ::QueryPerformanceFrequency(&perf_counter_frequency);
+  PERFETTO_CHECK(perf_counter_now >= perf_counter_initial);
+  const int64_t perf_counter_ticks = perf_counter_now - perf_counter_initial;
+  const double elapsed_time_seconds =
+      static_cast<double>(perf_counter_ticks) /
+      static_cast<double>(perf_counter_frequency.QuadPart);
+
+  constexpr double kMinimumEvaluationPeriodSeconds = 0.05;
+  if (elapsed_time_seconds < kMinimumEvaluationPeriodSeconds)
+    return 0;
+
+  // Compute the frequency of the TSC.
+  PERFETTO_CHECK(tsc_now >= tsc_initial);
+  const uint64_t tsc_ticks = tsc_now - tsc_initial;
+  // Racing with another thread to write |tsc_ticks_per_second| is benign
+  // because both threads will write a valid result.
+  tsc_ticks_per_second.store(
+      static_cast<double>(tsc_ticks) / elapsed_time_seconds,
+      std::memory_order_relaxed);
+
+  return tsc_ticks_per_second.load(std::memory_order_relaxed);
+}
+
+}  // namespace
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+
+TimeNanos GetWallTimeNs() {
+  LARGE_INTEGER freq;
+  ::QueryPerformanceFrequency(&freq);
+  LARGE_INTEGER counter;
+  ::QueryPerformanceCounter(&counter);
+  double elapsed_nanoseconds = (1e9 * static_cast<double>(counter.QuadPart)) /
+                               static_cast<double>(freq.QuadPart);
+  return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds));
+}
+
+TimeNanos GetThreadCPUTimeNs() {
+#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+  // QueryThreadCycleTime versus TSCTicksPerSecond doesn't have much relation to
+  // actual elapsed time on Windows on Arm, because QueryThreadCycleTime is
+  // backed by the actual number of CPU cycles executed, rather than a
+  // constant-rate timer like Intel. To work around this, use GetThreadTimes
+  // (which isn't as accurate but is meaningful as a measure of elapsed
+  // per-thread time).
+  FILETIME dummy, kernel_ftime, user_ftime;
+  ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime,
+                   &user_ftime);
+  uint64_t kernel_time =
+      kernel_ftime.dwHighDateTime * 0x100000000 + kernel_ftime.dwLowDateTime;
+  uint64_t user_time =
+      user_ftime.dwHighDateTime * 0x100000000 + user_ftime.dwLowDateTime;
+
+  return TimeNanos((kernel_time + user_time) * 100);
+#else   // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+  // Get the number of TSC ticks used by the current thread.
+  ULONG64 thread_cycle_time = 0;
+  ::QueryThreadCycleTime(GetCurrentThread(), &thread_cycle_time);
+
+  // Get the frequency of the TSC.
+  const double tsc_ticks_per_second = TSCTicksPerSecond();
+  if (tsc_ticks_per_second == 0)
+    return TimeNanos();
+
+  // Return the CPU time of the current thread.
+  const double thread_time_seconds =
+      static_cast<double>(thread_cycle_time) / tsc_ticks_per_second;
+  constexpr int64_t kNanosecondsPerSecond = 1000 * 1000 * 1000;
+  return TimeNanos(
+      static_cast<int64_t>(thread_time_seconds * kNanosecondsPerSecond));
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+}
+
+void SleepMicroseconds(unsigned interval_us) {
+  // The Windows Sleep function takes a millisecond count. Round up so that
+  // short sleeps don't turn into a busy wait. Note that the sleep granularity
+  // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this
+  // being a short sleep.
+  ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000));
+}
+
+void InitializeTime() {
+#if !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+  // Make an early first call to TSCTicksPerSecond() to start 50 ms elapsed time
+  // (see comment in TSCTicksPerSecond()).
+  TSCTicksPerSecond();
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
+}
+
+#else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+void SleepMicroseconds(unsigned interval_us) {
+  ::usleep(static_cast<useconds_t>(interval_us));
+}
+
+void InitializeTime() {}
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+std::string GetTimeFmt(const std::string& fmt) {
+  time_t raw_time;
+  time(&raw_time);
+  struct tm* local_tm;
+  local_tm = localtime(&raw_time);
+  char buf[128];
+  PERFETTO_CHECK(strftime(buf, 80, fmt.c_str(), local_tm) > 0);
+  return buf;
+}
+
+std::optional<int32_t> GetTimezoneOffsetMins() {
+  std::string tz = GetTimeFmt("%z");
+  if (tz.size() != 5 || (tz[0] != '+' && tz[0] != '-'))
+    return std::nullopt;
+  char sign = '\0';
+  int32_t hh = 0;
+  int32_t mm = 0;
+  if (sscanf(tz.c_str(), "%c%2d%2d", &sign, &hh, &mm) != 3)
+    return std::nullopt;
+  return (hh * 60 + mm) * (sign == '-' ? -1 : 1);
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/utils.cc
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <limits.h>
+#include <stdlib.h>  // For _exit()
+#include <unistd.h>  // For getpagesize() and geteuid() & fork()
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <mach-o/dyld.h>
+#include <mach/vm_page_size.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <io.h>
+#include <malloc.h>  // For _aligned_malloc().
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <dlfcn.h>
+#include <malloc.h>
+
+#ifdef M_PURGE
+#define PERFETTO_M_PURGE M_PURGE
+#else
+// Only available in in-tree builds and on newer SDKs.
+#define PERFETTO_M_PURGE -101
+#endif  // M_PURGE
+
+#ifdef M_PURGE_ALL
+#define PERFETTO_M_PURGE_ALL M_PURGE_ALL
+#else
+// Only available in in-tree builds and on newer SDKs.
+#define PERFETTO_M_PURGE_ALL -104
+#endif  // M_PURGE
+
+namespace {
+extern "C" {
+using MalloptType = int (*)(int, int);
+}
+}  // namespace
+#endif  // OS_ANDROID
+
+namespace {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_X64_CPU_OPT)
+
+// Preserve the %rbx register via %rdi to work around a clang bug
+// https://bugs.llvm.org/show_bug.cgi?id=17907 (%rbx in an output constraint
+// is not considered a clobbered register).
+#define PERFETTO_GETCPUID(a, b, c, d, a_inp, c_inp) \
+  asm("mov %%rbx, %%rdi\n"                          \
+      "cpuid\n"                                     \
+      "xchg %%rdi, %%rbx\n"                         \
+      : "=a"(a), "=D"(b), "=c"(c), "=d"(d)          \
+      : "a"(a_inp), "2"(c_inp))
+
+uint32_t GetXCR0EAX() {
+  uint32_t eax = 0, edx = 0;
+  asm("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
+  return eax;
+}
+
+// If we are building with -msse4 check that the CPU actually supports it.
+// This file must be kept in sync with gn/standalone/BUILD.gn.
+void PERFETTO_EXPORT_COMPONENT __attribute__((constructor))
+CheckCpuOptimizations() {
+  uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+  PERFETTO_GETCPUID(eax, ebx, ecx, edx, 1, 0);
+
+  static constexpr uint64_t xcr0_xmm_mask = 0x2;
+  static constexpr uint64_t xcr0_ymm_mask = 0x4;
+  static constexpr uint64_t xcr0_avx_mask = xcr0_xmm_mask | xcr0_ymm_mask;
+
+  const bool have_popcnt = ecx & (1u << 23);
+  const bool have_sse4_2 = ecx & (1u << 20);
+  const bool have_avx =
+      // Does the OS save/restore XMM and YMM state?
+      (ecx & (1u << 27)) &&  // OS support XGETBV.
+      (ecx & (1u << 28)) &&  // AVX supported in hardware
+      ((GetXCR0EAX() & xcr0_avx_mask) == xcr0_avx_mask);
+
+  // Get level 7 features (eax = 7 and ecx= 0), to check for AVX2 support.
+  // (See Intel 64 and IA-32 Architectures Software Developer's Manual
+  //  Volume 2A: Instruction Set Reference, A-M CPUID).
+  PERFETTO_GETCPUID(eax, ebx, ecx, edx, 7, 0);
+  const bool have_avx2 = have_avx && ((ebx >> 5) & 0x1);
+  const bool have_bmi = (ebx >> 3) & 0x1;
+  const bool have_bmi2 = (ebx >> 8) & 0x1;
+
+  if (!have_sse4_2 || !have_popcnt || !have_avx2 || !have_bmi || !have_bmi2) {
+    fprintf(
+        stderr,
+        "This executable requires a x86_64 cpu that supports SSE4.2, BMI2 and "
+        "AVX2.\n"
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+        "On MacOS, this might be caused by running x86_64 binaries on arm64.\n"
+        "See https://github.com/google/perfetto/issues/294 for more.\n"
+#endif
+        "Rebuild with enable_perfetto_x64_cpu_opt=false.\n");
+    _exit(126);
+  }
+}
+#endif
+
+}  // namespace
+
+namespace perfetto {
+namespace base {
+
+namespace internal {
+
+std::atomic<uint32_t> g_cached_page_size{0};
+
+uint32_t GetSysPageSizeSlowpath() {
+  uint32_t page_size = 0;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  const int page_size_int = getpagesize();
+  // If sysconf() fails for obscure reasons (e.g. SELinux denial) assume the
+  // page size is 4KB. This is to avoid regressing subtle SDK usages, as old
+  // versions of this code had a static constant baked in.
+  page_size = static_cast<uint32_t>(page_size_int > 0 ? page_size_int : 4096);
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  page_size = static_cast<uint32_t>(vm_page_size);
+#else
+  page_size = 4096;
+#endif
+
+  PERFETTO_CHECK(page_size > 0 && page_size % 4096 == 0);
+
+  // Races here are fine because any thread will write the same value.
+  g_cached_page_size.store(page_size, std::memory_order_relaxed);
+  return page_size;
+}
+
+}  // namespace internal
+
+void MaybeReleaseAllocatorMemToOS() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // mallopt() on Android requires SDK level 26. Many targets and embedders
+  // still depend on a lower SDK level. Given mallopt() is a quite simple API,
+  // use reflection to do this rather than bumping the SDK level for all
+  // embedders. This keeps the behavior of standalone builds aligned with
+  // in-tree builds.
+  static MalloptType mallopt_fn =
+      reinterpret_cast<MalloptType>(dlsym(RTLD_DEFAULT, "mallopt"));
+  if (!mallopt_fn)
+    return;
+  if (mallopt_fn(PERFETTO_M_PURGE_ALL, 0) == 0) {
+    mallopt_fn(PERFETTO_M_PURGE, 0);
+  }
+#endif
+}
+
+uid_t GetCurrentUserId() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  return geteuid();
+#else
+  // TODO(primiano): On Windows we could hash the current user SID and derive a
+  // numeric user id [1]. It is not clear whether we need that. Right now that
+  // would not bring any benefit. Returning 0 unil we can prove we need it.
+  // [1]:https://android-review.googlesource.com/c/platform/external/perfetto/+/1513879/25/src/base/utils.cc
+  return 0;
+#endif
+}
+
+void SetEnv(const std::string& key, const std::string& value) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  PERFETTO_CHECK(::_putenv_s(key.c_str(), value.c_str()) == 0);
+#else
+  PERFETTO_CHECK(::setenv(key.c_str(), value.c_str(), /*overwrite=*/true) == 0);
+#endif
+}
+
+void UnsetEnv(const std::string& key) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  PERFETTO_CHECK(::_putenv_s(key.c_str(), "") == 0);
+#else
+  PERFETTO_CHECK(::unsetenv(key.c_str()) == 0);
+#endif
+}
+
+void Daemonize(std::function<int()> parent_cb) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  Pipe pipe = Pipe::Create(Pipe::kBothBlock);
+  pid_t pid;
+  switch (pid = fork()) {
+    case -1:
+      PERFETTO_FATAL("fork");
+    case 0: {
+      PERFETTO_CHECK(setsid() != -1);
+      base::ignore_result(chdir("/"));
+      base::ScopedFile null = base::OpenFile("/dev/null", O_RDONLY);
+      PERFETTO_CHECK(null);
+      PERFETTO_CHECK(dup2(*null, STDIN_FILENO) != -1);
+      PERFETTO_CHECK(dup2(*null, STDOUT_FILENO) != -1);
+      PERFETTO_CHECK(dup2(*null, STDERR_FILENO) != -1);
+      // Do not accidentally close stdin/stdout/stderr.
+      if (*null <= 2)
+        null.release();
+      WriteAll(*pipe.wr, "1", 1);
+      break;
+    }
+    default: {
+      // Wait for the child process to have reached the setsid() call. This is
+      // to avoid that 'adb shell perfetto -D' destroys the terminal (hence
+      // sending a SIGHUP to the child) before the child has detached from the
+      // terminal (see b/238644870).
+
+      // This is to unblock the read() below (with EOF, which will fail the
+      // CHECK) in the unlikely case of the child crashing before WriteAll("1").
+      pipe.wr.reset();
+      char one = '\0';
+      PERFETTO_CHECK(Read(*pipe.rd, &one, sizeof(one)) == 1 && one == '1');
+      printf("%d\n", pid);
+      int err = parent_cb();
+      exit(err);
+    }
+  }
+#else
+  // Avoid -Wunreachable warnings.
+  if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
+    PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
+  ignore_result(parent_cb);
+#endif  // OS_WIN
+}
+
+std::string GetCurExecutablePath() {
+  std::string self_path;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  char buf[PATH_MAX];
+  ssize_t size = readlink("/proc/self/exe", buf, sizeof(buf));
+  PERFETTO_CHECK(size != -1);
+  // readlink does not null terminate.
+  self_path = std::string(buf, static_cast<size_t>(size));
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  uint32_t size = 0;
+  PERFETTO_CHECK(_NSGetExecutablePath(nullptr, &size));
+  self_path.resize(size);
+  PERFETTO_CHECK(_NSGetExecutablePath(&self_path[0], &size) == 0);
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  char buf[MAX_PATH];
+  auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
+  self_path = std::string(buf, len);
+#else
+  PERFETTO_FATAL(
+      "GetCurExecutableDir() not implemented on the current platform");
+#endif
+  return self_path;
+}
+
+std::string GetCurExecutableDir() {
+  auto path = GetCurExecutablePath();
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Paths in Windows can have both kinds of slashes (mingw vs msvc).
+  path = path.substr(0, path.find_last_of('\\'));
+#endif
+  path = path.substr(0, path.find_last_of('/'));
+  return path;
+}
+
+void* AlignedAlloc(size_t alignment, size_t size) {
+  void* res = nullptr;
+  alignment = AlignUp<sizeof(void*)>(alignment);  // At least pointer size.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Window's _aligned_malloc() has a nearly identically signature to Unix's
+  // aligned_alloc() but its arguments are obviously swapped.
+  res = _aligned_malloc(size, alignment);
+#else
+  // aligned_alloc() has been introduced in Android only in API 28.
+  // Also NaCl and Fuchsia seems to have only posix_memalign().
+  ignore_result(posix_memalign(&res, alignment, size));
+#endif
+  PERFETTO_CHECK(res);
+  return res;
+}
+
+void AlignedFree(void* ptr) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  _aligned_free(ptr);  // MSDN says it is fine to pass nullptr.
+#else
+  free(ptr);
+#endif
+}
+
+std::string HexDump(const void* data_void, size_t len, size_t bytes_per_line) {
+  const char* data = reinterpret_cast<const char*>(data_void);
+  std::string res;
+  static const size_t kPadding = bytes_per_line * 3 + 12;
+  std::unique_ptr<char[]> line(new char[bytes_per_line * 4 + 128]);
+  for (size_t i = 0; i < len; i += bytes_per_line) {
+    char* wptr = line.get();
+    wptr += base::SprintfTrunc(wptr, 19, "%08zX: ", i);
+    for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
+      wptr += base::SprintfTrunc(wptr, 4, "%02X ",
+                                 static_cast<unsigned>(data[j]) & 0xFF);
+    }
+    for (size_t j = static_cast<size_t>(wptr - line.get()); j < kPadding; ++j)
+      *(wptr++) = ' ';
+    for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
+      char c = data[j];
+      *(wptr++) = (c >= 32 && c < 127) ? c : '.';
+    }
+    *(wptr++) = '\n';
+    *(wptr++) = '\0';
+    res.append(line.get());
+  }
+  return res;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/uuid.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/uuid.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_UUID_H_
+#define INCLUDE_PERFETTO_EXT_BASE_UUID_H_
+
+#include <string.h>
+#include <array>
+#include <cstdint>
+#include <optional>
+#include <string>
+
+namespace perfetto {
+namespace base {
+
+class Uuid {
+ public:
+  explicit Uuid(const std::string& s);
+  explicit Uuid(int64_t lsb, int64_t msb);
+  Uuid();
+
+  std::array<uint8_t, 16>* data() { return &data_; }
+  const std::array<uint8_t, 16>* data() const { return &data_; }
+
+  bool operator==(const Uuid& other) const { return data_ == other.data_; }
+
+  bool operator!=(const Uuid& other) const { return !(*this == other); }
+
+  explicit operator bool() const { return *this != Uuid(); }
+
+  int64_t msb() const {
+    int64_t result;
+    memcpy(&result, data_.data() + 8, 8);
+    return result;
+  }
+
+  int64_t lsb() const {
+    int64_t result;
+    memcpy(&result, data_.data(), 8);
+    return result;
+  }
+
+  void set_lsb_msb(int64_t lsb, int64_t msb) {
+    set_lsb(lsb);
+    set_msb(msb);
+  }
+  void set_msb(int64_t msb) { memcpy(data_.data() + 8, &msb, 8); }
+  void set_lsb(int64_t lsb) { memcpy(data_.data(), &lsb, 8); }
+
+  std::string ToString() const;
+  std::string ToPrettyString() const;
+
+ private:
+  std::array<uint8_t, 16> data_{};
+};
+
+Uuid Uuidv4();
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_UUID_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
+
+#include <random>
+
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+
+namespace perfetto {
+namespace base {
+namespace {
+
+constexpr char kHexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7',
+                            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+}  // namespace
+
+// A globally unique 128-bit number.
+// In the early days of perfetto we were (sorta) respecting rfc4122. Later we
+// started replacing the LSB of the UUID with the statsd subscription ID in
+// other parts of the codebase (see perfetto_cmd.cc) for the convenience of
+// trace lookups, so rfc4122 made no sense as it just reduced entropy.
+Uuid Uuidv4() {
+  // Mix different sources of entropy to reduce the chances of collisions.
+  // Only using boot time is not enough. Under the assumption that most traces
+  // are started around the same time at boot, within a 1s window, the birthday
+  // paradox gives a chance of 90% collisions with 70k traces over a 1e9 space
+  // (Number of ns in a 1s window).
+  // &kHexmap >> 14 is used to feed use indirectly ASLR as a source of entropy.
+  // We deliberately don't use /dev/urandom as that might block for
+  // unpredictable time if the system is idle.
+  // The UUID does NOT need to be cryptographically secure, but random enough
+  // to avoid collisions across a large number of devices.
+  static std::minstd_rand rng(
+      static_cast<uint32_t>(static_cast<uint64_t>(GetBootTimeNs().count()) ^
+                            static_cast<uint64_t>(GetWallTimeNs().count()) ^
+                            (reinterpret_cast<uintptr_t>(&kHexmap) >> 14)));
+  Uuid uuid;
+  auto& data = *uuid.data();
+
+  for (size_t i = 0; i < sizeof(data);) {
+    // Note: the 32-th bit of rng() is always 0 as minstd_rand operates modulo
+    // 2**31. Fill in blocks of 16b rather than 32b to not lose 1b of entropy.
+    const auto rnd_data = static_cast<uint16_t>(rng());
+    memcpy(&data[i], &rnd_data, sizeof(rnd_data));
+    i += sizeof(rnd_data);
+  }
+
+  return uuid;
+}
+
+Uuid::Uuid() {}
+
+Uuid::Uuid(const std::string& s) {
+  PERFETTO_CHECK(s.size() == data_.size());
+  memcpy(data_.data(), s.data(), s.size());
+}
+
+Uuid::Uuid(int64_t lsb, int64_t msb) {
+  set_lsb_msb(lsb, msb);
+}
+
+std::string Uuid::ToString() const {
+  return std::string(reinterpret_cast<const char*>(data_.data()), data_.size());
+}
+
+std::string Uuid::ToPrettyString() const {
+  std::string s(data_.size() * 2 + 4, '-');
+  // Format is 123e4567-e89b-12d3-a456-426655443322.
+  size_t j = 0;
+  for (size_t i = 0; i < data_.size(); ++i) {
+    if (i == 4 || i == 6 || i == 8 || i == 10)
+      j++;
+    s[2 * i + j] = kHexmap[(data_[data_.size() - i - 1] & 0xf0) >> 4];
+    s[2 * i + 1 + j] = kHexmap[(data_[data_.size() - i - 1] & 0x0f)];
+  }
+  return s;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/virtual_destructors.cc
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+
+// This translation unit contains the definitions for the destructor of pure
+// virtual interfaces for the current build target. The alternative would be
+// introducing a one-liner .cc file for each pure virtual interface, which is
+// overkill. This is for compliance with -Wweak-vtables.
+
+namespace perfetto {
+namespace base {
+
+TaskRunner::~TaskRunner() = default;
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/waitable_event.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/waitable_event.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
+#define INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
+
+#include <condition_variable>
+#include <mutex>
+
+namespace perfetto {
+namespace base {
+
+// A waitable event for cross-thread synchronization.
+// All methods on this class can be called from any thread.
+class WaitableEvent {
+ public:
+  WaitableEvent();
+  ~WaitableEvent();
+  WaitableEvent(const WaitableEvent&) = delete;
+  WaitableEvent operator=(const WaitableEvent&) = delete;
+
+  // Synchronously block until the event is notified.
+  void Wait();
+
+  // Signal the event, waking up blocked waiters.
+  void Notify();
+
+ private:
+  std::mutex mutex_;
+  std::condition_variable event_;
+  bool notified_ = false;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
+
+namespace perfetto {
+namespace base {
+
+WaitableEvent::WaitableEvent() = default;
+WaitableEvent::~WaitableEvent() = default;
+
+void WaitableEvent::Wait() {
+  std::unique_lock<std::mutex> lock(mutex_);
+  return event_.wait(lock, [this] { return notified_; });
+}
+
+void WaitableEvent::Notify() {
+  std::unique_lock<std::mutex> lock(mutex_);
+  notified_ = true;
+  event_.notify_all();
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/watchdog_posix.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/watchdog.h
+// gen_amalgamated begin header: include/perfetto/ext/base/watchdog_noop.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
+#define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
+
+#include <stdint.h>
+
+namespace perfetto {
+namespace base {
+
+enum class WatchdogCrashReason;  // Defined in watchdog.h.
+
+class Watchdog {
+ public:
+  class Timer {
+   public:
+    // Define an empty dtor to avoid "unused variable" errors on the call site.
+    Timer() {}
+    Timer(const Timer&) {}
+    ~Timer() {}
+  };
+  static Watchdog* GetInstance() {
+    static Watchdog* watchdog = new Watchdog();
+    return watchdog;
+  }
+  Timer CreateFatalTimer(uint32_t /*ms*/, WatchdogCrashReason) {
+    return Timer();
+  }
+  void Start() {}
+  void SetMemoryLimit(uint64_t /*bytes*/, uint32_t /*window_ms*/) {}
+  void SetCpuLimit(uint32_t /*percentage*/, uint32_t /*window_ms*/) {}
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
+#define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// The POSIX watchdog is only supported on Linux and Android in non-embedder
+// builds.
+#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
+// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_posix.h"
+#else
+// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_noop.h"
+#endif
+
+namespace perfetto {
+namespace base {
+
+// Used only to add more details to crash reporting.
+enum class WatchdogCrashReason {
+  kUnspecified = 0,
+  kCpuGuardrail = 1,
+  kMemGuardrail = 2,
+  kTaskRunnerHung = 3,
+  kTraceDidntStop = 4,
+};
+
+// Make the limits more relaxed on desktop, where multi-GB traces are likely.
+// Multi-GB traces can take bursts of cpu time to write into disk at the end of
+// the trace.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+constexpr uint32_t kWatchdogDefaultCpuLimit = 75;
+constexpr uint32_t kWatchdogDefaultCpuWindow = 5 * 60 * 1000;  // 5 minutes.
+#else
+constexpr uint32_t kWatchdogDefaultCpuLimit = 90;
+constexpr uint32_t kWatchdogDefaultCpuWindow = 10 * 60 * 1000;  // 10 minutes.
+#endif
+
+// The default memory margin we give to our processes. This is used as as a
+// constant to put on top of the trace buffers.
+constexpr uint64_t kWatchdogDefaultMemorySlack = 32 * 1024 * 1024;  // 32 MiB.
+constexpr uint32_t kWatchdogDefaultMemoryWindow = 30 * 1000;  // 30 seconds.
+
+inline void RunTaskWithWatchdogGuard(const std::function<void()>& task) {
+  // Maximum time a single task can take in a TaskRunner before the
+  // program suicides.
+  constexpr int64_t kWatchdogMillis = 30000;  // 30s
+
+  Watchdog::Timer handle = base::Watchdog::GetInstance()->CreateFatalTimer(
+      kWatchdogMillis, WatchdogCrashReason::kTaskRunnerHung);
+  task();
+
+  // Suppress unused variable warnings in the client library amalgamated build.
+  (void)kWatchdogDefaultCpuLimit;
+  (void)kWatchdogDefaultCpuWindow;
+  (void)kWatchdogDefaultMemorySlack;
+  (void)kWatchdogDefaultMemoryWindow;
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
+
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/syscall.h>
+#include <sys/timerfd.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <cinttypes>
+#include <fstream>
+#include <thread>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+constexpr uint32_t kDefaultPollingInterval = 30 * 1000;
+
+base::CrashKey g_crash_key_reason("wdog_reason");
+
+bool IsMultipleOf(uint32_t number, uint32_t divisor) {
+  return number >= divisor && number % divisor == 0;
+}
+
+double MeanForArray(const uint64_t array[], size_t size) {
+  uint64_t total = 0;
+  for (size_t i = 0; i < size; i++) {
+    total += array[i];
+  }
+  return static_cast<double>(total / size);
+}
+
+}  //  namespace
+
+bool ReadProcStat(int fd, ProcStat* out) {
+  char c[512];
+  size_t c_pos = 0;
+  while (c_pos < sizeof(c) - 1) {
+    ssize_t rd = PERFETTO_EINTR(read(fd, c + c_pos, sizeof(c) - c_pos));
+    if (rd < 0) {
+      PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
+      return false;
+    }
+    if (rd == 0)
+      break;
+    c_pos += static_cast<size_t>(rd);
+  }
+  PERFETTO_CHECK(c_pos < sizeof(c));
+  c[c_pos] = '\0';
+
+  if (sscanf(c,
+             "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu "
+             "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
+             &out->utime, &out->stime, &out->rss_pages) != 3) {
+    PERFETTO_ELOG("Invalid stat format: %s", c);
+    return false;
+  }
+  return true;
+}
+
+Watchdog::Watchdog(uint32_t polling_interval_ms)
+    : polling_interval_ms_(polling_interval_ms) {}
+
+Watchdog::~Watchdog() {
+  if (!thread_.joinable()) {
+    PERFETTO_DCHECK(!enabled_);
+    return;
+  }
+  PERFETTO_DCHECK(enabled_);
+  enabled_ = false;
+
+  // Rearm the timer to 1ns from now. This will cause the watchdog thread to
+  // wakeup from the poll() and see |enabled_| == false.
+  // This code path is used only in tests. In production code the watchdog is
+  // a singleton and is never destroyed.
+  struct itimerspec ts {};
+  ts.it_value.tv_sec = 0;
+  ts.it_value.tv_nsec = 1;
+  timerfd_settime(*timer_fd_, /*flags=*/0, &ts, nullptr);
+
+  thread_.join();
+}
+
+Watchdog* Watchdog::GetInstance() {
+  static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
+  return watchdog;
+}
+
+// Can be called from any thread.
+Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms,
+                                           WatchdogCrashReason crash_reason) {
+  if (!enabled_.load(std::memory_order_relaxed))
+    return Watchdog::Timer(this, 0, crash_reason);
+
+  return Watchdog::Timer(this, ms, crash_reason);
+}
+
+// Can be called from any thread.
+void Watchdog::AddFatalTimer(TimerData timer) {
+  std::lock_guard<std::mutex> guard(mutex_);
+  timers_.emplace_back(std::move(timer));
+  RearmTimerFd_Locked();
+}
+
+// Can be called from any thread.
+void Watchdog::RemoveFatalTimer(TimerData timer) {
+  std::lock_guard<std::mutex> guard(mutex_);
+  for (auto it = timers_.begin(); it != timers_.end(); it++) {
+    if (*it == timer) {
+      timers_.erase(it);
+      break;  // Remove only one. Doesn't matter which one.
+    }
+  }
+  RearmTimerFd_Locked();
+}
+
+void Watchdog::RearmTimerFd_Locked() {
+  if (!enabled_)
+    return;
+  auto it = std::min_element(timers_.begin(), timers_.end());
+
+  // We use one timerfd to handle all the oustanding |timers_|. Keep it armed
+  // to the task expiring soonest.
+  struct itimerspec ts {};
+  if (it != timers_.end()) {
+    ts.it_value = ToPosixTimespec(it->deadline);
+  }
+  // If |timers_| is empty (it == end()) |ts.it_value| will remain
+  // zero-initialized and that will disarm the timer in the call below.
+  int res = timerfd_settime(*timer_fd_, TFD_TIMER_ABSTIME, &ts, nullptr);
+  PERFETTO_DCHECK(res == 0);
+}
+
+void Watchdog::Start() {
+  std::lock_guard<std::mutex> guard(mutex_);
+  if (thread_.joinable()) {
+    PERFETTO_DCHECK(enabled_);
+  } else {
+    PERFETTO_DCHECK(!enabled_);
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+    // Kick the thread to start running but only on Android or Linux.
+    timer_fd_.reset(
+        timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK));
+    if (!timer_fd_) {
+      PERFETTO_PLOG(
+          "timerfd_create failed, the Perfetto watchdog is not available");
+      return;
+    }
+    enabled_ = true;
+    RearmTimerFd_Locked();  // Deal with timers created before Start().
+    thread_ = std::thread(&Watchdog::ThreadMain, this);
+#endif
+  }
+}
+
+void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
+  // Update the fields under the lock.
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);
+
+  size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
+  memory_window_bytes_.Reset(size);
+  memory_limit_bytes_ = bytes;
+}
+
+void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  PERFETTO_CHECK(percentage <= 100);
+  PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
+                 percentage == 0);
+
+  size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
+  cpu_window_time_ticks_.Reset(size);
+  cpu_limit_percentage_ = percentage;
+}
+
+void Watchdog::ThreadMain() {
+  // Register crash keys explicitly to avoid running out of slots at crash time.
+  g_crash_key_reason.Register();
+
+  base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
+  if (!stat_fd) {
+    PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
+    return;
+  }
+
+  PERFETTO_DCHECK(timer_fd_);
+
+  constexpr uint8_t kFdCount = 1;
+  struct pollfd fds[kFdCount]{};
+  fds[0].fd = *timer_fd_;
+  fds[0].events = POLLIN;
+
+  for (;;) {
+    // We use the poll() timeout to drive the periodic ticks for the cpu/memory
+    // checks. The only other case when the poll() unblocks is when we crash
+    // (or have to quit via enabled_ == false, but that happens only in tests).
+    platform::BeforeMaybeBlockingSyscall();
+    auto ret = poll(fds, kFdCount, static_cast<int>(polling_interval_ms_));
+    platform::AfterMaybeBlockingSyscall();
+    if (!enabled_)
+      return;
+    if (ret < 0) {
+      if (errno == ENOMEM || errno == EINTR) {
+        // Should happen extremely rarely.
+        std::this_thread::sleep_for(std::chrono::milliseconds(100));
+        continue;
+      }
+      PERFETTO_FATAL("watchdog poll() failed");
+    }
+
+    // If we get here either:
+    // 1. poll() timed out, in which case we should process cpu/mem guardrails.
+    // 2. A timer expired, in which case we shall crash.
+
+    uint64_t expired = 0;  // Must be exactly 8 bytes.
+    auto res = PERFETTO_EINTR(read(*timer_fd_, &expired, sizeof(expired)));
+    PERFETTO_DCHECK((res < 0 && (errno == EAGAIN)) ||
+                    (res == sizeof(expired) && expired > 0));
+    const auto now = GetWallTimeMs();
+
+    // Check if any of the timers expired.
+    int tid_to_kill = 0;
+    WatchdogCrashReason crash_reason{};
+    std::unique_lock<std::mutex> guard(mutex_);
+    for (const auto& timer : timers_) {
+      if (now >= timer.deadline) {
+        tid_to_kill = timer.thread_id;
+        crash_reason = timer.crash_reason;
+        break;
+      }
+    }
+    guard.unlock();
+
+    if (tid_to_kill)
+      SerializeLogsAndKillThread(tid_to_kill, crash_reason);
+
+    // Check CPU and memory guardrails (if enabled).
+    lseek(stat_fd.get(), 0, SEEK_SET);
+    ProcStat stat;
+    if (!ReadProcStat(stat_fd.get(), &stat))
+      continue;
+    uint64_t cpu_time = stat.utime + stat.stime;
+    uint64_t rss_bytes =
+        static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();
+
+    bool threshold_exceeded = false;
+    guard.lock();
+    if (CheckMemory_Locked(rss_bytes)) {
+      threshold_exceeded = true;
+      crash_reason = WatchdogCrashReason::kMemGuardrail;
+    } else if (CheckCpu_Locked(cpu_time)) {
+      threshold_exceeded = true;
+      crash_reason = WatchdogCrashReason::kCpuGuardrail;
+    }
+    guard.unlock();
+
+    if (threshold_exceeded)
+      SerializeLogsAndKillThread(getpid(), crash_reason);
+  }
+}
+
+void Watchdog::SerializeLogsAndKillThread(int tid,
+                                          WatchdogCrashReason crash_reason) {
+  g_crash_key_reason.Set(static_cast<int>(crash_reason));
+
+  // We are about to die. Serialize the logs into the crash buffer so the
+  // debuggerd crash handler picks them up and attaches to the bugreport.
+  // In the case of a PERFETTO_CHECK/PERFETTO_FATAL this is done in logging.h.
+  // But in the watchdog case, we don't hit that codepath and must do ourselves.
+  MaybeSerializeLastLogsForCrashReporting();
+
+  // Send a SIGABRT to the thread that armed the timer. This is to see the
+  // callstack of the thread that is stuck in a long task rather than the
+  // watchdog thread.
+  if (syscall(__NR_tgkill, getpid(), tid, SIGABRT) < 0) {
+    // At this point the process must die. If for any reason the tgkill doesn't
+    // work (e.g. the thread has disappeared), force a crash from here.
+    abort();
+  }
+
+  if (disable_kill_failsafe_for_testing_)
+    return;
+
+  // The tgkill() above will take some milliseconds to cause a crash, as it
+  // involves the kernel to queue the SIGABRT on the target thread (often the
+  // main thread, which is != watchdog thread) and do a scheduling round.
+  // If something goes wrong though (the target thread has signals masked or
+  // is stuck in an uninterruptible+wakekill syscall) force quit from this
+  // thread.
+  std::this_thread::sleep_for(std::chrono::seconds(10));
+  abort();
+}
+
+bool Watchdog::CheckMemory_Locked(uint64_t rss_bytes) {
+  if (memory_limit_bytes_ == 0)
+    return false;
+
+  // Add the current stat value to the ring buffer and check that the mean
+  // remains under our threshold.
+  if (memory_window_bytes_.Push(rss_bytes)) {
+    if (memory_window_bytes_.Mean() >
+        static_cast<double>(memory_limit_bytes_)) {
+      PERFETTO_ELOG(
+          "Memory watchdog trigger. Memory window of %f bytes is above the "
+          "%" PRIu64 " bytes limit.",
+          memory_window_bytes_.Mean(), memory_limit_bytes_);
+      return true;
+    }
+  }
+  return false;
+}
+
+bool Watchdog::CheckCpu_Locked(uint64_t cpu_time) {
+  if (cpu_limit_percentage_ == 0)
+    return false;
+
+  // Add the cpu time to the ring buffer.
+  if (cpu_window_time_ticks_.Push(cpu_time)) {
+    // Compute the percentage over the whole window and check that it remains
+    // under the threshold.
+    uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
+                                cpu_window_time_ticks_.OldestWhenFull();
+    double window_interval_ticks =
+        (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
+         1000.0) *
+        static_cast<double>(sysconf(_SC_CLK_TCK));
+    double percentage = static_cast<double>(difference_ticks) /
+                        static_cast<double>(window_interval_ticks) * 100;
+    if (percentage > cpu_limit_percentage_) {
+      PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
+                    "%% CPU limit.",
+                    percentage, cpu_limit_percentage_);
+      return true;
+    }
+  }
+  return false;
+}
+
+uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
+  return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
+}
+
+bool Watchdog::WindowedInterval::Push(uint64_t sample) {
+  // Add the sample to the current position in the ring buffer.
+  buffer_[position_] = sample;
+
+  // Update the position with next one circularily.
+  position_ = (position_ + 1) % size_;
+
+  // Set the filled flag the first time we wrap.
+  filled_ = filled_ || position_ == 0;
+  return filled_;
+}
+
+double Watchdog::WindowedInterval::Mean() const {
+  return MeanForArray(buffer_.get(), size_);
+}
+
+void Watchdog::WindowedInterval::Clear() {
+  position_ = 0;
+  buffer_.reset(new uint64_t[size_]());
+}
+
+void Watchdog::WindowedInterval::Reset(size_t new_size) {
+  position_ = 0;
+  size_ = new_size;
+  buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
+}
+
+Watchdog::Timer::Timer(Watchdog* watchdog,
+                       uint32_t ms,
+                       WatchdogCrashReason crash_reason)
+    : watchdog_(watchdog) {
+  if (!ms)
+    return;  // No-op timer created when the watchdog is disabled.
+  timer_data_.deadline = GetWallTimeMs() + std::chrono::milliseconds(ms);
+  timer_data_.thread_id = GetThreadId();
+  timer_data_.crash_reason = crash_reason;
+  PERFETTO_DCHECK(watchdog_);
+  watchdog_->AddFatalTimer(timer_data_);
+}
+
+Watchdog::Timer::~Timer() {
+  if (timer_data_.deadline.count())
+    watchdog_->RemoveFatalTimer(timer_data_);
+}
+
+Watchdog::Timer::Timer(Timer&& other) noexcept {
+  watchdog_ = std::move(other.watchdog_);
+  other.watchdog_ = nullptr;
+  timer_data_ = std::move(other.timer_data_);
+  other.timer_data_ = TimerData();
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
+// gen_amalgamated begin source: src/base/thread_task_runner.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/thread_task_runner.h
+// gen_amalgamated begin header: include/perfetto/ext/base/unix_task_runner.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+
+#include <chrono>
+#include <deque>
+#include <map>
+#include <mutex>
+#include <vector>
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <poll.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+// Runs a task runner on the current thread.
+//
+// Implementation note: we currently assume (and enforce in debug builds) that
+// Run() is called from the thread that constructed the UnixTaskRunner. This is
+// not strictly necessary, and we could instead track the thread that invokes
+// Run(). However, a related property that *might* be important to enforce is
+// that the destructor runs on the task-running thread. Otherwise, if there are
+// still-pending tasks at the time of destruction, we would destroy those
+// outside of the task thread (which might be unexpected to the caller). On the
+// other hand, the std::function task interface discourages use of any
+// resource-owning tasks (as the callable needs to be copyable), so this might
+// not be important in practice.
+//
+// TODO(rsavitski): consider adding a thread-check in the destructor, after
+// auditing existing usages.
+// TODO(primiano): rename this to TaskRunnerImpl. The "Unix" part is misleading
+// now as it supports also Windows.
+class UnixTaskRunner : public TaskRunner {
+ public:
+  UnixTaskRunner();
+  ~UnixTaskRunner() override;
+
+  // Start executing tasks. Doesn't return until Quit() is called. Run() may be
+  // called multiple times on the same task runner.
+  void Run();
+  void Quit();
+
+  // Checks whether there are any pending immediate tasks to run. Note that
+  // delayed tasks don't count even if they are due to run.
+  bool IsIdleForTesting();
+
+  // TaskRunner implementation:
+  void PostTask(std::function<void()>) override;
+  void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
+  void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
+  void RemoveFileDescriptorWatch(PlatformHandle) override;
+  bool RunsTasksOnCurrentThread() const override;
+
+  // Returns true if the task runner is quitting, or has quit and hasn't been
+  // restarted since. Exposed primarily for ThreadTaskRunner, not necessary for
+  // normal use of this class.
+  bool QuitCalled();
+
+ private:
+  void WakeUp();
+  void UpdateWatchTasksLocked();
+  int GetDelayMsToNextTaskLocked() const;
+  void RunImmediateAndDelayedTask();
+  void PostFileDescriptorWatches(uint64_t windows_wait_result);
+  void RunFileDescriptorWatch(PlatformHandle);
+
+  ThreadChecker thread_checker_;
+  PlatformThreadId created_thread_id_ = GetThreadId();
+
+  EventFd event_;
+
+// The array of fds/handles passed to poll(2) / WaitForMultipleObjects().
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  std::vector<PlatformHandle> poll_fds_;
+#else
+  std::vector<struct pollfd> poll_fds_;
+#endif
+
+  // --- Begin lock-protected members ---
+
+  std::mutex lock_;
+
+  std::deque<std::function<void()>> immediate_tasks_;
+  std::multimap<TimeMillis, std::function<void()>> delayed_tasks_;
+  bool quit_ = false;
+
+  struct WatchTask {
+    std::function<void()> callback;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    // On UNIX systems we make the FD number negative in |poll_fds_| to avoid
+    // polling it again until the queued task runs. On Windows we can't do that.
+    // Instead we keep track of its state here.
+    bool pending = false;
+#else
+    size_t poll_fd_index;  // Index into |poll_fds_|.
+#endif
+  };
+
+  std::map<PlatformHandle, WatchTask> watch_tasks_;
+  bool watch_tasks_changed_ = false;
+
+  // --- End lock-protected members ---
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
+#define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
+
+#include <functional>
+#include <thread>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
+
+namespace perfetto {
+namespace base {
+
+// A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
+// joins the thread upon destruction. Can be moved to transfer ownership.
+//
+// Guarantees that:
+// * the UnixTaskRunner will be constructed and destructed on the task thread.
+// * the task thread will live for the lifetime of the UnixTaskRunner.
+//
+class PERFETTO_EXPORT_COMPONENT ThreadTaskRunner : public TaskRunner {
+ public:
+  static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
+    return ThreadTaskRunner(name);
+  }
+
+  ThreadTaskRunner(const ThreadTaskRunner&) = delete;
+  ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;
+
+  ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
+  ThreadTaskRunner& operator=(ThreadTaskRunner&&);
+  ~ThreadTaskRunner() override;
+
+  // Executes the given function on the task runner thread and blocks the caller
+  // thread until the function has run.
+  void PostTaskAndWaitForTesting(std::function<void()>);
+
+  // Can be called from another thread to get the CPU time of the thread the
+  // task-runner is executing on.
+  uint64_t GetThreadCPUTimeNsForTesting();
+
+  // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
+  // this ThreadTaskRunner object (unless this object is moved-from, in which
+  // case the pointer remains valid for the lifetime of the new owning
+  // ThreadTaskRunner).
+  //
+  // Warning: do not call Quit() on the returned runner pointer, the termination
+  // should be handled exclusively by this class' destructor.
+  UnixTaskRunner* get() const { return task_runner_; }
+
+  // TaskRunner implementation.
+  // These methods just proxy to the underlying task_runner_.
+  void PostTask(std::function<void()>) override;
+  void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
+  void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
+  void RemoveFileDescriptorWatch(PlatformHandle) override;
+  bool RunsTasksOnCurrentThread() const override;
+
+ private:
+  explicit ThreadTaskRunner(const std::string& name);
+  void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);
+
+  std::thread thread_;
+  std::string name_;
+  UnixTaskRunner* task_runner_ = nullptr;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
+
+#include <condition_variable>
+#include <functional>
+#include <mutex>
+#include <thread>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/prctl.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+ThreadTaskRunner::ThreadTaskRunner(ThreadTaskRunner&& other) noexcept
+    : thread_(std::move(other.thread_)), task_runner_(other.task_runner_) {
+  other.task_runner_ = nullptr;
+}
+
+ThreadTaskRunner& ThreadTaskRunner::operator=(ThreadTaskRunner&& other) {
+  this->~ThreadTaskRunner();
+  new (this) ThreadTaskRunner(std::move(other));
+  return *this;
+}
+
+ThreadTaskRunner::~ThreadTaskRunner() {
+  if (task_runner_) {
+    PERFETTO_CHECK(!task_runner_->QuitCalled());
+    task_runner_->Quit();
+
+    PERFETTO_DCHECK(thread_.joinable());
+  }
+  if (thread_.joinable())
+    thread_.join();
+}
+
+ThreadTaskRunner::ThreadTaskRunner(const std::string& name) : name_(name) {
+  std::mutex init_lock;
+  std::condition_variable init_cv;
+
+  std::function<void(UnixTaskRunner*)> initializer =
+      [this, &init_lock, &init_cv](UnixTaskRunner* task_runner) {
+        std::lock_guard<std::mutex> lock(init_lock);
+        task_runner_ = task_runner;
+        // Notify while still holding the lock, as init_cv ceases to exist as
+        // soon as the main thread observes a non-null task_runner_, and it can
+        // wake up spuriously (i.e. before the notify if we had unlocked before
+        // notifying).
+        init_cv.notify_one();
+      };
+
+  thread_ = std::thread(&ThreadTaskRunner::RunTaskThread, this,
+                        std::move(initializer));
+
+  std::unique_lock<std::mutex> lock(init_lock);
+  init_cv.wait(lock, [this] { return !!task_runner_; });
+}
+
+void ThreadTaskRunner::RunTaskThread(
+    std::function<void(UnixTaskRunner*)> initializer) {
+  if (!name_.empty()) {
+    base::MaybeSetThreadName(name_);
+  }
+
+  UnixTaskRunner task_runner;
+  task_runner.PostTask(std::bind(std::move(initializer), &task_runner));
+  task_runner.Run();
+}
+
+void ThreadTaskRunner::PostTaskAndWaitForTesting(std::function<void()> fn) {
+  std::mutex mutex;
+  std::condition_variable cv;
+
+  std::unique_lock<std::mutex> lock(mutex);
+  bool done = false;
+  task_runner_->PostTask([&mutex, &cv, &done, &fn] {
+    fn();
+
+    std::lock_guard<std::mutex> inner_lock(mutex);
+    done = true;
+    cv.notify_one();
+  });
+  cv.wait(lock, [&done] { return done; });
+}
+
+uint64_t ThreadTaskRunner::GetThreadCPUTimeNsForTesting() {
+  uint64_t thread_time_ns = 0;
+  PostTaskAndWaitForTesting([&thread_time_ns] {
+    thread_time_ns = static_cast<uint64_t>(base::GetThreadCPUTimeNs().count());
+  });
+  return thread_time_ns;
+}
+
+void ThreadTaskRunner::PostTask(std::function<void()> task) {
+  task_runner_->PostTask(std::move(task));
+}
+
+void ThreadTaskRunner::PostDelayedTask(std::function<void()> task,
+                                       uint32_t delay_ms) {
+  task_runner_->PostDelayedTask(std::move(task), delay_ms);
+}
+
+void ThreadTaskRunner::AddFileDescriptorWatch(
+    PlatformHandle handle,
+    std::function<void()> watch_task) {
+  task_runner_->AddFileDescriptorWatch(handle, std::move(watch_task));
+}
+
+void ThreadTaskRunner::RemoveFileDescriptorWatch(PlatformHandle handle) {
+  task_runner_->RemoveFileDescriptorWatch(handle);
+}
+
+bool ThreadTaskRunner::RunsTasksOnCurrentThread() const {
+  return task_runner_->RunsTasksOnCurrentThread();
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/unix_task_runner.cc
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
+
+#include <errno.h>
+#include <stdlib.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <Windows.h>
+#include <synchapi.h>
+#else
+#include <unistd.h>
+#endif
+
+#include <algorithm>
+#include <limits>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
+
+namespace perfetto {
+namespace base {
+
+UnixTaskRunner::UnixTaskRunner() {
+  AddFileDescriptorWatch(event_.fd(), [] {
+    // Not reached -- see PostFileDescriptorWatches().
+    PERFETTO_DFATAL("Should be unreachable.");
+  });
+}
+
+UnixTaskRunner::~UnixTaskRunner() = default;
+
+void UnixTaskRunner::WakeUp() {
+  event_.Notify();
+}
+
+void UnixTaskRunner::Run() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  created_thread_id_ = GetThreadId();
+  quit_ = false;
+  for (;;) {
+    int poll_timeout_ms;
+    {
+      std::lock_guard<std::mutex> lock(lock_);
+      if (quit_)
+        return;
+      poll_timeout_ms = GetDelayMsToNextTaskLocked();
+      UpdateWatchTasksLocked();
+    }
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    DWORD timeout =
+        poll_timeout_ms >= 0 ? static_cast<DWORD>(poll_timeout_ms) : INFINITE;
+    DWORD ret =
+        WaitForMultipleObjects(static_cast<DWORD>(poll_fds_.size()),
+                               &poll_fds_[0], /*bWaitAll=*/false, timeout);
+    // Unlike poll(2), WaitForMultipleObjects() returns only *one* handle in the
+    // set, even when >1 is signalled. In order to avoid starvation,
+    // PostFileDescriptorWatches() will WaitForSingleObject() each other handle
+    // to ensure fairness. |ret| here is passed just to avoid an extra
+    // WaitForSingleObject() for the one handle that WaitForMultipleObject()
+    // returned.
+    PostFileDescriptorWatches(ret);
+#else
+    platform::BeforeMaybeBlockingSyscall();
+    int ret = PERFETTO_EINTR(poll(
+        &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), poll_timeout_ms));
+    platform::AfterMaybeBlockingSyscall();
+    PERFETTO_CHECK(ret >= 0);
+    PostFileDescriptorWatches(0 /*ignored*/);
+#endif
+
+    // To avoid starvation we always interleave all types of tasks -- immediate,
+    // delayed and file descriptor watches.
+    RunImmediateAndDelayedTask();
+  }
+}
+
+void UnixTaskRunner::Quit() {
+  std::lock_guard<std::mutex> lock(lock_);
+  quit_ = true;
+  WakeUp();
+}
+
+bool UnixTaskRunner::QuitCalled() {
+  std::lock_guard<std::mutex> lock(lock_);
+  return quit_;
+}
+
+bool UnixTaskRunner::IsIdleForTesting() {
+  std::lock_guard<std::mutex> lock(lock_);
+  return immediate_tasks_.empty();
+}
+
+void UnixTaskRunner::UpdateWatchTasksLocked() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if (!watch_tasks_changed_)
+    return;
+  watch_tasks_changed_ = false;
+#endif
+  poll_fds_.clear();
+  for (auto& it : watch_tasks_) {
+    PlatformHandle handle = it.first;
+    WatchTask& watch_task = it.second;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    if (!watch_task.pending)
+      poll_fds_.push_back(handle);
+#else
+    watch_task.poll_fd_index = poll_fds_.size();
+    poll_fds_.push_back({handle, POLLIN | POLLHUP, 0});
+#endif
+  }
+}
+
+void UnixTaskRunner::RunImmediateAndDelayedTask() {
+  // If locking overhead becomes an issue, add a separate work queue.
+  std::function<void()> immediate_task;
+  std::function<void()> delayed_task;
+  TimeMillis now = GetWallTimeMs();
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    if (!immediate_tasks_.empty()) {
+      immediate_task = std::move(immediate_tasks_.front());
+      immediate_tasks_.pop_front();
+    }
+    if (!delayed_tasks_.empty()) {
+      auto it = delayed_tasks_.begin();
+      if (now >= it->first) {
+        delayed_task = std::move(it->second);
+        delayed_tasks_.erase(it);
+      }
+    }
+  }
+
+  errno = 0;
+  if (immediate_task)
+    RunTaskWithWatchdogGuard(immediate_task);
+  errno = 0;
+  if (delayed_task)
+    RunTaskWithWatchdogGuard(delayed_task);
+}
+
+void UnixTaskRunner::PostFileDescriptorWatches(uint64_t windows_wait_result) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (size_t i = 0; i < poll_fds_.size(); i++) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    const PlatformHandle handle = poll_fds_[i];
+    // |windows_wait_result| is the result of WaitForMultipleObjects() call. If
+    // one of the objects was signalled, it will have a value between
+    // [0, poll_fds_.size()].
+    if (i != windows_wait_result &&
+        WaitForSingleObject(handle, 0) != WAIT_OBJECT_0) {
+      continue;
+    }
+#else
+    base::ignore_result(windows_wait_result);
+    const PlatformHandle handle = poll_fds_[i].fd;
+    if (!(poll_fds_[i].revents & (POLLIN | POLLHUP)))
+      continue;
+    poll_fds_[i].revents = 0;
+#endif
+
+    // The wake-up event is handled inline to avoid an infinite recursion of
+    // posted tasks.
+    if (handle == event_.fd()) {
+      event_.Clear();
+      continue;
+    }
+
+    // Binding to |this| is safe since we are the only object executing the
+    // task.
+    PostTask(std::bind(&UnixTaskRunner::RunFileDescriptorWatch, this, handle));
+
+    // Flag the task as pending.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    // On Windows this is done by marking the WatchTask entry as pending. This
+    // is more expensive than Linux as requires rebuilding the |poll_fds_|
+    // vector on each call. There doesn't seem to be a good alternative though.
+    auto it = watch_tasks_.find(handle);
+    PERFETTO_CHECK(it != watch_tasks_.end());
+    PERFETTO_DCHECK(!it->second.pending);
+    it->second.pending = true;
+#else
+    // On UNIX systems instead, we just make the fd negative while its task is
+    // pending. This makes poll(2) ignore the fd.
+    PERFETTO_DCHECK(poll_fds_[i].fd >= 0);
+    poll_fds_[i].fd = -poll_fds_[i].fd;
+#endif
+  }
+}
+
+void UnixTaskRunner::RunFileDescriptorWatch(PlatformHandle fd) {
+  std::function<void()> task;
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    auto it = watch_tasks_.find(fd);
+    if (it == watch_tasks_.end())
+      return;
+    WatchTask& watch_task = it->second;
+
+    // Make poll(2) pay attention to the fd again. Since another thread may have
+    // updated this watch we need to refresh the set first.
+    UpdateWatchTasksLocked();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    // On Windows we manually track the presence of outstanding tasks for the
+    // watch. The UpdateWatchTasksLocked() in the Run() loop will re-add the
+    // task to the |poll_fds_| vector.
+    PERFETTO_DCHECK(watch_task.pending);
+    watch_task.pending = false;
+#else
+    size_t fd_index = watch_task.poll_fd_index;
+    PERFETTO_DCHECK(fd_index < poll_fds_.size());
+    PERFETTO_DCHECK(::abs(poll_fds_[fd_index].fd) == fd);
+    poll_fds_[fd_index].fd = fd;
+#endif
+    task = watch_task.callback;
+  }
+  errno = 0;
+  RunTaskWithWatchdogGuard(task);
+}
+
+int UnixTaskRunner::GetDelayMsToNextTaskLocked() const {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!immediate_tasks_.empty())
+    return 0;
+  if (!delayed_tasks_.empty()) {
+    TimeMillis diff = delayed_tasks_.begin()->first - GetWallTimeMs();
+    return std::max(0, static_cast<int>(diff.count()));
+  }
+  return -1;
+}
+
+void UnixTaskRunner::PostTask(std::function<void()> task) {
+  bool was_empty;
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    was_empty = immediate_tasks_.empty();
+    immediate_tasks_.push_back(std::move(task));
+  }
+  if (was_empty)
+    WakeUp();
+}
+
+void UnixTaskRunner::PostDelayedTask(std::function<void()> task,
+                                     uint32_t delay_ms) {
+  TimeMillis runtime = GetWallTimeMs() + TimeMillis(delay_ms);
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    delayed_tasks_.insert(std::make_pair(runtime, std::move(task)));
+  }
+  WakeUp();
+}
+
+void UnixTaskRunner::AddFileDescriptorWatch(PlatformHandle fd,
+                                            std::function<void()> task) {
+  PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    PERFETTO_DCHECK(!watch_tasks_.count(fd));
+    WatchTask& watch_task = watch_tasks_[fd];
+    watch_task.callback = std::move(task);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    watch_task.pending = false;
+#else
+    watch_task.poll_fd_index = SIZE_MAX;
+#endif
+    watch_tasks_changed_ = true;
+  }
+  WakeUp();
+}
+
+void UnixTaskRunner::RemoveFileDescriptorWatch(PlatformHandle fd) {
+  PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
+  {
+    std::lock_guard<std::mutex> lock(lock_);
+    PERFETTO_DCHECK(watch_tasks_.count(fd));
+    watch_tasks_.erase(fd);
+    watch_tasks_changed_ = true;
+  }
+  // No need to schedule a wake-up for this.
+}
+
+bool UnixTaskRunner::RunsTasksOnCurrentThread() const {
+  return GetThreadId() == created_thread_id_;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/subprocess.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/subprocess.h
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
+#define INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
+
+#include <condition_variable>
+#include <functional>
+#include <initializer_list>
+#include <mutex>
+#include <optional>
+#include <string>
+#include <thread>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+namespace perfetto {
+namespace base {
+
+// Handles creation and lifecycle management of subprocesses, taking care of
+// all subtleties involved in handling processes on UNIX.
+// This class allows to deal with macro two use-cases:
+// 1) fork() + exec() equivalent: for spawning a brand new process image.
+//    This happens when |args.exec_cmd| is not empty.
+//    This is safe to use even in a multi-threaded environment.
+// 2) fork(): for spawning a process and running a function.
+//    This happens when |args.posix_entrypoint_for_testing| is not empty.
+//    This is intended only for tests as it is extremely subtle.
+//    This mode must be used with extreme care. Before the entrypoint is
+//    invoked all file descriptors other than stdin/out/err and the ones
+//    specified in |args.preserve_fds| will be closed, to avoid each process
+//    retaining a dupe of other subprocesses pipes. This however means that
+//    any non trivial calls (including logging) must be avoided as they might
+//    refer to FDs that are now closed. The entrypoint should really be used
+//    just to signal a pipe or similar for synchronizing sequencing in tests.
+
+//
+// This class allows to control stdin/out/err pipe redirection and takes care
+// of keeping all the pipes pumped (stdin) / drained (stdout/err), in a similar
+// fashion of python's subprocess.Communicate()
+// stdin: is always piped and closed once the |args.input| buffer is written.
+// stdout/err can be either:
+//   - dup()ed onto the parent process stdout/err.
+//   - redirected onto /dev/null.
+//   - piped onto a buffer (see output() method). There is only one output
+//     buffer in total. If both stdout and stderr are set to kBuffer mode, they
+//     will be merged onto the same. There doesn't seem any use case where they
+//     are needed distinctly.
+//
+// Some caveats worth mentioning:
+// - It always waitpid()s, to avoid leaving zombies around. If the process is
+//   not terminated by the time the destructor is reached, the dtor will
+//   send a SIGKILL and wait for the termination.
+// - After fork()-ing it will close all file descriptors, preserving only
+//   stdin/out/err and the fds listed in |args.preserve_fds|.
+// - On Linux/Android, the child process will be SIGKILL-ed if the calling
+//   thread exists, even if the Subprocess is std::move()-d onto another thread.
+//   This happens by virtue PR_SET_PDEATHSIG, which is used to avoid that
+//   child processes are leaked in the case of a crash of the parent (frequent
+//   in tests). However, the child process might still be leaked if execing
+//   a setuid/setgid binary (see man 2 prctl).
+//
+// Usage:
+// base::Subprocess p({"/bin/cat", "-"});
+// (or equivalently:
+//     base::Subprocess p;
+//     p.args.exec_cmd.push_back("/bin/cat");
+//     p.args.exec_cmd.push_back("-");
+//  )
+// p.args.stdout_mode = base::Subprocess::kBuffer;
+// p.args.stderr_mode = base::Subprocess::kInherit;
+// p.args.input = "stdin contents";
+// p.Call();
+// (or equivalently:
+//     p.Start();
+//     p.Wait();
+// )
+// EXPECT_EQ(p.status(), base::Subprocess::kTerminated);
+// EXPECT_EQ(p.returncode(), 0);
+class Subprocess {
+ public:
+  enum Status {
+    kNotStarted = 0,  // Before calling Start() or Call().
+    kRunning,         // After calling Start(), before Wait().
+    kTerminated,      // The subprocess terminated, either successfully or not.
+                      // This includes crashes or other signals on UNIX.
+  };
+
+  enum class OutputMode {
+    kInherit = 0,  // Inherit's the caller process stdout/stderr.
+    kDevNull,      // dup() onto /dev/null.
+    kBuffer,       // dup() onto a pipe and move it into the output() buffer.
+    kFd,           // dup() onto the passed args.fd.
+  };
+
+  enum class InputMode {
+    kBuffer = 0,  // dup() onto a pipe and write args.input on it.
+    kDevNull,     // dup() onto /dev/null.
+  };
+
+  // Input arguments for configuring the subprocess behavior.
+  struct Args {
+    Args(std::initializer_list<std::string> _cmd = {}) : exec_cmd(_cmd) {}
+    Args(Args&&) noexcept;
+    Args& operator=(Args&&);
+    // If non-empty this will cause an exec() when Start()/Call() are called.
+    std::vector<std::string> exec_cmd;
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    // If non-empty, it changes the argv[0] argument passed to exec. If
+    // unset, argv[0] == exec_cmd[0]. This is to handle cases like:
+    // exec_cmd = {"/proc/self/exec"}, argv0: "my_custom_test_override".
+    std::string posix_argv0_override_for_testing;
+
+    // If non-empty this will be invoked on the fork()-ed child process, after
+    // stdin/out/err has been redirected and all other file descriptor are
+    // closed. It is valid to specify both |exec_cmd| AND
+    // |posix_entrypoint_for_testing|. In this case the latter will be invoked
+    // just before the exec() call, but after having closed all fds % stdin/o/e.
+    // This is for synchronization barriers in tests.
+    std::function<void()> posix_entrypoint_for_testing;
+
+    // When set, will will move the process to the given process group. If set
+    // and zero, it will create a new process group. Effectively this calls
+    // setpgid(0 /*self_pid*/, posix_proc_group_id).
+    // This can be used to avoid that subprocesses receive CTRL-C from the
+    // terminal, while still living in the same session.
+    std::optional<pid_t> posix_proc_group_id{};
+#endif
+
+    // If non-empty, replaces the environment passed to exec().
+    std::vector<std::string> env;
+
+    // The file descriptors in this list will not be closed.
+    std::vector<int> preserve_fds;
+
+    // The data to push in the child process stdin, if input_mode ==
+    // InputMode::kBuffer.
+    std::string input;
+
+    InputMode stdin_mode = InputMode::kBuffer;
+    OutputMode stdout_mode = OutputMode::kInherit;
+    OutputMode stderr_mode = OutputMode::kInherit;
+
+    base::ScopedPlatformHandle out_fd;
+
+    // Returns " ".join(exec_cmd), quoting arguments.
+    std::string GetCmdString() const;
+  };
+
+  struct ResourceUsage {
+    uint32_t cpu_utime_ms = 0;
+    uint32_t cpu_stime_ms = 0;
+    uint32_t max_rss_kb = 0;
+    uint32_t min_page_faults = 0;
+    uint32_t maj_page_faults = 0;
+    uint32_t vol_ctx_switch = 0;
+    uint32_t invol_ctx_switch = 0;
+
+    uint32_t cpu_time_ms() const { return cpu_utime_ms + cpu_stime_ms; }
+  };
+
+  explicit Subprocess(std::initializer_list<std::string> exec_cmd = {});
+  Subprocess(Subprocess&&) noexcept;
+  Subprocess& operator=(Subprocess&&);
+  ~Subprocess();  // It will KillAndWaitForTermination() if still alive.
+
+  // Starts the subprocess but doesn't wait for its termination. The caller
+  // is expected to either call Wait() or Poll() after this call.
+  void Start();
+
+  // Wait for process termination. Can be called more than once.
+  // Args:
+  //   |timeout_ms| = 0: wait indefinitely.
+  //   |timeout_ms| > 0: wait for at most |timeout_ms|.
+  // Returns:
+  //  True: The process terminated. See status() and returncode().
+  //  False: Timeout reached, the process is still running. In this case the
+  //         process will be left in the kRunning state.
+  bool Wait(int timeout_ms = 0);
+
+  // Equivalent of Start() + Wait();
+  // Returns true if the process exited cleanly with return code 0. False in
+  // any othe case.
+  bool Call(int timeout_ms = 0);
+
+  Status Poll();
+
+  // Sends a signal (SIGKILL if not specified) and wait for process termination.
+  void KillAndWaitForTermination(int sig_num = 0);
+
+  PlatformProcessId pid() const { return s_->pid; }
+
+  // The accessors below are updated only after a call to Poll(), Wait() or
+  // KillAndWaitForTermination().
+  // In most cases you want to call Poll() rather than these accessors.
+
+  Status status() const { return s_->status; }
+  int returncode() const { return s_->returncode; }
+  bool timed_out() const { return s_->timed_out; }
+
+  // This contains both stdout and stderr (if the corresponding _mode ==
+  // OutputMode::kBuffer). It's non-const so the caller can std::move() it.
+  std::string& output() { return s_->output; }
+  const std::string& output() const { return s_->output; }
+
+  const ResourceUsage& posix_rusage() const { return *s_->rusage; }
+
+  Args args;
+
+ private:
+  // The signal/exit code used when killing the process in case of a timeout.
+  static const int kTimeoutSignal;
+
+  Subprocess(const Subprocess&) = delete;
+  Subprocess& operator=(const Subprocess&) = delete;
+
+  // This is to deal robustly with the move operators, without having to
+  // manually maintain member-wise move instructions.
+  struct MovableState {
+    base::Pipe stdin_pipe;
+    base::Pipe stdouterr_pipe;
+    PlatformProcessId pid;
+    Status status = kNotStarted;
+    int returncode = -1;
+    std::string output;  // Stdin+stderr. Only when OutputMode::kBuffer.
+    std::unique_ptr<ResourceUsage> rusage{new ResourceUsage()};
+    bool timed_out = false;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    std::thread stdouterr_thread;
+    std::thread stdin_thread;
+    ScopedPlatformHandle win_proc_handle;
+    ScopedPlatformHandle win_thread_handle;
+
+    base::EventFd stdouterr_done_event;
+    std::mutex mutex;  // Protects locked_outerr_buf and the two pipes.
+    std::string locked_outerr_buf;
+#else
+    base::Pipe exit_status_pipe;
+    size_t input_written = 0;
+    std::thread waitpid_thread;
+#endif
+  };
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  static void StdinThread(MovableState*, std::string input);
+  static void StdoutErrThread(MovableState*);
+#else
+  void TryPushStdin();
+  void TryReadStdoutAndErr();
+  void TryReadExitStatus();
+  bool PollInternal(int poll_timeout_ms);
+#endif
+
+  std::unique_ptr<MovableState> s_;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
+
+#include <tuple>
+
+// This file contains only the common bits (ctors / dtors / move operators).
+// The rest lives in subprocess_posix.cc and subprocess_windows.cc.
+
+namespace perfetto {
+namespace base {
+
+Subprocess::Args::Args(Args&&) noexcept = default;
+Subprocess::Args& Subprocess::Args::operator=(Args&&) = default;
+
+Subprocess::Subprocess(std::initializer_list<std::string> a)
+    : args(a), s_(new MovableState()) {}
+
+Subprocess::Subprocess(Subprocess&& other) noexcept {
+  static_assert(sizeof(Subprocess) ==
+                    sizeof(std::tuple<std::unique_ptr<MovableState>, Args>),
+                "base::Subprocess' move ctor needs updating");
+  s_ = std::move(other.s_);
+  args = std::move(other.args);
+
+  // Reset the state of the moved-from object.
+  other.s_.reset(new MovableState());
+  other.~Subprocess();
+  new (&other) Subprocess();
+}
+
+Subprocess& Subprocess::operator=(Subprocess&& other) {
+  this->~Subprocess();
+  new (this) Subprocess(std::move(other));
+  return *this;
+}
+
+Subprocess::~Subprocess() {
+  if (s_->status == kRunning)
+    KillAndWaitForTermination();
+}
+
+bool Subprocess::Call(int timeout_ms) {
+  PERFETTO_CHECK(s_->status == kNotStarted);
+  Start();
+
+  if (!Wait(timeout_ms)) {
+    s_->timed_out = true;
+    KillAndWaitForTermination(kTimeoutSignal);
+  }
+  PERFETTO_DCHECK(s_->status != kRunning);
+  return s_->status == kTerminated && s_->returncode == 0;
+}
+
+std::string Subprocess::Args::GetCmdString() const {
+  std::string str;
+  for (size_t i = 0; i < exec_cmd.size(); i++) {
+    str += i > 0 ? " \"" : "";
+    str += exec_cmd[i];
+    str += i > 0 ? "\"" : "";
+  }
+  return str;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/subprocess_posix.cc
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+
+#include <fcntl.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <thread>
+#include <tuple>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/prctl.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+// In MacOS this is not defined in any header.
+extern "C" char** environ;
+
+namespace perfetto {
+namespace base {
+
+namespace {
+
+struct ChildProcessArgs {
+  Subprocess::Args* create_args;
+  const char* exec_cmd = nullptr;
+  std::vector<char*> argv;
+  std::vector<char*> env;
+  int stdin_pipe_rd = -1;
+  int stdouterr_pipe_wr = -1;
+};
+
+// Don't add any dynamic allocation in this function. This will be invoked
+// under a fork(), potentially in a state where the allocator lock is held.
+void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // In no case we want a child process to outlive its parent process. This is
+  // relevant for tests, so that a test failure/crash doesn't leave child
+  // processes around that get reparented to init.
+  prctl(PR_SET_PDEATHSIG, SIGKILL);
+#endif
+
+  auto die = [args](const char* err) __attribute__((noreturn)) {
+    base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
+    base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
+    // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
+    // "In particular, the value 128 is used to indicate failure to execute
+    // another program in a subprocess. This convention is not universally
+    // obeyed, but it is a good idea to follow it in your programs."
+    _exit(128);
+  };
+
+  if (args->create_args->posix_proc_group_id.has_value()) {
+    if (setpgid(0 /*self*/, args->create_args->posix_proc_group_id.value())) {
+      die("setpgid() failed");
+    }
+  }
+
+  auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
+    int flags = fcntl(fd, F_GETFD, 0);
+    if (flags < 0)
+      die("fcntl(F_GETFD) failed");
+    flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
+    if (fcntl(fd, F_SETFD, flags) < 0)
+      die("fcntl(F_SETFD) failed");
+  };
+
+  if (getppid() == 1)
+    die("terminating because parent process died");
+
+  switch (args->create_args->stdin_mode) {
+    case Subprocess::InputMode::kBuffer:
+      if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
+        die("Failed to dup2(STDIN)");
+      close(args->stdin_pipe_rd);
+      break;
+    case Subprocess::InputMode::kDevNull:
+      if (dup2(open("/dev/null", O_RDONLY), STDIN_FILENO) == -1)
+        die("Failed to dup2(STDOUT)");
+      break;
+  }
+
+  switch (args->create_args->stdout_mode) {
+    case Subprocess::OutputMode::kInherit:
+      break;
+    case Subprocess::OutputMode::kDevNull: {
+      if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
+        die("Failed to dup2(STDOUT)");
+      break;
+    }
+    case Subprocess::OutputMode::kBuffer:
+      if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
+        die("Failed to dup2(STDOUT)");
+      break;
+    case Subprocess::OutputMode::kFd:
+      if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
+        die("Failed to dup2(STDOUT)");
+      break;
+  }
+
+  switch (args->create_args->stderr_mode) {
+    case Subprocess::OutputMode::kInherit:
+      break;
+    case Subprocess::OutputMode::kDevNull: {
+      if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
+        die("Failed to dup2(STDERR)");
+      break;
+    }
+    case Subprocess::OutputMode::kBuffer:
+      if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
+        die("Failed to dup2(STDERR)");
+      break;
+    case Subprocess::OutputMode::kFd:
+      if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
+        die("Failed to dup2(STDERR)");
+      break;
+  }
+
+  // Close all FDs % stdin/out/err and the ones that the client explicitly
+  // asked to retain. The reason for this is twofold:
+  // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
+  //    that didn't get marked as O_CLOEXEC by accident.
+  // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
+  //    that would prevent the parent process to receive EOFs (tests usually use
+  //    pipes as a synchronization mechanism between subprocesses).
+  const auto& preserve_fds = args->create_args->preserve_fds;
+  for (int i = 0; i < 512; i++) {
+    if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
+        i != args->stdouterr_pipe_wr &&
+        !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
+      close(i);
+    }
+  }
+
+  // Clears O_CLOEXEC from stdin/out/err and the |preserve_fds| list. These are
+  // the only FDs that we want to be preserved after the exec().
+  set_fd_close_on_exec(STDIN_FILENO, false);
+  set_fd_close_on_exec(STDOUT_FILENO, false);
+  set_fd_close_on_exec(STDERR_FILENO, false);
+
+  for (auto fd : preserve_fds)
+    set_fd_close_on_exec(fd, false);
+
+  // If the caller specified a std::function entrypoint, run that first.
+  if (args->create_args->posix_entrypoint_for_testing)
+    args->create_args->posix_entrypoint_for_testing();
+
+  // If the caller specified only an entrypoint, without any args, exit now.
+  // Otherwise proceed with the exec() below.
+  if (!args->exec_cmd)
+    _exit(0);
+
+  // If |args[0]| is a path use execv() (which takes a path), othewise use
+  // exevp(), which uses the shell and follows PATH.
+  if (strchr(args->exec_cmd, '/')) {
+    char** env = args->env.empty() ? environ : args->env.data();
+    execve(args->exec_cmd, args->argv.data(), env);
+  } else {
+    // There is no execvpe() on Mac.
+    if (!args->env.empty())
+      die("A full path is required for |exec_cmd| when setting |env|");
+    execvp(args->exec_cmd, args->argv.data());
+  }
+
+  // Reached only if execv fails.
+  die("execve() failed");
+}
+
+}  // namespace
+
+// static
+const int Subprocess::kTimeoutSignal = SIGKILL;
+
+void Subprocess::Start() {
+  ChildProcessArgs proc_args;
+  proc_args.create_args = &args;
+
+  // Setup argv.
+  if (!args.exec_cmd.empty()) {
+    proc_args.exec_cmd = args.exec_cmd[0].c_str();
+    for (const std::string& arg : args.exec_cmd)
+      proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
+    proc_args.argv.push_back(nullptr);
+
+    if (!args.posix_argv0_override_for_testing.empty()) {
+      proc_args.argv[0] =
+          const_cast<char*>(args.posix_argv0_override_for_testing.c_str());
+    }
+  }
+
+  // Setup env.
+  if (!args.env.empty()) {
+    for (const std::string& str : args.env)
+      proc_args.env.push_back(const_cast<char*>(str.c_str()));
+    proc_args.env.push_back(nullptr);
+  }
+
+  // Setup the pipes for stdin/err redirection.
+  if (args.stdin_mode == InputMode::kBuffer) {
+    s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
+    proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
+  }
+  s_->stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
+  proc_args.stdouterr_pipe_wr = *s_->stdouterr_pipe.wr;
+
+  // Spawn the child process that will exec().
+  s_->pid = fork();
+  PERFETTO_CHECK(s_->pid >= 0);
+  if (s_->pid == 0) {
+    // Close the parent-ends of the pipes.
+    s_->stdin_pipe.wr.reset();
+    s_->stdouterr_pipe.rd.reset();
+    ChildProcess(&proc_args);
+    // ChildProcess() doesn't return, not even in case of failures.
+    PERFETTO_FATAL("not reached");
+  }
+
+  s_->status = kRunning;
+
+  // Close the child-end of the pipes.
+  // Deliberately NOT closing the s_->stdin_pipe.rd. This is to avoid crashing
+  // with a SIGPIPE if the process exits without consuming its stdin, while
+  // the parent tries to write() on the other end of the stdin pipe.
+  s_->stdouterr_pipe.wr.reset();
+  proc_args.create_args->out_fd.reset();
+
+  // Spawn a thread that is blocked on waitpid() and writes the termination
+  // status onto a pipe. The problem here is that waipid() doesn't have a
+  // timeout option and can't be passed to poll(). The alternative would be
+  // using a SIGCHLD handler, but anecdotally signal handlers introduce more
+  // problems than what they solve.
+  s_->exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
+
+  // Both ends of the pipe are closed after the thread.join().
+  int pid = s_->pid;
+  int exit_status_pipe_wr = s_->exit_status_pipe.wr.release();
+  auto* rusage = s_->rusage.get();
+  s_->waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
+    int pid_stat = -1;
+    struct rusage usg {};
+    int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
+    PERFETTO_CHECK(wait_res == pid);
+
+    auto tv_to_ms = [](const struct timeval& tv) {
+      return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
+    };
+    rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
+    rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
+    rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
+    rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
+    rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
+    rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
+    rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);
+
+    base::ignore_result(PERFETTO_EINTR(
+        write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
+    PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
+  });
+}
+
+Subprocess::Status Subprocess::Poll() {
+  if (s_->status != kRunning)
+    return s_->status;  // Nothing to poll.
+  while (PollInternal(0 /* don't block*/)) {
+  }
+  return s_->status;
+}
+
+// |timeout_ms| semantic:
+//   -1: Block indefinitely.
+//    0: Don't block, return immediately.
+//   >0: Block for at most X ms.
+// Returns:
+//  True: Read at least one fd (so there might be more queued).
+//  False: if all fds reached quiescent (no data to read/write).
+bool Subprocess::PollInternal(int poll_timeout_ms) {
+  struct pollfd fds[3]{};
+  size_t num_fds = 0;
+  if (s_->exit_status_pipe.rd) {
+    fds[num_fds].fd = *s_->exit_status_pipe.rd;
+    fds[num_fds].events = POLLIN;
+    num_fds++;
+  }
+  if (s_->stdouterr_pipe.rd) {
+    fds[num_fds].fd = *s_->stdouterr_pipe.rd;
+    fds[num_fds].events = POLLIN;
+    num_fds++;
+  }
+  if (s_->stdin_pipe.wr) {
+    fds[num_fds].fd = *s_->stdin_pipe.wr;
+    fds[num_fds].events = POLLOUT;
+    num_fds++;
+  }
+
+  if (num_fds == 0)
+    return false;
+
+  auto nfds = static_cast<nfds_t>(num_fds);
+  int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
+  PERFETTO_CHECK(poll_res >= 0);
+
+  TryReadStdoutAndErr();
+  TryPushStdin();
+  TryReadExitStatus();
+
+  return poll_res > 0;
+}
+
+bool Subprocess::Wait(int timeout_ms) {
+  PERFETTO_CHECK(s_->status != kNotStarted);
+
+  // Break out of the loop only after both conditions are satisfied:
+  // - All stdout/stderr data has been read (if kBuffer).
+  // - The process exited.
+  // Note that the two events can happen arbitrary order. After the process
+  // exits, there might be still data in the pipe buffer, which we want to
+  // read fully.
+  //
+  // Instead, don't wait on the stdin to be fully written. The child process
+  // might exit prematurely (or crash). If that happens, we can end up in a
+  // state where the write(stdin_pipe_.wr) will never unblock.
+
+  const int64_t t_start = base::GetWallTimeMs().count();
+  while (s_->exit_status_pipe.rd || s_->stdouterr_pipe.rd) {
+    int poll_timeout_ms = -1;  // Block until a FD is ready.
+    if (timeout_ms > 0) {
+      const int64_t now = GetWallTimeMs().count();
+      poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
+      if (poll_timeout_ms <= 0)
+        return false;
+    }
+    PollInternal(poll_timeout_ms);
+  }  // while(...)
+  return true;
+}
+
+void Subprocess::TryReadExitStatus() {
+  if (!s_->exit_status_pipe.rd)
+    return;
+
+  int pid_stat = -1;
+  int64_t rsize = PERFETTO_EINTR(
+      read(*s_->exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
+  if (rsize < 0 && errno == EAGAIN)
+    return;
+
+  if (rsize > 0) {
+    PERFETTO_CHECK(rsize == sizeof(pid_stat));
+  } else if (rsize < 0) {
+    PERFETTO_PLOG("Subprocess read(s_->exit_status_pipe) failed");
+  }
+  s_->waitpid_thread.join();
+  s_->exit_status_pipe.rd.reset();
+
+  s_->status = kTerminated;
+  if (WIFEXITED(pid_stat)) {
+    s_->returncode = WEXITSTATUS(pid_stat);
+  } else if (WIFSIGNALED(pid_stat)) {
+    s_->returncode = 128 + WTERMSIG(pid_stat);  // Follow bash convention.
+  } else {
+    PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
+  }
+}
+
+// If the stidn pipe is still open, push input data and close it at the end.
+void Subprocess::TryPushStdin() {
+  if (!s_->stdin_pipe.wr)
+    return;
+
+  PERFETTO_DCHECK(args.input.empty() || s_->input_written < args.input.size());
+  if (!args.input.empty()) {
+    int64_t wsize =
+        PERFETTO_EINTR(write(*s_->stdin_pipe.wr, &args.input[s_->input_written],
+                             args.input.size() - s_->input_written));
+    if (wsize < 0 && errno == EAGAIN)
+      return;
+
+    if (wsize >= 0) {
+      // Whether write() can return 0 is one of the greatest mysteries of UNIX.
+      // Just ignore it.
+      s_->input_written += static_cast<size_t>(wsize);
+    } else {
+      PERFETTO_PLOG("Subprocess write(stdin) failed");
+      s_->stdin_pipe.wr.reset();
+    }
+  }
+  PERFETTO_DCHECK(s_->input_written <= args.input.size());
+  if (s_->input_written == args.input.size())
+    s_->stdin_pipe.wr.reset();  // Close stdin.
+}
+
+void Subprocess::TryReadStdoutAndErr() {
+  if (!s_->stdouterr_pipe.rd)
+    return;
+  char buf[4096];
+  int64_t rsize =
+      PERFETTO_EINTR(read(*s_->stdouterr_pipe.rd, buf, sizeof(buf)));
+  if (rsize < 0 && errno == EAGAIN)
+    return;
+
+  if (rsize > 0) {
+    s_->output.append(buf, static_cast<size_t>(rsize));
+  } else if (rsize == 0 /* EOF */) {
+    s_->stdouterr_pipe.rd.reset();
+  } else {
+    PERFETTO_PLOG("Subprocess read(stdout/err) failed");
+    s_->stdouterr_pipe.rd.reset();
+  }
+}
+
+void Subprocess::KillAndWaitForTermination(int sig_num) {
+  kill(s_->pid, sig_num ? sig_num : SIGKILL);
+  Wait();
+  // TryReadExitStatus must have joined the thread.
+  PERFETTO_DCHECK(!s_->waitpid_thread.joinable());
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // PERFETTO_OS_LINUX || PERFETTO_OS_ANDROID || PERFETTO_OS_APPLE
+// gen_amalgamated begin source: src/base/subprocess_windows.cc
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include <stdio.h>
+
+#include <algorithm>
+#include <mutex>
+#include <tuple>
+
+#include <Windows.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+// static
+const int Subprocess::kTimeoutSignal = static_cast<int>(STATUS_TIMEOUT);
+
+void Subprocess::Start() {
+  if (args.exec_cmd.empty()) {
+    PERFETTO_ELOG("Subprocess.exec_cmd cannot be empty on Windows");
+    return;
+  }
+
+  // Quote arguments but only when ambiguous. When quoting, CreateProcess()
+  // assumes that the command is an absolute path and does not search in the
+  // %PATH%. If non quoted, instead, CreateProcess() tries both. This is to
+  // allow Subprocess("cmd.exe", "/c", "shell command").
+  std::string cmd;
+  for (const auto& part : args.exec_cmd) {
+    if (part.find(" ") != std::string::npos) {
+      cmd += "\"" + part + "\" ";
+    } else {
+      cmd += part + " ";
+    }
+  }
+  // Remove trailing space.
+  if (!cmd.empty())
+    cmd.resize(cmd.size() - 1);
+
+  if (args.stdin_mode == InputMode::kBuffer) {
+    s_->stdin_pipe = Pipe::Create();
+    // Allow the child process to inherit the other end of the pipe.
+    PERFETTO_CHECK(
+        ::SetHandleInformation(*s_->stdin_pipe.rd, HANDLE_FLAG_INHERIT, 1));
+  }
+
+  if (args.stderr_mode == OutputMode::kBuffer ||
+      args.stdout_mode == OutputMode::kBuffer) {
+    s_->stdouterr_pipe = Pipe::Create();
+    PERFETTO_CHECK(
+        ::SetHandleInformation(*s_->stdouterr_pipe.wr, HANDLE_FLAG_INHERIT, 1));
+  }
+
+  ScopedPlatformHandle nul_handle;
+  if (args.stderr_mode == OutputMode::kDevNull ||
+      args.stdout_mode == OutputMode::kDevNull) {
+    nul_handle.reset(::CreateFileA(
+        "NUL", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
+        nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
+    PERFETTO_CHECK(::SetHandleInformation(*nul_handle, HANDLE_FLAG_INHERIT, 1));
+  }
+
+  PROCESS_INFORMATION proc_info{};
+  STARTUPINFOA start_info{};
+  start_info.cb = sizeof(STARTUPINFOA);
+
+  if (args.stderr_mode == OutputMode::kInherit) {
+    start_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
+  } else if (args.stderr_mode == OutputMode::kBuffer) {
+    start_info.hStdError = *s_->stdouterr_pipe.wr;
+  } else if (args.stderr_mode == OutputMode::kDevNull) {
+    start_info.hStdError = *nul_handle;
+  } else if (args.stderr_mode == OutputMode::kFd) {
+    PERFETTO_CHECK(
+        ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
+    start_info.hStdError = *args.out_fd;
+  } else {
+    PERFETTO_CHECK(false);
+  }
+
+  if (args.stdout_mode == OutputMode::kInherit) {
+    start_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
+  } else if (args.stdout_mode == OutputMode::kBuffer) {
+    start_info.hStdOutput = *s_->stdouterr_pipe.wr;
+  } else if (args.stdout_mode == OutputMode::kDevNull) {
+    start_info.hStdOutput = *nul_handle;
+  } else if (args.stdout_mode == OutputMode::kFd) {
+    PERFETTO_CHECK(
+        ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
+    start_info.hStdOutput = *args.out_fd;
+  } else {
+    PERFETTO_CHECK(false);
+  }
+
+  if (args.stdin_mode == InputMode::kBuffer) {
+    start_info.hStdInput = *s_->stdin_pipe.rd;
+  } else if (args.stdin_mode == InputMode::kDevNull) {
+    start_info.hStdInput = *nul_handle;
+  }
+
+  start_info.dwFlags |= STARTF_USESTDHANDLES;
+
+  // Create the child process.
+  bool success =
+      ::CreateProcessA(nullptr,      // App name. Needs to be null to use PATH.
+                       &cmd[0],      // Command line.
+                       nullptr,      // Process security attributes.
+                       nullptr,      // Primary thread security attributes.
+                       true,         // Handles are inherited.
+                       0,            // Flags.
+                       nullptr,      // Use parent's environment.
+                       nullptr,      // Use parent's current directory.
+                       &start_info,  // STARTUPINFO pointer.
+                       &proc_info);  // Receives PROCESS_INFORMATION.
+
+  // Close on our side the pipe ends that we passed to the child process.
+  s_->stdin_pipe.rd.reset();
+  s_->stdouterr_pipe.wr.reset();
+  args.out_fd.reset();
+
+  if (!success) {
+    s_->returncode = ERROR_FILE_NOT_FOUND;
+    s_->status = kTerminated;
+    s_->stdin_pipe.wr.reset();
+    s_->stdouterr_pipe.rd.reset();
+    PERFETTO_ELOG("CreateProcess failed: %lx, cmd: %s", GetLastError(),
+                  &cmd[0]);
+    return;
+  }
+
+  s_->pid = proc_info.dwProcessId;
+  s_->win_proc_handle = ScopedPlatformHandle(proc_info.hProcess);
+  s_->win_thread_handle = ScopedPlatformHandle(proc_info.hThread);
+  s_->status = kRunning;
+
+  MovableState* s = s_.get();
+  if (args.stdin_mode == InputMode::kBuffer) {
+    s_->stdin_thread = std::thread(&Subprocess::StdinThread, s, args.input);
+  }
+
+  if (args.stderr_mode == OutputMode::kBuffer ||
+      args.stdout_mode == OutputMode::kBuffer) {
+    PERFETTO_DCHECK(s_->stdouterr_pipe.rd);
+    s_->stdouterr_thread = std::thread(&Subprocess::StdoutErrThread, s);
+  }
+}
+
+// static
+void Subprocess::StdinThread(MovableState* s, std::string input) {
+  size_t input_written = 0;
+  while (input_written < input.size()) {
+    DWORD wsize = 0;
+    if (::WriteFile(*s->stdin_pipe.wr, input.data() + input_written,
+                    static_cast<DWORD>(input.size() - input_written), &wsize,
+                    nullptr)) {
+      input_written += wsize;
+    } else {
+      // ERROR_BROKEN_PIPE is WAI when the child just closes stdin and stops
+      // accepting input.
+      auto err = ::GetLastError();
+      if (err != ERROR_BROKEN_PIPE)
+        PERFETTO_PLOG("Subprocess WriteFile(stdin) failed %lx", err);
+      break;
+    }
+  }  // while(...)
+  std::unique_lock<std::mutex> lock(s->mutex);
+  s->stdin_pipe.wr.reset();
+}
+
+// static
+void Subprocess::StdoutErrThread(MovableState* s) {
+  char buf[4096];
+  for (;;) {
+    DWORD rsize = 0;
+    bool res =
+        ::ReadFile(*s->stdouterr_pipe.rd, buf, sizeof(buf), &rsize, nullptr);
+    if (!res) {
+      auto err = GetLastError();
+      if (err != ERROR_BROKEN_PIPE)
+        PERFETTO_PLOG("Subprocess ReadFile(stdouterr) failed %ld", err);
+    }
+
+    if (rsize > 0) {
+      std::unique_lock<std::mutex> lock(s->mutex);
+      s->locked_outerr_buf.append(buf, static_cast<size_t>(rsize));
+    } else {  // EOF or some error.
+      break;
+    }
+  }  // For(..)
+
+  // Close the stdouterr_pipe. The main loop looks at the pipe closure to
+  // determine whether the stdout/err thread has completed.
+  {
+    std::unique_lock<std::mutex> lock(s->mutex);
+    s->stdouterr_pipe.rd.reset();
+  }
+  s->stdouterr_done_event.Notify();
+}
+
+Subprocess::Status Subprocess::Poll() {
+  if (s_->status != kRunning)
+    return s_->status;  // Nothing to poll.
+  Wait(1 /*ms*/);
+  return s_->status;
+}
+
+bool Subprocess::Wait(int timeout_ms) {
+  PERFETTO_CHECK(s_->status != kNotStarted);
+  const bool wait_forever = timeout_ms == 0;
+  const int64_t wait_start_ms = base::GetWallTimeMs().count();
+
+  // Break out of the loop only after both conditions are satisfied:
+  // - All stdout/stderr data has been read (if OutputMode::kBuffer).
+  // - The process exited.
+  // Note that the two events can happen arbitrary order. After the process
+  // exits, there might be still data in the pipe buffer, which we want to
+  // read fully.
+  // Note also that stdout/err might be "complete" before starting, if neither
+  // is operating in OutputMode::kBuffer mode. In that case we just want to wait
+  // for the process termination.
+  //
+  // Instead, don't wait on the stdin to be fully written. The child process
+  // might exit prematurely (or crash). If that happens, we can end up in a
+  // state where the write(stdin_pipe_.wr) will never unblock.
+  bool stdouterr_complete = false;
+  for (;;) {
+    HANDLE wait_handles[2]{};
+    DWORD num_handles = 0;
+
+    // Check if the process exited.
+    bool process_exited = !s_->win_proc_handle;
+    if (!process_exited) {
+      DWORD exit_code = STILL_ACTIVE;
+      PERFETTO_CHECK(::GetExitCodeProcess(*s_->win_proc_handle, &exit_code));
+      if (exit_code != STILL_ACTIVE) {
+        s_->returncode = static_cast<int>(exit_code);
+        s_->status = kTerminated;
+        s_->win_proc_handle.reset();
+        s_->win_thread_handle.reset();
+        process_exited = true;
+      }
+    } else {
+      PERFETTO_DCHECK(s_->status != kRunning);
+    }
+    if (!process_exited) {
+      wait_handles[num_handles++] = *s_->win_proc_handle;
+    }
+
+    // Check if there is more output and if the stdout/err pipe has been closed.
+    {
+      std::unique_lock<std::mutex> lock(s_->mutex);
+      // Move the output from the internal buffer shared with the
+      // stdouterr_thread to the final buffer exposed to the client.
+      if (!s_->locked_outerr_buf.empty()) {
+        s_->output.append(std::move(s_->locked_outerr_buf));
+        s_->locked_outerr_buf.clear();
+      }
+      stdouterr_complete = !s_->stdouterr_pipe.rd;
+      if (!stdouterr_complete) {
+        wait_handles[num_handles++] = s_->stdouterr_done_event.fd();
+      }
+    }  // lock(s_->mutex)
+
+    if (num_handles == 0) {
+      PERFETTO_DCHECK(process_exited && stdouterr_complete);
+      break;
+    }
+
+    DWORD wait_ms;  // Note: DWORD is unsigned.
+    if (wait_forever) {
+      wait_ms = INFINITE;
+    } else {
+      const int64_t now = GetWallTimeMs().count();
+      const int64_t wait_left_ms = timeout_ms - (now - wait_start_ms);
+      if (wait_left_ms <= 0)
+        return false;  // Timed out
+      wait_ms = static_cast<DWORD>(wait_left_ms);
+    }
+
+    auto wait_res =
+        ::WaitForMultipleObjects(num_handles, wait_handles, false, wait_ms);
+    PERFETTO_CHECK(wait_res != WAIT_FAILED);
+  }
+
+  PERFETTO_DCHECK(!s_->win_proc_handle);
+  PERFETTO_DCHECK(!s_->win_thread_handle);
+
+  if (s_->stdin_thread.joinable())  // Might not exist if CreateProcess failed.
+    s_->stdin_thread.join();
+  if (s_->stdouterr_thread.joinable())
+    s_->stdouterr_thread.join();
+
+  // The stdin pipe is closed by the dedicated stdin thread. However if that is
+  // not started (e.g. because of no redirection) force close it now. Needs to
+  // happen after the join() to be thread safe.
+  s_->stdin_pipe.wr.reset();
+  s_->stdouterr_pipe.rd.reset();
+
+  return true;
+}
+
+void Subprocess::KillAndWaitForTermination(int exit_code) {
+  auto code = exit_code ? static_cast<DWORD>(exit_code) : STATUS_CONTROL_C_EXIT;
+  ::TerminateProcess(*s_->win_proc_handle, code);
+  Wait();
+  // TryReadExitStatus must have joined the threads.
+  PERFETTO_DCHECK(!s_->stdin_thread.joinable());
+  PERFETTO_DCHECK(!s_->stdouterr_thread.joinable());
+}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // PERFETTO_OS_WIN
+// gen_amalgamated begin source: src/protozero/field.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+#if !PERFETTO_IS_LITTLE_ENDIAN()
+// The memcpy() for fixed32/64 below needs to be adjusted if we want to
+// support big endian CPUs. There doesn't seem to be a compelling need today.
+#error Unimplemented for big endian archs.
+#endif
+
+namespace protozero {
+
+template <typename Container>
+void Field::SerializeAndAppendToInternal(Container* dst) const {
+  namespace pu = proto_utils;
+  size_t initial_size = dst->size();
+  dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
+  uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
+  uint8_t* wptr = start;
+  switch (type_) {
+    case static_cast<int>(pu::ProtoWireType::kVarInt): {
+      wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
+      wptr = pu::WriteVarInt(int_value_, wptr);
+      break;
+    }
+    case static_cast<int>(pu::ProtoWireType::kFixed32): {
+      wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
+      uint32_t value32 = static_cast<uint32_t>(int_value_);
+      memcpy(wptr, &value32, sizeof(value32));
+      wptr += sizeof(uint32_t);
+      break;
+    }
+    case static_cast<int>(pu::ProtoWireType::kFixed64): {
+      wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
+      memcpy(wptr, &int_value_, sizeof(int_value_));
+      wptr += sizeof(uint64_t);
+      break;
+    }
+    case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
+      ConstBytes payload = as_bytes();
+      wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
+      wptr = pu::WriteVarInt(payload.size, wptr);
+      memcpy(wptr, payload.data, payload.size);
+      wptr += payload.size;
+      break;
+    }
+    default:
+      PERFETTO_FATAL("Unknown field type %u", type_);
+  }
+  size_t written_size = static_cast<size_t>(wptr - start);
+  PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
+  PERFETTO_DCHECK(initial_size + written_size <= dst->size());
+  dst->resize(initial_size + written_size);
+}
+
+void Field::SerializeAndAppendTo(std::string* dst) const {
+  SerializeAndAppendToInternal(dst);
+}
+
+void Field::SerializeAndAppendTo(std::vector<uint8_t>* dst) const {
+  SerializeAndAppendToInternal(dst);
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/gen_field_helpers.cc
+/*
+ * Copyright (C) 2023 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+
+namespace protozero {
+namespace internal {
+namespace gen_helpers {
+
+void DeserializeString(const protozero::Field& field, std::string* dst) {
+  field.get(dst);
+}
+
+template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
+                                        uint64_t>(const protozero::Field& field,
+                                                  std::vector<uint64_t>* dst);
+
+template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
+                                        int64_t>(const protozero::Field& field,
+                                                 std::vector<int64_t>* dst);
+
+template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
+                                        uint32_t>(const protozero::Field& field,
+                                                  std::vector<uint32_t>* dst);
+
+template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
+                                        int32_t>(const protozero::Field& field,
+                                                 std::vector<int32_t>* dst);
+
+void SerializeTinyVarInt(uint32_t field_id, bool value, Message* msg) {
+  msg->AppendTinyVarInt(field_id, value);
+}
+
+template void SerializeExtendedVarInt<uint64_t>(uint32_t field_id,
+                                                uint64_t value,
+                                                Message* msg);
+
+template void SerializeExtendedVarInt<uint32_t>(uint32_t field_id,
+                                                uint32_t value,
+                                                Message* msg);
+
+template void SerializeFixed<double>(uint32_t field_id,
+                                     double value,
+                                     Message* msg);
+
+template void SerializeFixed<float>(uint32_t field_id,
+                                    float value,
+                                    Message* msg);
+
+template void SerializeFixed<uint64_t>(uint32_t field_id,
+                                       uint64_t value,
+                                       Message* msg);
+
+template void SerializeFixed<int64_t>(uint32_t field_id,
+                                      int64_t value,
+                                      Message* msg);
+
+template void SerializeFixed<uint32_t>(uint32_t field_id,
+                                       uint32_t value,
+                                       Message* msg);
+
+template void SerializeFixed<int32_t>(uint32_t field_id,
+                                      int32_t value,
+                                      Message* msg);
+
+void SerializeString(uint32_t field_id,
+                     const std::string& value,
+                     Message* msg) {
+  msg->AppendString(field_id, value);
+}
+
+void SerializeUnknownFields(const std::string& unknown_fields, Message* msg) {
+  msg->AppendRawProtoBytes(unknown_fields.data(), unknown_fields.size());
+}
+
+MessageSerializer::MessageSerializer() = default;
+
+MessageSerializer::~MessageSerializer() = default;
+
+std::vector<uint8_t> MessageSerializer::SerializeAsArray() {
+  return msg_.SerializeAsArray();
+}
+
+std::string MessageSerializer::SerializeAsString() {
+  return msg_.SerializeAsString();
+}
+
+template bool EqualsField<std::string>(const std::string&, const std::string&);
+
+}  // namespace gen_helpers
+}  // namespace internal
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/message.cc
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+
+#include <atomic>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+
+#if !PERFETTO_IS_LITTLE_ENDIAN()
+// The memcpy() for float and double below needs to be adjusted if we want to
+// support big endian CPUs. There doesn't seem to be a compelling need today.
+#error Unimplemented for big endian archs.
+#endif
+
+namespace protozero {
+
+namespace {
+
+constexpr int kBytesToCompact = proto_utils::kMessageLengthFieldSize - 1u;
+
+#if PERFETTO_DCHECK_IS_ON()
+std::atomic<uint32_t> g_generation;
+#endif
+
+}  // namespace
+
+// Do NOT put any code in the constructor or use default initialization.
+// Use the Reset() method below instead.
+
+// This method is called to initialize both root and nested messages.
+void Message::Reset(ScatteredStreamWriter* stream_writer, MessageArena* arena) {
+// Older versions of libstdcxx don't have is_trivially_constructible.
+#if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20170516
+  static_assert(std::is_trivially_constructible<Message>::value,
+                "Message must be trivially constructible");
+#endif
+
+  static_assert(std::is_trivially_destructible<Message>::value,
+                "Message must be trivially destructible");
+  stream_writer_ = stream_writer;
+  arena_ = arena;
+  size_ = 0;
+  size_field_ = nullptr;
+  nested_message_ = nullptr;
+  message_state_ = MessageState::kNotFinalized;
+#if PERFETTO_DCHECK_IS_ON()
+  handle_ = nullptr;
+  generation_ = g_generation.fetch_add(1, std::memory_order_relaxed);
+#endif
+}
+
+void Message::AppendString(uint32_t field_id, const char* str) {
+  AppendBytes(field_id, str, strlen(str));
+}
+
+void Message::AppendBytes(uint32_t field_id, const void* src, size_t size) {
+  PERFETTO_DCHECK(field_id);
+  if (nested_message_)
+    EndNestedMessage();
+
+  PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
+  // Write the proto preamble (field id, type and length of the field).
+  uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
+  uint8_t* pos = buffer;
+  pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
+                                 pos);
+  pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
+  WriteToStream(buffer, pos);
+
+  const uint8_t* src_u8 = reinterpret_cast<const uint8_t*>(src);
+  WriteToStream(src_u8, src_u8 + size);
+}
+
+size_t Message::AppendScatteredBytes(uint32_t field_id,
+                                     ContiguousMemoryRange* ranges,
+                                     size_t num_ranges) {
+  PERFETTO_DCHECK(field_id);
+  if (nested_message_)
+    EndNestedMessage();
+
+  size_t size = 0;
+  for (size_t i = 0; i < num_ranges; ++i) {
+    size += ranges[i].size();
+  }
+
+  PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
+
+  uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
+  uint8_t* pos = buffer;
+  pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
+                                 pos);
+  pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
+  WriteToStream(buffer, pos);
+
+  for (size_t i = 0; i < num_ranges; ++i) {
+    auto& range = ranges[i];
+    WriteToStream(range.begin, range.end);
+  }
+
+  return size;
+}
+
+uint32_t Message::Finalize() {
+  if (is_finalized())
+    return size_;
+
+  if (nested_message_)
+    EndNestedMessage();
+
+  // Write the length of the nested message a posteriori, using a leading-zero
+  // redundant varint encoding. This can be nullptr for the root message, among
+  // many reasons, because the TraceWriterImpl delegate is keeping track of the
+  // root fragment size independently.
+  if (size_field_) {
+    PERFETTO_DCHECK(!is_finalized());
+    PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
+    //
+    // Normally the size of a protozero message is written with 4 bytes just
+    // before the contents of the message itself:
+    //
+    //    size          message data
+    //   [aa bb cc dd] [01 23 45 67 ...]
+    //
+    // We always reserve 4 bytes for the size, because the real size of the
+    // message isn't known until the call to Finalize(). This is possible
+    // because we can use leading zero redundant varint coding to expand any
+    // size smaller than 256 MiB to 4 bytes.
+    //
+    // However this is wasteful for short, frequently written messages, so the
+    // code below uses a 1 byte size field when possible. This is done by
+    // shifting the already-written data (which should still be in the cache)
+    // back by 3 bytes, resulting in this layout:
+    //
+    //   size  message data
+    //   [aa] [01 23 45 67 ...]
+    //
+    // We can only do this optimization if the message is contained in a single
+    // chunk (since we can't modify previously committed chunks). We can check
+    // this by verifying that the size field is immediately before the message
+    // in memory and is fully contained by the current chunk.
+    //
+    if (PERFETTO_LIKELY(size_ <= proto_utils::kMaxOneByteMessageLength &&
+                        size_field_ ==
+                            stream_writer_->write_ptr() - size_ -
+                                proto_utils::kMessageLengthFieldSize &&
+                        size_field_ >= stream_writer_->cur_range().begin)) {
+      stream_writer_->Rewind(size_, kBytesToCompact);
+      PERFETTO_DCHECK(size_field_ == stream_writer_->write_ptr() - size_ - 1u);
+      *size_field_ = static_cast<uint8_t>(size_);
+      message_state_ = MessageState::kFinalizedWithCompaction;
+    } else {
+      proto_utils::WriteRedundantVarInt(size_, size_field_);
+      message_state_ = MessageState::kFinalized;
+    }
+    size_field_ = nullptr;
+  } else {
+    message_state_ = MessageState::kFinalized;
+  }
+
+#if PERFETTO_DCHECK_IS_ON()
+  if (handle_)
+    handle_->reset_message();
+#endif
+
+  return size_;
+}
+
+Message* Message::BeginNestedMessageInternal(uint32_t field_id) {
+  PERFETTO_DCHECK(field_id);
+  if (nested_message_)
+    EndNestedMessage();
+
+  // Write the proto preamble for the nested message.
+  uint8_t data[proto_utils::kMaxTagEncodedSize];
+  uint8_t* data_end = proto_utils::WriteVarInt(
+      proto_utils::MakeTagLengthDelimited(field_id), data);
+  WriteToStream(data, data_end);
+
+  Message* message = arena_->NewMessage();
+  message->Reset(stream_writer_, arena_);
+
+  // The length of the nested message cannot be known upfront. So right now
+  // just reserve the bytes to encode the size after the nested message is done.
+  message->set_size_field(
+      stream_writer_->ReserveBytes(proto_utils::kMessageLengthFieldSize));
+  size_ += proto_utils::kMessageLengthFieldSize;
+
+  nested_message_ = message;
+  return message;
+}
+
+void Message::EndNestedMessage() {
+  size_ += nested_message_->Finalize();
+  if (nested_message_->message_state_ ==
+      MessageState::kFinalizedWithCompaction) {
+    size_ -= kBytesToCompact;
+  }
+  arena_->DeleteLastMessage(nested_message_);
+  nested_message_ = nullptr;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/message_arena.cc
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
+
+#include <atomic>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+
+namespace protozero {
+
+MessageArena::MessageArena() {
+  // The code below assumes that there is always at least one block.
+  blocks_.emplace_front();
+  static_assert(
+      std::alignment_of<decltype(blocks_.front().storage[0])>::value >=
+          alignof(Message),
+      "MessageArea's storage is not properly aligned");
+}
+
+MessageArena::~MessageArena() = default;
+
+Message* MessageArena::NewMessage() {
+  PERFETTO_DCHECK(!blocks_.empty());  // Should never become empty.
+
+  Block* block = &blocks_.front();
+  if (PERFETTO_UNLIKELY(block->entries >= Block::kCapacity)) {
+    blocks_.emplace_front();
+    block = &blocks_.front();
+  }
+  const auto idx = block->entries++;
+  void* storage = &block->storage[idx];
+  PERFETTO_ASAN_UNPOISON(storage, sizeof(Message));
+  return new (storage) Message();
+}
+
+void MessageArena::DeleteLastMessageInternal() {
+  PERFETTO_DCHECK(!blocks_.empty());  // Should never be empty, see below.
+  Block* block = &blocks_.front();
+  PERFETTO_DCHECK(block->entries > 0);
+
+  // This is the reason why there is no ~Message() call here.
+  // MessageArea::Reset() (see header) also relies on dtor being trivial.
+  static_assert(std::is_trivially_destructible<Message>::value,
+                "Message must be trivially destructible");
+
+  --block->entries;
+  PERFETTO_ASAN_POISON(&block->storage[block->entries], sizeof(Message));
+
+  // Don't remove the first block to avoid malloc/free calls when the root
+  // message is reset. Hitting the allocator all the times is a waste of time.
+  if (block->entries == 0 && std::next(blocks_.cbegin()) != blocks_.cend()) {
+    blocks_.pop_front();
+  }
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/packed_repeated_fields.cc
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace protozero {
+
+void PackedBufferBase::GrowSlowpath() {
+  size_t write_off = static_cast<size_t>(write_ptr_ - storage_begin_);
+  size_t old_size = static_cast<size_t>(storage_end_ - storage_begin_);
+  size_t new_size = old_size < 65536 ? (old_size * 2) : (old_size * 3 / 2);
+  new_size = perfetto::base::AlignUp<4096>(new_size);
+  std::unique_ptr<uint8_t[]> new_buf(new uint8_t[new_size]);
+  memcpy(new_buf.get(), storage_begin_, old_size);
+  heap_buf_ = std::move(new_buf);
+  storage_begin_ = heap_buf_.get();
+  storage_end_ = storage_begin_ + new_size;
+  write_ptr_ = storage_begin_ + write_off;
+}
+
+void PackedBufferBase::Reset() {
+  heap_buf_.reset();
+  storage_begin_ = reinterpret_cast<uint8_t*>(&stack_buf_[0]);
+  storage_end_ = reinterpret_cast<uint8_t*>(&stack_buf_[kOnStackStorageSize]);
+  write_ptr_ = storage_begin_;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/proto_decoder.cc
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+
+#include <string.h>
+
+#include <cinttypes>
+#include <limits>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+using namespace proto_utils;
+
+#if !PERFETTO_IS_LITTLE_ENDIAN()
+#error Unimplemented for big endian archs.
+#endif
+
+namespace {
+
+struct ParseFieldResult {
+  enum ParseResult { kAbort, kSkip, kOk };
+  ParseResult parse_res;
+  const uint8_t* next;
+  Field field;
+};
+
+// Parses one field and returns the field itself and a pointer to the next
+// field to parse. If parsing fails, the returned |next| == |buffer|.
+ParseFieldResult ParseOneField(const uint8_t* const buffer,
+                               const uint8_t* const end) {
+  ParseFieldResult res{ParseFieldResult::kAbort, buffer, Field{}};
+
+  // The first byte of a proto field is structured as follows:
+  // The least 3 significant bits determine the field type.
+  // The most 5 significant bits determine the field id. If MSB == 1, the
+  // field id continues on the next bytes following the VarInt encoding.
+  const uint8_t kFieldTypeNumBits = 3;
+  const uint64_t kFieldTypeMask = (1 << kFieldTypeNumBits) - 1;  // 0000 0111;
+  const uint8_t* pos = buffer;
+
+  // If we've already hit the end, just return an invalid field.
+  if (PERFETTO_UNLIKELY(pos >= end))
+    return res;
+
+  uint64_t preamble = 0;
+  if (PERFETTO_LIKELY(*pos < 0x80)) {  // Fastpath for fields with ID < 16.
+    preamble = *(pos++);
+  } else {
+    const uint8_t* next = ParseVarInt(pos, end, &preamble);
+    if (PERFETTO_UNLIKELY(pos == next))
+      return res;
+    pos = next;
+  }
+
+  uint32_t field_id = static_cast<uint32_t>(preamble >> kFieldTypeNumBits);
+  if (field_id == 0 || pos >= end)
+    return res;
+
+  auto field_type = static_cast<uint8_t>(preamble & kFieldTypeMask);
+  const uint8_t* new_pos = pos;
+  uint64_t int_value = 0;
+  uint64_t size = 0;
+
+  switch (field_type) {
+    case static_cast<uint8_t>(ProtoWireType::kVarInt): {
+      new_pos = ParseVarInt(pos, end, &int_value);
+
+      // new_pos not being greater than pos means ParseVarInt could not fully
+      // parse the number. This is because we are out of space in the buffer.
+      // Set the id to zero and return but don't update the offset so a future
+      // read can read this field.
+      if (PERFETTO_UNLIKELY(new_pos == pos))
+        return res;
+
+      break;
+    }
+
+    case static_cast<uint8_t>(ProtoWireType::kLengthDelimited): {
+      uint64_t payload_length;
+      new_pos = ParseVarInt(pos, end, &payload_length);
+      if (PERFETTO_UNLIKELY(new_pos == pos))
+        return res;
+
+      // ParseVarInt guarantees that |new_pos| <= |end| when it succeeds;
+      if (payload_length > static_cast<uint64_t>(end - new_pos))
+        return res;
+
+      const uintptr_t payload_start = reinterpret_cast<uintptr_t>(new_pos);
+      int_value = payload_start;
+      size = payload_length;
+      new_pos += payload_length;
+      break;
+    }
+
+    case static_cast<uint8_t>(ProtoWireType::kFixed64): {
+      new_pos = pos + sizeof(uint64_t);
+      if (PERFETTO_UNLIKELY(new_pos > end))
+        return res;
+      memcpy(&int_value, pos, sizeof(uint64_t));
+      break;
+    }
+
+    case static_cast<uint8_t>(ProtoWireType::kFixed32): {
+      new_pos = pos + sizeof(uint32_t);
+      if (PERFETTO_UNLIKELY(new_pos > end))
+        return res;
+      memcpy(&int_value, pos, sizeof(uint32_t));
+      break;
+    }
+
+    default:
+      PERFETTO_DLOG("Invalid proto field type: %u", field_type);
+      return res;
+  }
+
+  res.next = new_pos;
+
+  if (PERFETTO_UNLIKELY(field_id > Field::kMaxId)) {
+    PERFETTO_DLOG("Skipping field %" PRIu32 " because its id > %" PRIu32,
+                  field_id, Field::kMaxId);
+    res.parse_res = ParseFieldResult::kSkip;
+    return res;
+  }
+
+  if (PERFETTO_UNLIKELY(size > proto_utils::kMaxMessageLength)) {
+    PERFETTO_DLOG("Skipping field %" PRIu32 " because it's too big (%" PRIu64
+                  " KB)",
+                  field_id, size / 1024);
+    res.parse_res = ParseFieldResult::kSkip;
+    return res;
+  }
+
+  res.parse_res = ParseFieldResult::kOk;
+  res.field.initialize(field_id, field_type, int_value,
+                       static_cast<uint32_t>(size));
+  return res;
+}
+
+}  // namespace
+
+Field ProtoDecoder::FindField(uint32_t field_id) {
+  Field res{};
+  auto old_position = read_ptr_;
+  read_ptr_ = begin_;
+  for (auto f = ReadField(); f.valid(); f = ReadField()) {
+    if (f.id() == field_id) {
+      res = f;
+      break;
+    }
+  }
+  read_ptr_ = old_position;
+  return res;
+}
+
+Field ProtoDecoder::ReadField() {
+  ParseFieldResult res;
+  do {
+    res = ParseOneField(read_ptr_, end_);
+    read_ptr_ = res.next;
+  } while (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip));
+  return res.field;
+}
+
+void TypedProtoDecoderBase::ParseAllFields() {
+  const uint8_t* cur = begin_;
+  ParseFieldResult res;
+  for (;;) {
+    res = ParseOneField(cur, end_);
+    PERFETTO_DCHECK(res.parse_res != ParseFieldResult::kOk || res.next != cur);
+    cur = res.next;
+    if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip))
+      continue;
+    if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort))
+      break;
+
+    PERFETTO_DCHECK(res.parse_res == ParseFieldResult::kOk);
+    PERFETTO_DCHECK(res.field.valid());
+    auto field_id = res.field.id();
+    if (PERFETTO_UNLIKELY(field_id >= num_fields_))
+      continue;
+
+    // There are two reasons why we might want to expand the heap capacity:
+    // 1. We are writing a non-repeated field, which has an id >
+    //    INITIAL_STACK_CAPACITY. In this case ExpandHeapStorage() ensures to
+    //    allocate at least (num_fields_ + 1) slots.
+    // 2. We are writing a repeated field but ran out of capacity.
+    if (PERFETTO_UNLIKELY(field_id >= size_ || size_ >= capacity_))
+      ExpandHeapStorage();
+
+    PERFETTO_DCHECK(field_id < size_);
+    Field* fld = &fields_[field_id];
+    if (PERFETTO_LIKELY(!fld->valid())) {
+      // This is the first time we see this field.
+      *fld = std::move(res.field);
+    } else {
+      // Repeated field case.
+      // In this case we need to:
+      // 1. Append the last value of the field to end of the repeated field
+      //    storage.
+      // 2. Replace the default instance at offset |field_id| with the current
+      //    value. This is because in case of repeated field a call to Get(X) is
+      //    supposed to return the last value of X, not the first one.
+      // This is so that the RepeatedFieldIterator will iterate in the right
+      // order, see comments on RepeatedFieldIterator.
+      PERFETTO_DCHECK(size_ < capacity_);
+      fields_[size_++] = *fld;
+      *fld = std::move(res.field);
+    }
+  }
+  read_ptr_ = res.next;
+}
+
+void TypedProtoDecoderBase::ExpandHeapStorage() {
+  // When we expand the heap we must ensure that we have at very last capacity
+  // to deal with all known fields plus at least one repeated field. We go +2048
+  // here based on observations on a large 4GB android trace. This is to avoid
+  // trivial re-allocations when dealing with repeated fields of a message that
+  // has > INITIAL_STACK_CAPACITY fields.
+  const uint32_t min_capacity = num_fields_ + 2048;  // Any num >= +1 will do.
+  const uint32_t new_capacity = std::max(capacity_ * 2, min_capacity);
+  PERFETTO_CHECK(new_capacity > size_ && new_capacity > num_fields_);
+  std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
+
+  static_assert(std::is_trivially_constructible<Field>::value,
+                "Field must be trivially constructible");
+  static_assert(std::is_trivially_copyable<Field>::value,
+                "Field must be trivially copyable");
+
+  // Zero-initialize the slots for known field IDs slots, as they can be
+  // randomly accessed. Instead, there is no need to initialize the repeated
+  // slots, because they are written linearly with no gaps and are always
+  // initialized before incrementing |size_|.
+  const uint32_t new_size = std::max(size_, num_fields_);
+  memset(&new_storage[size_], 0, sizeof(Field) * (new_size - size_));
+
+  memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
+
+  heap_storage_ = std::move(new_storage);
+  fields_ = &heap_storage_[0];
+  capacity_ = new_capacity;
+  size_ = new_size;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/scattered_heap_buffer.cc
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+
+#include <algorithm>
+
+namespace protozero {
+
+ScatteredHeapBuffer::Slice::Slice()
+    : buffer_(nullptr), size_(0u), unused_bytes_(0u) {}
+
+ScatteredHeapBuffer::Slice::Slice(size_t size)
+    : buffer_(std::unique_ptr<uint8_t[]>(new uint8_t[size])),
+      size_(size),
+      unused_bytes_(size) {
+  PERFETTO_DCHECK(size);
+  Clear();
+}
+
+ScatteredHeapBuffer::Slice::Slice(Slice&& slice) noexcept = default;
+
+ScatteredHeapBuffer::Slice::~Slice() = default;
+
+ScatteredHeapBuffer::Slice& ScatteredHeapBuffer::Slice::operator=(Slice&&) =
+    default;
+
+void ScatteredHeapBuffer::Slice::Clear() {
+  unused_bytes_ = size_;
+#if PERFETTO_DCHECK_IS_ON()
+  memset(start(), 0xff, size_);
+#endif  // PERFETTO_DCHECK_IS_ON()
+}
+
+ScatteredHeapBuffer::ScatteredHeapBuffer(size_t initial_slice_size_bytes,
+                                         size_t maximum_slice_size_bytes)
+    : next_slice_size_(initial_slice_size_bytes),
+      maximum_slice_size_(maximum_slice_size_bytes) {
+  PERFETTO_DCHECK(next_slice_size_ && maximum_slice_size_);
+  PERFETTO_DCHECK(maximum_slice_size_ >= initial_slice_size_bytes);
+}
+
+ScatteredHeapBuffer::~ScatteredHeapBuffer() = default;
+
+protozero::ContiguousMemoryRange ScatteredHeapBuffer::GetNewBuffer() {
+  PERFETTO_CHECK(writer_);
+  AdjustUsedSizeOfCurrentSlice();
+
+  if (cached_slice_.start()) {
+    slices_.push_back(std::move(cached_slice_));
+    PERFETTO_DCHECK(!cached_slice_.start());
+  } else {
+    slices_.emplace_back(next_slice_size_);
+  }
+  next_slice_size_ = std::min(maximum_slice_size_, next_slice_size_ * 2);
+  return slices_.back().GetTotalRange();
+}
+
+const std::vector<ScatteredHeapBuffer::Slice>&
+ScatteredHeapBuffer::GetSlices() {
+  AdjustUsedSizeOfCurrentSlice();
+  return slices_;
+}
+
+std::vector<uint8_t> ScatteredHeapBuffer::StitchSlices() {
+  size_t stitched_size = 0u;
+  const auto& slices = GetSlices();
+  for (const auto& slice : slices)
+    stitched_size += slice.size() - slice.unused_bytes();
+
+  std::vector<uint8_t> buffer;
+  buffer.reserve(stitched_size);
+  for (const auto& slice : slices) {
+    auto used_range = slice.GetUsedRange();
+    buffer.insert(buffer.end(), used_range.begin, used_range.end);
+  }
+  return buffer;
+}
+
+std::vector<protozero::ContiguousMemoryRange> ScatteredHeapBuffer::GetRanges() {
+  std::vector<protozero::ContiguousMemoryRange> ranges;
+  for (const auto& slice : GetSlices())
+    ranges.push_back(slice.GetUsedRange());
+  return ranges;
+}
+
+void ScatteredHeapBuffer::AdjustUsedSizeOfCurrentSlice() {
+  if (!slices_.empty())
+    slices_.back().set_unused_bytes(writer_->bytes_available());
+}
+
+size_t ScatteredHeapBuffer::GetTotalSize() {
+  size_t total_size = 0;
+  for (auto& slice : slices_) {
+    total_size += slice.size();
+  }
+  return total_size;
+}
+
+void ScatteredHeapBuffer::Reset() {
+  if (slices_.empty())
+    return;
+  cached_slice_ = std::move(slices_.front());
+  cached_slice_.Clear();
+  slices_.clear();
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/scattered_stream_null_delegate.cc
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
+
+namespace protozero {
+
+// An implementation of ScatteredStreamWriter::Delegate which always returns
+// the same piece of memory.
+// This is used when we need to no-op the writers (e.g. during teardown or in
+// case of resource exhaustion), avoiding that the clients have to deal with
+// nullptr checks.
+ScatteredStreamWriterNullDelegate::ScatteredStreamWriterNullDelegate(
+    size_t chunk_size)
+    : chunk_size_(chunk_size),
+      chunk_(std::unique_ptr<uint8_t[]>(new uint8_t[chunk_size_])) {}
+
+ScatteredStreamWriterNullDelegate::~ScatteredStreamWriterNullDelegate() {}
+
+ContiguousMemoryRange ScatteredStreamWriterNullDelegate::GetNewBuffer() {
+  return {chunk_.get(), chunk_.get() + chunk_size_};
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/scattered_stream_writer.cc
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+#include <algorithm>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace protozero {
+
+ScatteredStreamWriter::Delegate::~Delegate() {}
+
+uint8_t* ScatteredStreamWriter::Delegate::AnnotatePatch(uint8_t* patch_addr) {
+  // In most cases, a patch is transparent. The caller can write directly into
+  // `to_patch`, because its memory is not going away. TraceWriterImpl, however,
+  // requires a more complicated logic, because the chunks might be copied
+  // earlier.
+  return patch_addr;
+}
+
+ScatteredStreamWriter::ScatteredStreamWriter(Delegate* delegate)
+    : delegate_(delegate),
+      cur_range_({nullptr, nullptr}),
+      write_ptr_(nullptr) {}
+
+ScatteredStreamWriter::~ScatteredStreamWriter() {}
+
+void ScatteredStreamWriter::Reset(ContiguousMemoryRange range) {
+  written_previously_ += static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
+  cur_range_ = range;
+  write_ptr_ = range.begin;
+  PERFETTO_DCHECK(!write_ptr_ || write_ptr_ < cur_range_.end);
+}
+
+void ScatteredStreamWriter::Extend() {
+  Reset(delegate_->GetNewBuffer());
+}
+
+void ScatteredStreamWriter::WriteBytesSlowPath(const uint8_t* src,
+                                               size_t size) {
+  size_t bytes_left = size;
+  while (bytes_left > 0) {
+    if (write_ptr_ >= cur_range_.end)
+      Extend();
+    const size_t burst_size = std::min(bytes_available(), bytes_left);
+    WriteBytesUnsafe(src, burst_size);
+    bytes_left -= burst_size;
+    src += burst_size;
+  }
+}
+
+// TODO(primiano): perf optimization: I suspect that at the end this will always
+// be called with |size| == 4, in which case we might just hardcode it.
+uint8_t* ScatteredStreamWriter::ReserveBytes(size_t size) {
+  if (write_ptr_ + size > cur_range_.end) {
+    // Assume the reservations are always < Delegate::GetNewBuffer().size(),
+    // so that one single call to Extend() will definitely give enough headroom.
+    Extend();
+    PERFETTO_DCHECK(write_ptr_ + size <= cur_range_.end);
+  }
+  uint8_t* begin = write_ptr_;
+  write_ptr_ += size;
+#if PERFETTO_DCHECK_IS_ON()
+  // In the past, the service had a matching DCHECK in
+  // TraceBuffer::TryPatchChunkContents, which was assuming that service and all
+  // producers are built with matching DCHECK levels. This turned out to be a
+  // source of problems and was removed in b/197340286. This memset is useless
+  // these days and is here only to maintain ABI compatibility between producers
+  // that use a v20+ SDK and older versions of the service that were built in
+  // debug mode. At some point around 2023 it should be safe to remove it.
+  // (running a debug version of traced in production seems a bad idea
+  // regardless).
+  memset(begin, 0, size);
+#endif
+  return begin;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/static_buffer.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace protozero {
+
+StaticBufferDelegate::~StaticBufferDelegate() = default;
+
+ContiguousMemoryRange StaticBufferDelegate::GetNewBuffer() {
+  if (get_new_buffer_called_once_) {
+    // This is the 2nd time GetNewBuffer is called. The estimate is wrong. We
+    // shouldn't try to grow the buffer after the initial call.
+    PERFETTO_FATAL("Static buffer too small");
+  }
+  get_new_buffer_called_once_ = true;
+  return range_;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/virtual_destructors.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+
+namespace protozero {
+
+CppMessageObj::~CppMessageObj() = default;
+
+}  // namespace protozero
+// gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_energy_consumer_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor() = default;
+AndroidEnergyConsumerDescriptor::~AndroidEnergyConsumerDescriptor() = default;
+AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&) = default;
+AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(const AndroidEnergyConsumerDescriptor&) = default;
+AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept = default;
+AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(AndroidEnergyConsumerDescriptor&&) = default;
+
+bool AndroidEnergyConsumerDescriptor::operator==(const AndroidEnergyConsumerDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(energy_consumers_, other.energy_consumers_);
+}
+
+int AndroidEnergyConsumerDescriptor::energy_consumers_size() const { return static_cast<int>(energy_consumers_.size()); }
+void AndroidEnergyConsumerDescriptor::clear_energy_consumers() { energy_consumers_.clear(); }
+AndroidEnergyConsumer* AndroidEnergyConsumerDescriptor::add_energy_consumers() { energy_consumers_.emplace_back(); return &energy_consumers_.back(); }
+bool AndroidEnergyConsumerDescriptor::ParseFromArray(const void* raw, size_t size) {
+  energy_consumers_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* energy_consumers */:
+        energy_consumers_.emplace_back();
+        energy_consumers_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidEnergyConsumerDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidEnergyConsumerDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidEnergyConsumerDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: energy_consumers
+  for (auto& it : energy_consumers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+AndroidEnergyConsumer::AndroidEnergyConsumer() = default;
+AndroidEnergyConsumer::~AndroidEnergyConsumer() = default;
+AndroidEnergyConsumer::AndroidEnergyConsumer(const AndroidEnergyConsumer&) = default;
+AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(const AndroidEnergyConsumer&) = default;
+AndroidEnergyConsumer::AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept = default;
+AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(AndroidEnergyConsumer&&) = default;
+
+bool AndroidEnergyConsumer::operator==(const AndroidEnergyConsumer& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(energy_consumer_id_, other.energy_consumer_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(ordinal_, other.ordinal_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool AndroidEnergyConsumer::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* energy_consumer_id */:
+        field.get(&energy_consumer_id_);
+        break;
+      case 2 /* ordinal */:
+        field.get(&ordinal_);
+        break;
+      case 3 /* type */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &type_);
+        break;
+      case 4 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidEnergyConsumer::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidEnergyConsumer::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidEnergyConsumer::Serialize(::protozero::Message* msg) const {
+  // Field 1: energy_consumer_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, energy_consumer_id_, msg);
+  }
+
+  // Field 2: ordinal
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, ordinal_, msg);
+  }
+
+  // Field 3: type
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, type_, msg);
+  }
+
+  // Field 4: name
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+CommitDataRequest::CommitDataRequest() = default;
+CommitDataRequest::~CommitDataRequest() = default;
+CommitDataRequest::CommitDataRequest(const CommitDataRequest&) = default;
+CommitDataRequest& CommitDataRequest::operator=(const CommitDataRequest&) = default;
+CommitDataRequest::CommitDataRequest(CommitDataRequest&&) noexcept = default;
+CommitDataRequest& CommitDataRequest::operator=(CommitDataRequest&&) = default;
+
+bool CommitDataRequest::operator==(const CommitDataRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_to_move_, other.chunks_to_move_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_to_patch_, other.chunks_to_patch_)
+   && ::protozero::internal::gen_helpers::EqualsField(flush_request_id_, other.flush_request_id_);
+}
+
+int CommitDataRequest::chunks_to_move_size() const { return static_cast<int>(chunks_to_move_.size()); }
+void CommitDataRequest::clear_chunks_to_move() { chunks_to_move_.clear(); }
+CommitDataRequest_ChunksToMove* CommitDataRequest::add_chunks_to_move() { chunks_to_move_.emplace_back(); return &chunks_to_move_.back(); }
+int CommitDataRequest::chunks_to_patch_size() const { return static_cast<int>(chunks_to_patch_.size()); }
+void CommitDataRequest::clear_chunks_to_patch() { chunks_to_patch_.clear(); }
+CommitDataRequest_ChunkToPatch* CommitDataRequest::add_chunks_to_patch() { chunks_to_patch_.emplace_back(); return &chunks_to_patch_.back(); }
+bool CommitDataRequest::ParseFromArray(const void* raw, size_t size) {
+  chunks_to_move_.clear();
+  chunks_to_patch_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* chunks_to_move */:
+        chunks_to_move_.emplace_back();
+        chunks_to_move_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* chunks_to_patch */:
+        chunks_to_patch_.emplace_back();
+        chunks_to_patch_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* flush_request_id */:
+        field.get(&flush_request_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: chunks_to_move
+  for (auto& it : chunks_to_move_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: chunks_to_patch
+  for (auto& it : chunks_to_patch_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: flush_request_id
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, flush_request_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch() = default;
+CommitDataRequest_ChunkToPatch::~CommitDataRequest_ChunkToPatch() = default;
+CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&) = default;
+CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(const CommitDataRequest_ChunkToPatch&) = default;
+CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept = default;
+CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(CommitDataRequest_ChunkToPatch&&) = default;
+
+bool CommitDataRequest_ChunkToPatch::operator==(const CommitDataRequest_ChunkToPatch& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_)
+   && ::protozero::internal::gen_helpers::EqualsField(writer_id_, other.writer_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunk_id_, other.chunk_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(patches_, other.patches_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_more_patches_, other.has_more_patches_);
+}
+
+int CommitDataRequest_ChunkToPatch::patches_size() const { return static_cast<int>(patches_.size()); }
+void CommitDataRequest_ChunkToPatch::clear_patches() { patches_.clear(); }
+CommitDataRequest_ChunkToPatch_Patch* CommitDataRequest_ChunkToPatch::add_patches() { patches_.emplace_back(); return &patches_.back(); }
+bool CommitDataRequest_ChunkToPatch::ParseFromArray(const void* raw, size_t size) {
+  patches_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* target_buffer */:
+        field.get(&target_buffer_);
+        break;
+      case 2 /* writer_id */:
+        field.get(&writer_id_);
+        break;
+      case 3 /* chunk_id */:
+        field.get(&chunk_id_);
+        break;
+      case 4 /* patches */:
+        patches_.emplace_back();
+        patches_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* has_more_patches */:
+        field.get(&has_more_patches_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataRequest_ChunkToPatch::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest_ChunkToPatch::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest_ChunkToPatch::Serialize(::protozero::Message* msg) const {
+  // Field 1: target_buffer
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, target_buffer_, msg);
+  }
+
+  // Field 2: writer_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, writer_id_, msg);
+  }
+
+  // Field 3: chunk_id
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, chunk_id_, msg);
+  }
+
+  // Field 4: patches
+  for (auto& it : patches_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: has_more_patches
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, has_more_patches_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch() = default;
+CommitDataRequest_ChunkToPatch_Patch::~CommitDataRequest_ChunkToPatch_Patch() = default;
+CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&) = default;
+CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(const CommitDataRequest_ChunkToPatch_Patch&) = default;
+CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept = default;
+CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(CommitDataRequest_ChunkToPatch_Patch&&) = default;
+
+bool CommitDataRequest_ChunkToPatch_Patch::operator==(const CommitDataRequest_ChunkToPatch_Patch& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(offset_, other.offset_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_, other.data_);
+}
+
+bool CommitDataRequest_ChunkToPatch_Patch::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* offset */:
+        field.get(&offset_);
+        break;
+      case 2 /* data */:
+        field.get(&data_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataRequest_ChunkToPatch_Patch::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest_ChunkToPatch_Patch::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest_ChunkToPatch_Patch::Serialize(::protozero::Message* msg) const {
+  // Field 1: offset
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, offset_, msg);
+  }
+
+  // Field 2: data
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, data_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove() = default;
+CommitDataRequest_ChunksToMove::~CommitDataRequest_ChunksToMove() = default;
+CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&) = default;
+CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(const CommitDataRequest_ChunksToMove&) = default;
+CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept = default;
+CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(CommitDataRequest_ChunksToMove&&) = default;
+
+bool CommitDataRequest_ChunksToMove::operator==(const CommitDataRequest_ChunksToMove& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(page_, other.page_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunk_, other.chunk_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_, other.data_);
+}
+
+bool CommitDataRequest_ChunksToMove::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* page */:
+        field.get(&page_);
+        break;
+      case 2 /* chunk */:
+        field.get(&chunk_);
+        break;
+      case 3 /* target_buffer */:
+        field.get(&target_buffer_);
+        break;
+      case 4 /* data */:
+        field.get(&data_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataRequest_ChunksToMove::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataRequest_ChunksToMove::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataRequest_ChunksToMove::Serialize(::protozero::Message* msg) const {
+  // Field 1: page
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, page_, msg);
+  }
+
+  // Field 2: chunk
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, chunk_, msg);
+  }
+
+  // Field 3: target_buffer
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, target_buffer_, msg);
+  }
+
+  // Field 4: data
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, data_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+DataSourceDescriptor::DataSourceDescriptor() = default;
+DataSourceDescriptor::~DataSourceDescriptor() = default;
+DataSourceDescriptor::DataSourceDescriptor(const DataSourceDescriptor&) = default;
+DataSourceDescriptor& DataSourceDescriptor::operator=(const DataSourceDescriptor&) = default;
+DataSourceDescriptor::DataSourceDescriptor(DataSourceDescriptor&&) noexcept = default;
+DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) = default;
+
+bool DataSourceDescriptor::operator==(const DataSourceDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
+   && ::protozero::internal::gen_helpers::EqualsField(will_notify_on_stop_, other.will_notify_on_stop_)
+   && ::protozero::internal::gen_helpers::EqualsField(will_notify_on_start_, other.will_notify_on_start_)
+   && ::protozero::internal::gen_helpers::EqualsField(handles_incremental_state_clear_, other.handles_incremental_state_clear_)
+   && ::protozero::internal::gen_helpers::EqualsField(no_flush_, other.no_flush_)
+   && ::protozero::internal::gen_helpers::EqualsField(gpu_counter_descriptor_, other.gpu_counter_descriptor_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_event_descriptor_, other.track_event_descriptor_)
+   && ::protozero::internal::gen_helpers::EqualsField(ftrace_descriptor_, other.ftrace_descriptor_);
+}
+
+bool DataSourceDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 7 /* id */:
+        field.get(&id_);
+        break;
+      case 2 /* will_notify_on_stop */:
+        field.get(&will_notify_on_stop_);
+        break;
+      case 3 /* will_notify_on_start */:
+        field.get(&will_notify_on_start_);
+        break;
+      case 4 /* handles_incremental_state_clear */:
+        field.get(&handles_incremental_state_clear_);
+        break;
+      case 9 /* no_flush */:
+        field.get(&no_flush_);
+        break;
+      case 5 /* gpu_counter_descriptor */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &gpu_counter_descriptor_);
+        break;
+      case 6 /* track_event_descriptor */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &track_event_descriptor_);
+        break;
+      case 8 /* ftrace_descriptor */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &ftrace_descriptor_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DataSourceDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DataSourceDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DataSourceDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 7: id
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, id_, msg);
+  }
+
+  // Field 2: will_notify_on_stop
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, will_notify_on_stop_, msg);
+  }
+
+  // Field 3: will_notify_on_start
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, will_notify_on_start_, msg);
+  }
+
+  // Field 4: handles_incremental_state_clear
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, handles_incremental_state_clear_, msg);
+  }
+
+  // Field 9: no_flush
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, no_flush_, msg);
+  }
+
+  // Field 5: gpu_counter_descriptor
+  if (_has_field_[5]) {
+    msg->AppendString(5, gpu_counter_descriptor_);
+  }
+
+  // Field 6: track_event_descriptor
+  if (_has_field_[6]) {
+    msg->AppendString(6, track_event_descriptor_);
+  }
+
+  // Field 8: ftrace_descriptor
+  if (_has_field_[8]) {
+    msg->AppendString(8, ftrace_descriptor_);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+OneofOptions::OneofOptions() = default;
+OneofOptions::~OneofOptions() = default;
+OneofOptions::OneofOptions(const OneofOptions&) = default;
+OneofOptions& OneofOptions::operator=(const OneofOptions&) = default;
+OneofOptions::OneofOptions(OneofOptions&&) noexcept = default;
+OneofOptions& OneofOptions::operator=(OneofOptions&&) = default;
+
+bool OneofOptions::operator==(const OneofOptions& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool OneofOptions::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string OneofOptions::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> OneofOptions::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void OneofOptions::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+EnumValueDescriptorProto::EnumValueDescriptorProto() = default;
+EnumValueDescriptorProto::~EnumValueDescriptorProto() = default;
+EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto&) = default;
+EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(const EnumValueDescriptorProto&) = default;
+EnumValueDescriptorProto::EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept = default;
+EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(EnumValueDescriptorProto&&) = default;
+
+bool EnumValueDescriptorProto::operator==(const EnumValueDescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(number_, other.number_);
+}
+
+bool EnumValueDescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* number */:
+        field.get(&number_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EnumValueDescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnumValueDescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnumValueDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: number
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, number_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+EnumDescriptorProto::EnumDescriptorProto() = default;
+EnumDescriptorProto::~EnumDescriptorProto() = default;
+EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto&) = default;
+EnumDescriptorProto& EnumDescriptorProto::operator=(const EnumDescriptorProto&) = default;
+EnumDescriptorProto::EnumDescriptorProto(EnumDescriptorProto&&) noexcept = default;
+EnumDescriptorProto& EnumDescriptorProto::operator=(EnumDescriptorProto&&) = default;
+
+bool EnumDescriptorProto::operator==(const EnumDescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(value_, other.value_)
+   && ::protozero::internal::gen_helpers::EqualsField(reserved_name_, other.reserved_name_);
+}
+
+int EnumDescriptorProto::value_size() const { return static_cast<int>(value_.size()); }
+void EnumDescriptorProto::clear_value() { value_.clear(); }
+EnumValueDescriptorProto* EnumDescriptorProto::add_value() { value_.emplace_back(); return &value_.back(); }
+bool EnumDescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  value_.clear();
+  reserved_name_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* value */:
+        value_.emplace_back();
+        value_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* reserved_name */:
+        reserved_name_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &reserved_name_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EnumDescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnumDescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnumDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: value
+  for (auto& it : value_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 5: reserved_name
+  for (auto& it : reserved_name_) {
+    ::protozero::internal::gen_helpers::SerializeString(5, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+OneofDescriptorProto::OneofDescriptorProto() = default;
+OneofDescriptorProto::~OneofDescriptorProto() = default;
+OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto&) = default;
+OneofDescriptorProto& OneofDescriptorProto::operator=(const OneofDescriptorProto&) = default;
+OneofDescriptorProto::OneofDescriptorProto(OneofDescriptorProto&&) noexcept = default;
+OneofDescriptorProto& OneofDescriptorProto::operator=(OneofDescriptorProto&&) = default;
+
+bool OneofDescriptorProto::operator==(const OneofDescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(options_, other.options_);
+}
+
+bool OneofDescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* options */:
+        (*options_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string OneofDescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> OneofDescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void OneofDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: options
+  if (_has_field_[2]) {
+    (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FieldDescriptorProto::FieldDescriptorProto() = default;
+FieldDescriptorProto::~FieldDescriptorProto() = default;
+FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto&) = default;
+FieldDescriptorProto& FieldDescriptorProto::operator=(const FieldDescriptorProto&) = default;
+FieldDescriptorProto::FieldDescriptorProto(FieldDescriptorProto&&) noexcept = default;
+FieldDescriptorProto& FieldDescriptorProto::operator=(FieldDescriptorProto&&) = default;
+
+bool FieldDescriptorProto::operator==(const FieldDescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(number_, other.number_)
+   && ::protozero::internal::gen_helpers::EqualsField(label_, other.label_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_name_, other.type_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(extendee_, other.extendee_)
+   && ::protozero::internal::gen_helpers::EqualsField(default_value_, other.default_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(options_, other.options_)
+   && ::protozero::internal::gen_helpers::EqualsField(oneof_index_, other.oneof_index_);
+}
+
+bool FieldDescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 3 /* number */:
+        field.get(&number_);
+        break;
+      case 4 /* label */:
+        field.get(&label_);
+        break;
+      case 5 /* type */:
+        field.get(&type_);
+        break;
+      case 6 /* type_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &type_name_);
+        break;
+      case 2 /* extendee */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &extendee_);
+        break;
+      case 7 /* default_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &default_value_);
+        break;
+      case 8 /* options */:
+        (*options_).ParseFromArray(field.data(), field.size());
+        break;
+      case 9 /* oneof_index */:
+        field.get(&oneof_index_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FieldDescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FieldDescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FieldDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 3: number
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, number_, msg);
+  }
+
+  // Field 4: label
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, label_, msg);
+  }
+
+  // Field 5: type
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, type_, msg);
+  }
+
+  // Field 6: type_name
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeString(6, type_name_, msg);
+  }
+
+  // Field 2: extendee
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, extendee_, msg);
+  }
+
+  // Field 7: default_value
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeString(7, default_value_, msg);
+  }
+
+  // Field 8: options
+  if (_has_field_[8]) {
+    (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 9: oneof_index
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, oneof_index_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FieldOptions::FieldOptions() = default;
+FieldOptions::~FieldOptions() = default;
+FieldOptions::FieldOptions(const FieldOptions&) = default;
+FieldOptions& FieldOptions::operator=(const FieldOptions&) = default;
+FieldOptions::FieldOptions(FieldOptions&&) noexcept = default;
+FieldOptions& FieldOptions::operator=(FieldOptions&&) = default;
+
+bool FieldOptions::operator==(const FieldOptions& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(packed_, other.packed_)
+   && ::protozero::internal::gen_helpers::EqualsField(uninterpreted_option_, other.uninterpreted_option_);
+}
+
+int FieldOptions::uninterpreted_option_size() const { return static_cast<int>(uninterpreted_option_.size()); }
+void FieldOptions::clear_uninterpreted_option() { uninterpreted_option_.clear(); }
+UninterpretedOption* FieldOptions::add_uninterpreted_option() { uninterpreted_option_.emplace_back(); return &uninterpreted_option_.back(); }
+bool FieldOptions::ParseFromArray(const void* raw, size_t size) {
+  uninterpreted_option_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 2 /* packed */:
+        field.get(&packed_);
+        break;
+      case 999 /* uninterpreted_option */:
+        uninterpreted_option_.emplace_back();
+        uninterpreted_option_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FieldOptions::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FieldOptions::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FieldOptions::Serialize(::protozero::Message* msg) const {
+  // Field 2: packed
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, packed_, msg);
+  }
+
+  // Field 999: uninterpreted_option
+  for (auto& it : uninterpreted_option_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(999));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UninterpretedOption::UninterpretedOption() = default;
+UninterpretedOption::~UninterpretedOption() = default;
+UninterpretedOption::UninterpretedOption(const UninterpretedOption&) = default;
+UninterpretedOption& UninterpretedOption::operator=(const UninterpretedOption&) = default;
+UninterpretedOption::UninterpretedOption(UninterpretedOption&&) noexcept = default;
+UninterpretedOption& UninterpretedOption::operator=(UninterpretedOption&&) = default;
+
+bool UninterpretedOption::operator==(const UninterpretedOption& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(identifier_value_, other.identifier_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(positive_int_value_, other.positive_int_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(negative_int_value_, other.negative_int_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(double_value_, other.double_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(string_value_, other.string_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(aggregate_value_, other.aggregate_value_);
+}
+
+int UninterpretedOption::name_size() const { return static_cast<int>(name_.size()); }
+void UninterpretedOption::clear_name() { name_.clear(); }
+UninterpretedOption_NamePart* UninterpretedOption::add_name() { name_.emplace_back(); return &name_.back(); }
+bool UninterpretedOption::ParseFromArray(const void* raw, size_t size) {
+  name_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 2 /* name */:
+        name_.emplace_back();
+        name_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* identifier_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &identifier_value_);
+        break;
+      case 4 /* positive_int_value */:
+        field.get(&positive_int_value_);
+        break;
+      case 5 /* negative_int_value */:
+        field.get(&negative_int_value_);
+        break;
+      case 6 /* double_value */:
+        field.get(&double_value_);
+        break;
+      case 7 /* string_value */:
+        field.get(&string_value_);
+        break;
+      case 8 /* aggregate_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &aggregate_value_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UninterpretedOption::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UninterpretedOption::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UninterpretedOption::Serialize(::protozero::Message* msg) const {
+  // Field 2: name
+  for (auto& it : name_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: identifier_value
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, identifier_value_, msg);
+  }
+
+  // Field 4: positive_int_value
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, positive_int_value_, msg);
+  }
+
+  // Field 5: negative_int_value
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, negative_int_value_, msg);
+  }
+
+  // Field 6: double_value
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(6, double_value_, msg);
+  }
+
+  // Field 7: string_value
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeString(7, string_value_, msg);
+  }
+
+  // Field 8: aggregate_value
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeString(8, aggregate_value_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UninterpretedOption_NamePart::UninterpretedOption_NamePart() = default;
+UninterpretedOption_NamePart::~UninterpretedOption_NamePart() = default;
+UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart&) = default;
+UninterpretedOption_NamePart& UninterpretedOption_NamePart::operator=(const UninterpretedOption_NamePart&) = default;
+UninterpretedOption_NamePart::UninterpretedOption_NamePart(UninterpretedOption_NamePart&&) noexcept = default;
+UninterpretedOption_NamePart& UninterpretedOption_NamePart::operator=(UninterpretedOption_NamePart&&) = default;
+
+bool UninterpretedOption_NamePart::operator==(const UninterpretedOption_NamePart& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_part_, other.name_part_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_extension_, other.is_extension_);
+}
+
+bool UninterpretedOption_NamePart::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name_part */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_part_);
+        break;
+      case 2 /* is_extension */:
+        field.get(&is_extension_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UninterpretedOption_NamePart::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UninterpretedOption_NamePart::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UninterpretedOption_NamePart::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_part
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_part_, msg);
+  }
+
+  // Field 2: is_extension
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, is_extension_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DescriptorProto::DescriptorProto() = default;
+DescriptorProto::~DescriptorProto() = default;
+DescriptorProto::DescriptorProto(const DescriptorProto&) = default;
+DescriptorProto& DescriptorProto::operator=(const DescriptorProto&) = default;
+DescriptorProto::DescriptorProto(DescriptorProto&&) noexcept = default;
+DescriptorProto& DescriptorProto::operator=(DescriptorProto&&) = default;
+
+bool DescriptorProto::operator==(const DescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_, other.field_)
+   && ::protozero::internal::gen_helpers::EqualsField(extension_, other.extension_)
+   && ::protozero::internal::gen_helpers::EqualsField(nested_type_, other.nested_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(enum_type_, other.enum_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(oneof_decl_, other.oneof_decl_)
+   && ::protozero::internal::gen_helpers::EqualsField(reserved_range_, other.reserved_range_)
+   && ::protozero::internal::gen_helpers::EqualsField(reserved_name_, other.reserved_name_);
+}
+
+int DescriptorProto::field_size() const { return static_cast<int>(field_.size()); }
+void DescriptorProto::clear_field() { field_.clear(); }
+FieldDescriptorProto* DescriptorProto::add_field() { field_.emplace_back(); return &field_.back(); }
+int DescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
+void DescriptorProto::clear_extension() { extension_.clear(); }
+FieldDescriptorProto* DescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
+int DescriptorProto::nested_type_size() const { return static_cast<int>(nested_type_.size()); }
+void DescriptorProto::clear_nested_type() { nested_type_.clear(); }
+DescriptorProto* DescriptorProto::add_nested_type() { nested_type_.emplace_back(); return &nested_type_.back(); }
+int DescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
+void DescriptorProto::clear_enum_type() { enum_type_.clear(); }
+EnumDescriptorProto* DescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
+int DescriptorProto::oneof_decl_size() const { return static_cast<int>(oneof_decl_.size()); }
+void DescriptorProto::clear_oneof_decl() { oneof_decl_.clear(); }
+OneofDescriptorProto* DescriptorProto::add_oneof_decl() { oneof_decl_.emplace_back(); return &oneof_decl_.back(); }
+int DescriptorProto::reserved_range_size() const { return static_cast<int>(reserved_range_.size()); }
+void DescriptorProto::clear_reserved_range() { reserved_range_.clear(); }
+DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { reserved_range_.emplace_back(); return &reserved_range_.back(); }
+bool DescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  field_.clear();
+  extension_.clear();
+  nested_type_.clear();
+  enum_type_.clear();
+  oneof_decl_.clear();
+  reserved_range_.clear();
+  reserved_name_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* field */:
+        field_.emplace_back();
+        field_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* extension */:
+        extension_.emplace_back();
+        extension_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* nested_type */:
+        nested_type_.emplace_back();
+        nested_type_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* enum_type */:
+        enum_type_.emplace_back();
+        enum_type_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* oneof_decl */:
+        oneof_decl_.emplace_back();
+        oneof_decl_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 9 /* reserved_range */:
+        reserved_range_.emplace_back();
+        reserved_range_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 10 /* reserved_name */:
+        reserved_name_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &reserved_name_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: field
+  for (auto& it : field_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 6: extension
+  for (auto& it : extension_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 3: nested_type
+  for (auto& it : nested_type_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: enum_type
+  for (auto& it : enum_type_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 8: oneof_decl
+  for (auto& it : oneof_decl_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 9: reserved_range
+  for (auto& it : reserved_range_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(9));
+  }
+
+  // Field 10: reserved_name
+  for (auto& it : reserved_name_) {
+    ::protozero::internal::gen_helpers::SerializeString(10, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() = default;
+DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() = default;
+DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&) = default;
+DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(const DescriptorProto_ReservedRange&) = default;
+DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept = default;
+DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(DescriptorProto_ReservedRange&&) = default;
+
+bool DescriptorProto_ReservedRange::operator==(const DescriptorProto_ReservedRange& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_, other.start_)
+   && ::protozero::internal::gen_helpers::EqualsField(end_, other.end_);
+}
+
+bool DescriptorProto_ReservedRange::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* start */:
+        field.get(&start_);
+        break;
+      case 2 /* end */:
+        field.get(&end_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DescriptorProto_ReservedRange::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DescriptorProto_ReservedRange::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DescriptorProto_ReservedRange::Serialize(::protozero::Message* msg) const {
+  // Field 1: start
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, start_, msg);
+  }
+
+  // Field 2: end
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, end_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FileDescriptorProto::FileDescriptorProto() = default;
+FileDescriptorProto::~FileDescriptorProto() = default;
+FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto&) = default;
+FileDescriptorProto& FileDescriptorProto::operator=(const FileDescriptorProto&) = default;
+FileDescriptorProto::FileDescriptorProto(FileDescriptorProto&&) noexcept = default;
+FileDescriptorProto& FileDescriptorProto::operator=(FileDescriptorProto&&) = default;
+
+bool FileDescriptorProto::operator==(const FileDescriptorProto& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(package_, other.package_)
+   && ::protozero::internal::gen_helpers::EqualsField(dependency_, other.dependency_)
+   && ::protozero::internal::gen_helpers::EqualsField(public_dependency_, other.public_dependency_)
+   && ::protozero::internal::gen_helpers::EqualsField(weak_dependency_, other.weak_dependency_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_type_, other.message_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(enum_type_, other.enum_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(extension_, other.extension_);
+}
+
+int FileDescriptorProto::message_type_size() const { return static_cast<int>(message_type_.size()); }
+void FileDescriptorProto::clear_message_type() { message_type_.clear(); }
+DescriptorProto* FileDescriptorProto::add_message_type() { message_type_.emplace_back(); return &message_type_.back(); }
+int FileDescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
+void FileDescriptorProto::clear_enum_type() { enum_type_.clear(); }
+EnumDescriptorProto* FileDescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
+int FileDescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
+void FileDescriptorProto::clear_extension() { extension_.clear(); }
+FieldDescriptorProto* FileDescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
+bool FileDescriptorProto::ParseFromArray(const void* raw, size_t size) {
+  dependency_.clear();
+  public_dependency_.clear();
+  weak_dependency_.clear();
+  message_type_.clear();
+  enum_type_.clear();
+  extension_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* package */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &package_);
+        break;
+      case 3 /* dependency */:
+        dependency_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &dependency_.back());
+        break;
+      case 10 /* public_dependency */:
+        public_dependency_.emplace_back();
+        field.get(&public_dependency_.back());
+        break;
+      case 11 /* weak_dependency */:
+        weak_dependency_.emplace_back();
+        field.get(&weak_dependency_.back());
+        break;
+      case 4 /* message_type */:
+        message_type_.emplace_back();
+        message_type_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* enum_type */:
+        enum_type_.emplace_back();
+        enum_type_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* extension */:
+        extension_.emplace_back();
+        extension_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FileDescriptorProto::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FileDescriptorProto::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FileDescriptorProto::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: package
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, package_, msg);
+  }
+
+  // Field 3: dependency
+  for (auto& it : dependency_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  // Field 10: public_dependency
+  for (auto& it : public_dependency_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, it, msg);
+  }
+
+  // Field 11: weak_dependency
+  for (auto& it : weak_dependency_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, it, msg);
+  }
+
+  // Field 4: message_type
+  for (auto& it : message_type_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: enum_type
+  for (auto& it : enum_type_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 7: extension
+  for (auto& it : extension_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FileDescriptorSet::FileDescriptorSet() = default;
+FileDescriptorSet::~FileDescriptorSet() = default;
+FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet&) = default;
+FileDescriptorSet& FileDescriptorSet::operator=(const FileDescriptorSet&) = default;
+FileDescriptorSet::FileDescriptorSet(FileDescriptorSet&&) noexcept = default;
+FileDescriptorSet& FileDescriptorSet::operator=(FileDescriptorSet&&) = default;
+
+bool FileDescriptorSet::operator==(const FileDescriptorSet& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(file_, other.file_);
+}
+
+int FileDescriptorSet::file_size() const { return static_cast<int>(file_.size()); }
+void FileDescriptorSet::clear_file() { file_.clear(); }
+FileDescriptorProto* FileDescriptorSet::add_file() { file_.emplace_back(); return &file_.back(); }
+bool FileDescriptorSet::ParseFromArray(const void* raw, size_t size) {
+  file_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* file */:
+        file_.emplace_back();
+        file_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FileDescriptorSet::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FileDescriptorSet::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FileDescriptorSet::Serialize(::protozero::Message* msg) const {
+  // Field 1: file
+  for (auto& it : file_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/ftrace_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+FtraceDescriptor::FtraceDescriptor() = default;
+FtraceDescriptor::~FtraceDescriptor() = default;
+FtraceDescriptor::FtraceDescriptor(const FtraceDescriptor&) = default;
+FtraceDescriptor& FtraceDescriptor::operator=(const FtraceDescriptor&) = default;
+FtraceDescriptor::FtraceDescriptor(FtraceDescriptor&&) noexcept = default;
+FtraceDescriptor& FtraceDescriptor::operator=(FtraceDescriptor&&) = default;
+
+bool FtraceDescriptor::operator==(const FtraceDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(atrace_categories_, other.atrace_categories_);
+}
+
+int FtraceDescriptor::atrace_categories_size() const { return static_cast<int>(atrace_categories_.size()); }
+void FtraceDescriptor::clear_atrace_categories() { atrace_categories_.clear(); }
+FtraceDescriptor_AtraceCategory* FtraceDescriptor::add_atrace_categories() { atrace_categories_.emplace_back(); return &atrace_categories_.back(); }
+bool FtraceDescriptor::ParseFromArray(const void* raw, size_t size) {
+  atrace_categories_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* atrace_categories */:
+        atrace_categories_.emplace_back();
+        atrace_categories_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: atrace_categories
+  for (auto& it : atrace_categories_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FtraceDescriptor_AtraceCategory::FtraceDescriptor_AtraceCategory() = default;
+FtraceDescriptor_AtraceCategory::~FtraceDescriptor_AtraceCategory() = default;
+FtraceDescriptor_AtraceCategory::FtraceDescriptor_AtraceCategory(const FtraceDescriptor_AtraceCategory&) = default;
+FtraceDescriptor_AtraceCategory& FtraceDescriptor_AtraceCategory::operator=(const FtraceDescriptor_AtraceCategory&) = default;
+FtraceDescriptor_AtraceCategory::FtraceDescriptor_AtraceCategory(FtraceDescriptor_AtraceCategory&&) noexcept = default;
+FtraceDescriptor_AtraceCategory& FtraceDescriptor_AtraceCategory::operator=(FtraceDescriptor_AtraceCategory&&) = default;
+
+bool FtraceDescriptor_AtraceCategory::operator==(const FtraceDescriptor_AtraceCategory& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_);
+}
+
+bool FtraceDescriptor_AtraceCategory::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* description */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceDescriptor_AtraceCategory::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceDescriptor_AtraceCategory::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceDescriptor_AtraceCategory::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: description
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, description_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+GpuCounterDescriptor::GpuCounterDescriptor() = default;
+GpuCounterDescriptor::~GpuCounterDescriptor() = default;
+GpuCounterDescriptor::GpuCounterDescriptor(const GpuCounterDescriptor&) = default;
+GpuCounterDescriptor& GpuCounterDescriptor::operator=(const GpuCounterDescriptor&) = default;
+GpuCounterDescriptor::GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept = default;
+GpuCounterDescriptor& GpuCounterDescriptor::operator=(GpuCounterDescriptor&&) = default;
+
+bool GpuCounterDescriptor::operator==(const GpuCounterDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(specs_, other.specs_)
+   && ::protozero::internal::gen_helpers::EqualsField(blocks_, other.blocks_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_sampling_period_ns_, other.min_sampling_period_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_sampling_period_ns_, other.max_sampling_period_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(supports_instrumented_sampling_, other.supports_instrumented_sampling_);
+}
+
+int GpuCounterDescriptor::specs_size() const { return static_cast<int>(specs_.size()); }
+void GpuCounterDescriptor::clear_specs() { specs_.clear(); }
+GpuCounterDescriptor_GpuCounterSpec* GpuCounterDescriptor::add_specs() { specs_.emplace_back(); return &specs_.back(); }
+int GpuCounterDescriptor::blocks_size() const { return static_cast<int>(blocks_.size()); }
+void GpuCounterDescriptor::clear_blocks() { blocks_.clear(); }
+GpuCounterDescriptor_GpuCounterBlock* GpuCounterDescriptor::add_blocks() { blocks_.emplace_back(); return &blocks_.back(); }
+bool GpuCounterDescriptor::ParseFromArray(const void* raw, size_t size) {
+  specs_.clear();
+  blocks_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* specs */:
+        specs_.emplace_back();
+        specs_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* blocks */:
+        blocks_.emplace_back();
+        blocks_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* min_sampling_period_ns */:
+        field.get(&min_sampling_period_ns_);
+        break;
+      case 4 /* max_sampling_period_ns */:
+        field.get(&max_sampling_period_ns_);
+        break;
+      case 5 /* supports_instrumented_sampling */:
+        field.get(&supports_instrumented_sampling_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GpuCounterDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: specs
+  for (auto& it : specs_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: blocks
+  for (auto& it : blocks_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: min_sampling_period_ns
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, min_sampling_period_ns_, msg);
+  }
+
+  // Field 4: max_sampling_period_ns
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, max_sampling_period_ns_, msg);
+  }
+
+  // Field 5: supports_instrumented_sampling
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, supports_instrumented_sampling_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock() = default;
+GpuCounterDescriptor_GpuCounterBlock::~GpuCounterDescriptor_GpuCounterBlock() = default;
+GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&) = default;
+GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(const GpuCounterDescriptor_GpuCounterBlock&) = default;
+GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept = default;
+GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(GpuCounterDescriptor_GpuCounterBlock&&) = default;
+
+bool GpuCounterDescriptor_GpuCounterBlock::operator==(const GpuCounterDescriptor_GpuCounterBlock& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(block_id_, other.block_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(block_capacity_, other.block_capacity_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_ids_, other.counter_ids_);
+}
+
+bool GpuCounterDescriptor_GpuCounterBlock::ParseFromArray(const void* raw, size_t size) {
+  counter_ids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* block_id */:
+        field.get(&block_id_);
+        break;
+      case 2 /* block_capacity */:
+        field.get(&block_capacity_);
+        break;
+      case 3 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 4 /* description */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
+        break;
+      case 5 /* counter_ids */:
+        counter_ids_.emplace_back();
+        field.get(&counter_ids_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GpuCounterDescriptor_GpuCounterBlock::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterDescriptor_GpuCounterBlock::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterDescriptor_GpuCounterBlock::Serialize(::protozero::Message* msg) const {
+  // Field 1: block_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, block_id_, msg);
+  }
+
+  // Field 2: block_capacity
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, block_capacity_, msg);
+  }
+
+  // Field 3: name
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, name_, msg);
+  }
+
+  // Field 4: description
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, description_, msg);
+  }
+
+  // Field 5: counter_ids
+  for (auto& it : counter_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec() = default;
+GpuCounterDescriptor_GpuCounterSpec::~GpuCounterDescriptor_GpuCounterSpec() = default;
+GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&) = default;
+GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(const GpuCounterDescriptor_GpuCounterSpec&) = default;
+GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept = default;
+GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(GpuCounterDescriptor_GpuCounterSpec&&) = default;
+
+bool GpuCounterDescriptor_GpuCounterSpec::operator==(const GpuCounterDescriptor_GpuCounterSpec& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_id_, other.counter_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_)
+   && ::protozero::internal::gen_helpers::EqualsField(int_peak_value_, other.int_peak_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(double_peak_value_, other.double_peak_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(numerator_units_, other.numerator_units_)
+   && ::protozero::internal::gen_helpers::EqualsField(denominator_units_, other.denominator_units_)
+   && ::protozero::internal::gen_helpers::EqualsField(select_by_default_, other.select_by_default_)
+   && ::protozero::internal::gen_helpers::EqualsField(groups_, other.groups_);
+}
+
+bool GpuCounterDescriptor_GpuCounterSpec::ParseFromArray(const void* raw, size_t size) {
+  numerator_units_.clear();
+  denominator_units_.clear();
+  groups_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* counter_id */:
+        field.get(&counter_id_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 3 /* description */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
+        break;
+      case 5 /* int_peak_value */:
+        field.get(&int_peak_value_);
+        break;
+      case 6 /* double_peak_value */:
+        field.get(&double_peak_value_);
+        break;
+      case 7 /* numerator_units */:
+        numerator_units_.emplace_back();
+        field.get(&numerator_units_.back());
+        break;
+      case 8 /* denominator_units */:
+        denominator_units_.emplace_back();
+        field.get(&denominator_units_.back());
+        break;
+      case 9 /* select_by_default */:
+        field.get(&select_by_default_);
+        break;
+      case 10 /* groups */:
+        groups_.emplace_back();
+        field.get(&groups_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GpuCounterDescriptor_GpuCounterSpec::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterDescriptor_GpuCounterSpec::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterDescriptor_GpuCounterSpec::Serialize(::protozero::Message* msg) const {
+  // Field 1: counter_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, counter_id_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  // Field 3: description
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, description_, msg);
+  }
+
+  // Field 5: int_peak_value
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, int_peak_value_, msg);
+  }
+
+  // Field 6: double_peak_value
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(6, double_peak_value_, msg);
+  }
+
+  // Field 7: numerator_units
+  for (auto& it : numerator_units_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, it, msg);
+  }
+
+  // Field 8: denominator_units
+  for (auto& it : denominator_units_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, it, msg);
+  }
+
+  // Field 9: select_by_default
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, select_by_default_, msg);
+  }
+
+  // Field 10: groups
+  for (auto& it : groups_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+InterceptorDescriptor::InterceptorDescriptor() = default;
+InterceptorDescriptor::~InterceptorDescriptor() = default;
+InterceptorDescriptor::InterceptorDescriptor(const InterceptorDescriptor&) = default;
+InterceptorDescriptor& InterceptorDescriptor::operator=(const InterceptorDescriptor&) = default;
+InterceptorDescriptor::InterceptorDescriptor(InterceptorDescriptor&&) noexcept = default;
+InterceptorDescriptor& InterceptorDescriptor::operator=(InterceptorDescriptor&&) = default;
+
+bool InterceptorDescriptor::operator==(const InterceptorDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool InterceptorDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InterceptorDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InterceptorDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InterceptorDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ObservableEvents::ObservableEvents() = default;
+ObservableEvents::~ObservableEvents() = default;
+ObservableEvents::ObservableEvents(const ObservableEvents&) = default;
+ObservableEvents& ObservableEvents::operator=(const ObservableEvents&) = default;
+ObservableEvents::ObservableEvents(ObservableEvents&&) noexcept = default;
+ObservableEvents& ObservableEvents::operator=(ObservableEvents&&) = default;
+
+bool ObservableEvents::operator==(const ObservableEvents& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(instance_state_changes_, other.instance_state_changes_)
+   && ::protozero::internal::gen_helpers::EqualsField(all_data_sources_started_, other.all_data_sources_started_)
+   && ::protozero::internal::gen_helpers::EqualsField(clone_trigger_hit_, other.clone_trigger_hit_);
+}
+
+int ObservableEvents::instance_state_changes_size() const { return static_cast<int>(instance_state_changes_.size()); }
+void ObservableEvents::clear_instance_state_changes() { instance_state_changes_.clear(); }
+ObservableEvents_DataSourceInstanceStateChange* ObservableEvents::add_instance_state_changes() { instance_state_changes_.emplace_back(); return &instance_state_changes_.back(); }
+bool ObservableEvents::ParseFromArray(const void* raw, size_t size) {
+  instance_state_changes_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* instance_state_changes */:
+        instance_state_changes_.emplace_back();
+        instance_state_changes_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* all_data_sources_started */:
+        field.get(&all_data_sources_started_);
+        break;
+      case 3 /* clone_trigger_hit */:
+        (*clone_trigger_hit_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObservableEvents::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObservableEvents::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObservableEvents::Serialize(::protozero::Message* msg) const {
+  // Field 1: instance_state_changes
+  for (auto& it : instance_state_changes_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: all_data_sources_started
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, all_data_sources_started_, msg);
+  }
+
+  // Field 3: clone_trigger_hit
+  if (_has_field_[3]) {
+    (*clone_trigger_hit_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ObservableEvents_CloneTriggerHit::ObservableEvents_CloneTriggerHit() = default;
+ObservableEvents_CloneTriggerHit::~ObservableEvents_CloneTriggerHit() = default;
+ObservableEvents_CloneTriggerHit::ObservableEvents_CloneTriggerHit(const ObservableEvents_CloneTriggerHit&) = default;
+ObservableEvents_CloneTriggerHit& ObservableEvents_CloneTriggerHit::operator=(const ObservableEvents_CloneTriggerHit&) = default;
+ObservableEvents_CloneTriggerHit::ObservableEvents_CloneTriggerHit(ObservableEvents_CloneTriggerHit&&) noexcept = default;
+ObservableEvents_CloneTriggerHit& ObservableEvents_CloneTriggerHit::operator=(ObservableEvents_CloneTriggerHit&&) = default;
+
+bool ObservableEvents_CloneTriggerHit::operator==(const ObservableEvents_CloneTriggerHit& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_session_id_, other.tracing_session_id_);
+}
+
+bool ObservableEvents_CloneTriggerHit::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* tracing_session_id */:
+        field.get(&tracing_session_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObservableEvents_CloneTriggerHit::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObservableEvents_CloneTriggerHit::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObservableEvents_CloneTriggerHit::Serialize(::protozero::Message* msg) const {
+  // Field 1: tracing_session_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, tracing_session_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange() = default;
+ObservableEvents_DataSourceInstanceStateChange::~ObservableEvents_DataSourceInstanceStateChange() = default;
+ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&) = default;
+ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(const ObservableEvents_DataSourceInstanceStateChange&) = default;
+ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept = default;
+ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(ObservableEvents_DataSourceInstanceStateChange&&) = default;
+
+bool ObservableEvents_DataSourceInstanceStateChange::operator==(const ObservableEvents_DataSourceInstanceStateChange& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_, other.producer_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_name_, other.data_source_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_);
+}
+
+bool ObservableEvents_DataSourceInstanceStateChange::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* producer_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_);
+        break;
+      case 2 /* data_source_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &data_source_name_);
+        break;
+      case 3 /* state */:
+        field.get(&state_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObservableEvents_DataSourceInstanceStateChange::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObservableEvents_DataSourceInstanceStateChange::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObservableEvents_DataSourceInstanceStateChange::Serialize(::protozero::Message* msg) const {
+  // Field 1: producer_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, producer_name_, msg);
+  }
+
+  // Field 2: data_source_name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, data_source_name_, msg);
+  }
+
+  // Field 3: state
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, state_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/perf_events.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+PerfEvents::PerfEvents() = default;
+PerfEvents::~PerfEvents() = default;
+PerfEvents::PerfEvents(const PerfEvents&) = default;
+PerfEvents& PerfEvents::operator=(const PerfEvents&) = default;
+PerfEvents::PerfEvents(PerfEvents&&) noexcept = default;
+PerfEvents& PerfEvents::operator=(PerfEvents&&) = default;
+
+bool PerfEvents::operator==(const PerfEvents& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool PerfEvents::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEvents::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+PerfEvents_RawEvent::PerfEvents_RawEvent() = default;
+PerfEvents_RawEvent::~PerfEvents_RawEvent() = default;
+PerfEvents_RawEvent::PerfEvents_RawEvent(const PerfEvents_RawEvent&) = default;
+PerfEvents_RawEvent& PerfEvents_RawEvent::operator=(const PerfEvents_RawEvent&) = default;
+PerfEvents_RawEvent::PerfEvents_RawEvent(PerfEvents_RawEvent&&) noexcept = default;
+PerfEvents_RawEvent& PerfEvents_RawEvent::operator=(PerfEvents_RawEvent&&) = default;
+
+bool PerfEvents_RawEvent::operator==(const PerfEvents_RawEvent& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_)
+   && ::protozero::internal::gen_helpers::EqualsField(config1_, other.config1_)
+   && ::protozero::internal::gen_helpers::EqualsField(config2_, other.config2_);
+}
+
+bool PerfEvents_RawEvent::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* type */:
+        field.get(&type_);
+        break;
+      case 2 /* config */:
+        field.get(&config_);
+        break;
+      case 3 /* config1 */:
+        field.get(&config1_);
+        break;
+      case 4 /* config2 */:
+        field.get(&config2_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEvents_RawEvent::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents_RawEvent::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents_RawEvent::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, type_, msg);
+  }
+
+  // Field 2: config
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, config_, msg);
+  }
+
+  // Field 3: config1
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, config1_, msg);
+  }
+
+  // Field 4: config2
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, config2_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+PerfEvents_Tracepoint::PerfEvents_Tracepoint() = default;
+PerfEvents_Tracepoint::~PerfEvents_Tracepoint() = default;
+PerfEvents_Tracepoint::PerfEvents_Tracepoint(const PerfEvents_Tracepoint&) = default;
+PerfEvents_Tracepoint& PerfEvents_Tracepoint::operator=(const PerfEvents_Tracepoint&) = default;
+PerfEvents_Tracepoint::PerfEvents_Tracepoint(PerfEvents_Tracepoint&&) noexcept = default;
+PerfEvents_Tracepoint& PerfEvents_Tracepoint::operator=(PerfEvents_Tracepoint&&) = default;
+
+bool PerfEvents_Tracepoint::operator==(const PerfEvents_Tracepoint& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(filter_, other.filter_);
+}
+
+bool PerfEvents_Tracepoint::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* filter */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &filter_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEvents_Tracepoint::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents_Tracepoint::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents_Tracepoint::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: filter
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, filter_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+PerfEvents_Timebase::PerfEvents_Timebase() = default;
+PerfEvents_Timebase::~PerfEvents_Timebase() = default;
+PerfEvents_Timebase::PerfEvents_Timebase(const PerfEvents_Timebase&) = default;
+PerfEvents_Timebase& PerfEvents_Timebase::operator=(const PerfEvents_Timebase&) = default;
+PerfEvents_Timebase::PerfEvents_Timebase(PerfEvents_Timebase&&) noexcept = default;
+PerfEvents_Timebase& PerfEvents_Timebase::operator=(PerfEvents_Timebase&&) = default;
+
+bool PerfEvents_Timebase::operator==(const PerfEvents_Timebase& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(frequency_, other.frequency_)
+   && ::protozero::internal::gen_helpers::EqualsField(period_, other.period_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_, other.counter_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracepoint_, other.tracepoint_)
+   && ::protozero::internal::gen_helpers::EqualsField(raw_event_, other.raw_event_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamp_clock_, other.timestamp_clock_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool PerfEvents_Timebase::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 2 /* frequency */:
+        field.get(&frequency_);
+        break;
+      case 1 /* period */:
+        field.get(&period_);
+        break;
+      case 4 /* counter */:
+        field.get(&counter_);
+        break;
+      case 3 /* tracepoint */:
+        (*tracepoint_).ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* raw_event */:
+        (*raw_event_).ParseFromArray(field.data(), field.size());
+        break;
+      case 11 /* timestamp_clock */:
+        field.get(&timestamp_clock_);
+        break;
+      case 10 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEvents_Timebase::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEvents_Timebase::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEvents_Timebase::Serialize(::protozero::Message* msg) const {
+  // Field 2: frequency
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, frequency_, msg);
+  }
+
+  // Field 1: period
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, period_, msg);
+  }
+
+  // Field 4: counter
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, counter_, msg);
+  }
+
+  // Field 3: tracepoint
+  if (_has_field_[3]) {
+    (*tracepoint_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 5: raw_event
+  if (_has_field_[5]) {
+    (*raw_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 11: timestamp_clock
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, timestamp_clock_, msg);
+  }
+
+  // Field 10: name
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeString(10, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TraceStats::TraceStats() = default;
+TraceStats::~TraceStats() = default;
+TraceStats::TraceStats(const TraceStats&) = default;
+TraceStats& TraceStats::operator=(const TraceStats&) = default;
+TraceStats::TraceStats(TraceStats&&) noexcept = default;
+TraceStats& TraceStats::operator=(TraceStats&&) = default;
+
+bool TraceStats::operator==(const TraceStats& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_stats_, other.buffer_stats_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunk_payload_histogram_def_, other.chunk_payload_histogram_def_)
+   && ::protozero::internal::gen_helpers::EqualsField(writer_stats_, other.writer_stats_)
+   && ::protozero::internal::gen_helpers::EqualsField(producers_connected_, other.producers_connected_)
+   && ::protozero::internal::gen_helpers::EqualsField(producers_seen_, other.producers_seen_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_sources_registered_, other.data_sources_registered_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_sources_seen_, other.data_sources_seen_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_sessions_, other.tracing_sessions_)
+   && ::protozero::internal::gen_helpers::EqualsField(total_buffers_, other.total_buffers_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_discarded_, other.chunks_discarded_)
+   && ::protozero::internal::gen_helpers::EqualsField(patches_discarded_, other.patches_discarded_)
+   && ::protozero::internal::gen_helpers::EqualsField(invalid_packets_, other.invalid_packets_)
+   && ::protozero::internal::gen_helpers::EqualsField(filter_stats_, other.filter_stats_)
+   && ::protozero::internal::gen_helpers::EqualsField(flushes_requested_, other.flushes_requested_)
+   && ::protozero::internal::gen_helpers::EqualsField(flushes_succeeded_, other.flushes_succeeded_)
+   && ::protozero::internal::gen_helpers::EqualsField(flushes_failed_, other.flushes_failed_)
+   && ::protozero::internal::gen_helpers::EqualsField(final_flush_outcome_, other.final_flush_outcome_);
+}
+
+int TraceStats::buffer_stats_size() const { return static_cast<int>(buffer_stats_.size()); }
+void TraceStats::clear_buffer_stats() { buffer_stats_.clear(); }
+TraceStats_BufferStats* TraceStats::add_buffer_stats() { buffer_stats_.emplace_back(); return &buffer_stats_.back(); }
+int TraceStats::writer_stats_size() const { return static_cast<int>(writer_stats_.size()); }
+void TraceStats::clear_writer_stats() { writer_stats_.clear(); }
+TraceStats_WriterStats* TraceStats::add_writer_stats() { writer_stats_.emplace_back(); return &writer_stats_.back(); }
+bool TraceStats::ParseFromArray(const void* raw, size_t size) {
+  buffer_stats_.clear();
+  chunk_payload_histogram_def_.clear();
+  writer_stats_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* buffer_stats */:
+        buffer_stats_.emplace_back();
+        buffer_stats_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 17 /* chunk_payload_histogram_def */:
+        chunk_payload_histogram_def_.emplace_back();
+        field.get(&chunk_payload_histogram_def_.back());
+        break;
+      case 18 /* writer_stats */:
+        writer_stats_.emplace_back();
+        writer_stats_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* producers_connected */:
+        field.get(&producers_connected_);
+        break;
+      case 3 /* producers_seen */:
+        field.get(&producers_seen_);
+        break;
+      case 4 /* data_sources_registered */:
+        field.get(&data_sources_registered_);
+        break;
+      case 5 /* data_sources_seen */:
+        field.get(&data_sources_seen_);
+        break;
+      case 6 /* tracing_sessions */:
+        field.get(&tracing_sessions_);
+        break;
+      case 7 /* total_buffers */:
+        field.get(&total_buffers_);
+        break;
+      case 8 /* chunks_discarded */:
+        field.get(&chunks_discarded_);
+        break;
+      case 9 /* patches_discarded */:
+        field.get(&patches_discarded_);
+        break;
+      case 10 /* invalid_packets */:
+        field.get(&invalid_packets_);
+        break;
+      case 11 /* filter_stats */:
+        (*filter_stats_).ParseFromArray(field.data(), field.size());
+        break;
+      case 12 /* flushes_requested */:
+        field.get(&flushes_requested_);
+        break;
+      case 13 /* flushes_succeeded */:
+        field.get(&flushes_succeeded_);
+        break;
+      case 14 /* flushes_failed */:
+        field.get(&flushes_failed_);
+        break;
+      case 15 /* final_flush_outcome */:
+        field.get(&final_flush_outcome_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceStats::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceStats::Serialize(::protozero::Message* msg) const {
+  // Field 1: buffer_stats
+  for (auto& it : buffer_stats_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 17: chunk_payload_histogram_def
+  for (auto& it : chunk_payload_histogram_def_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, it, msg);
+  }
+
+  // Field 18: writer_stats
+  for (auto& it : writer_stats_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(18));
+  }
+
+  // Field 2: producers_connected
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, producers_connected_, msg);
+  }
+
+  // Field 3: producers_seen
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, producers_seen_, msg);
+  }
+
+  // Field 4: data_sources_registered
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, data_sources_registered_, msg);
+  }
+
+  // Field 5: data_sources_seen
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, data_sources_seen_, msg);
+  }
+
+  // Field 6: tracing_sessions
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, tracing_sessions_, msg);
+  }
+
+  // Field 7: total_buffers
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, total_buffers_, msg);
+  }
+
+  // Field 8: chunks_discarded
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, chunks_discarded_, msg);
+  }
+
+  // Field 9: patches_discarded
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, patches_discarded_, msg);
+  }
+
+  // Field 10: invalid_packets
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, invalid_packets_, msg);
+  }
+
+  // Field 11: filter_stats
+  if (_has_field_[11]) {
+    (*filter_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  // Field 12: flushes_requested
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(12, flushes_requested_, msg);
+  }
+
+  // Field 13: flushes_succeeded
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, flushes_succeeded_, msg);
+  }
+
+  // Field 14: flushes_failed
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(14, flushes_failed_, msg);
+  }
+
+  // Field 15: final_flush_outcome
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(15, final_flush_outcome_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceStats_FilterStats::TraceStats_FilterStats() = default;
+TraceStats_FilterStats::~TraceStats_FilterStats() = default;
+TraceStats_FilterStats::TraceStats_FilterStats(const TraceStats_FilterStats&) = default;
+TraceStats_FilterStats& TraceStats_FilterStats::operator=(const TraceStats_FilterStats&) = default;
+TraceStats_FilterStats::TraceStats_FilterStats(TraceStats_FilterStats&&) noexcept = default;
+TraceStats_FilterStats& TraceStats_FilterStats::operator=(TraceStats_FilterStats&&) = default;
+
+bool TraceStats_FilterStats::operator==(const TraceStats_FilterStats& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(input_packets_, other.input_packets_)
+   && ::protozero::internal::gen_helpers::EqualsField(input_bytes_, other.input_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(output_bytes_, other.output_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(errors_, other.errors_)
+   && ::protozero::internal::gen_helpers::EqualsField(time_taken_ns_, other.time_taken_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytes_discarded_per_buffer_, other.bytes_discarded_per_buffer_);
+}
+
+bool TraceStats_FilterStats::ParseFromArray(const void* raw, size_t size) {
+  bytes_discarded_per_buffer_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* input_packets */:
+        field.get(&input_packets_);
+        break;
+      case 2 /* input_bytes */:
+        field.get(&input_bytes_);
+        break;
+      case 3 /* output_bytes */:
+        field.get(&output_bytes_);
+        break;
+      case 4 /* errors */:
+        field.get(&errors_);
+        break;
+      case 5 /* time_taken_ns */:
+        field.get(&time_taken_ns_);
+        break;
+      case 20 /* bytes_discarded_per_buffer */:
+        bytes_discarded_per_buffer_.emplace_back();
+        field.get(&bytes_discarded_per_buffer_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceStats_FilterStats::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats_FilterStats::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceStats_FilterStats::Serialize(::protozero::Message* msg) const {
+  // Field 1: input_packets
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, input_packets_, msg);
+  }
+
+  // Field 2: input_bytes
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, input_bytes_, msg);
+  }
+
+  // Field 3: output_bytes
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, output_bytes_, msg);
+  }
+
+  // Field 4: errors
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, errors_, msg);
+  }
+
+  // Field 5: time_taken_ns
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, time_taken_ns_, msg);
+  }
+
+  // Field 20: bytes_discarded_per_buffer
+  for (auto& it : bytes_discarded_per_buffer_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(20, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceStats_WriterStats::TraceStats_WriterStats() = default;
+TraceStats_WriterStats::~TraceStats_WriterStats() = default;
+TraceStats_WriterStats::TraceStats_WriterStats(const TraceStats_WriterStats&) = default;
+TraceStats_WriterStats& TraceStats_WriterStats::operator=(const TraceStats_WriterStats&) = default;
+TraceStats_WriterStats::TraceStats_WriterStats(TraceStats_WriterStats&&) noexcept = default;
+TraceStats_WriterStats& TraceStats_WriterStats::operator=(TraceStats_WriterStats&&) = default;
+
+bool TraceStats_WriterStats::operator==(const TraceStats_WriterStats& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(sequence_id_, other.sequence_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_, other.buffer_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunk_payload_histogram_counts_, other.chunk_payload_histogram_counts_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunk_payload_histogram_sum_, other.chunk_payload_histogram_sum_);
+}
+
+bool TraceStats_WriterStats::ParseFromArray(const void* raw, size_t size) {
+  chunk_payload_histogram_counts_.clear();
+  chunk_payload_histogram_sum_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* sequence_id */:
+        field.get(&sequence_id_);
+        break;
+      case 4 /* buffer */:
+        field.get(&buffer_);
+        break;
+      case 2 /* chunk_payload_histogram_counts */:
+        if (!::protozero::internal::gen_helpers::DeserializePackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(field, &chunk_payload_histogram_counts_)) {
+          packed_error = true;}
+        break;
+      case 3 /* chunk_payload_histogram_sum */:
+        if (!::protozero::internal::gen_helpers::DeserializePackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t>(field, &chunk_payload_histogram_sum_)) {
+          packed_error = true;}
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceStats_WriterStats::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats_WriterStats::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceStats_WriterStats::Serialize(::protozero::Message* msg) const {
+  // Field 1: sequence_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, sequence_id_, msg);
+  }
+
+  // Field 4: buffer
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, buffer_, msg);
+  }
+
+  // Field 2: chunk_payload_histogram_counts
+  {
+    ::protozero::PackedVarInt pack;
+    for (auto& it : chunk_payload_histogram_counts_)
+      pack.Append(it);
+    msg->AppendBytes(2, pack.data(), pack.size());
+  }
+
+  // Field 3: chunk_payload_histogram_sum
+  {
+    ::protozero::PackedVarInt pack;
+    for (auto& it : chunk_payload_histogram_sum_)
+      pack.Append(it);
+    msg->AppendBytes(3, pack.data(), pack.size());
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceStats_BufferStats::TraceStats_BufferStats() = default;
+TraceStats_BufferStats::~TraceStats_BufferStats() = default;
+TraceStats_BufferStats::TraceStats_BufferStats(const TraceStats_BufferStats&) = default;
+TraceStats_BufferStats& TraceStats_BufferStats::operator=(const TraceStats_BufferStats&) = default;
+TraceStats_BufferStats::TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept = default;
+TraceStats_BufferStats& TraceStats_BufferStats::operator=(TraceStats_BufferStats&&) = default;
+
+bool TraceStats_BufferStats::operator==(const TraceStats_BufferStats& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_, other.buffer_size_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytes_written_, other.bytes_written_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytes_overwritten_, other.bytes_overwritten_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytes_read_, other.bytes_read_)
+   && ::protozero::internal::gen_helpers::EqualsField(padding_bytes_written_, other.padding_bytes_written_)
+   && ::protozero::internal::gen_helpers::EqualsField(padding_bytes_cleared_, other.padding_bytes_cleared_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_written_, other.chunks_written_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_rewritten_, other.chunks_rewritten_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_overwritten_, other.chunks_overwritten_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_discarded_, other.chunks_discarded_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_read_, other.chunks_read_)
+   && ::protozero::internal::gen_helpers::EqualsField(chunks_committed_out_of_order_, other.chunks_committed_out_of_order_)
+   && ::protozero::internal::gen_helpers::EqualsField(write_wrap_count_, other.write_wrap_count_)
+   && ::protozero::internal::gen_helpers::EqualsField(patches_succeeded_, other.patches_succeeded_)
+   && ::protozero::internal::gen_helpers::EqualsField(patches_failed_, other.patches_failed_)
+   && ::protozero::internal::gen_helpers::EqualsField(readaheads_succeeded_, other.readaheads_succeeded_)
+   && ::protozero::internal::gen_helpers::EqualsField(readaheads_failed_, other.readaheads_failed_)
+   && ::protozero::internal::gen_helpers::EqualsField(abi_violations_, other.abi_violations_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_writer_packet_loss_, other.trace_writer_packet_loss_);
+}
+
+bool TraceStats_BufferStats::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 12 /* buffer_size */:
+        field.get(&buffer_size_);
+        break;
+      case 1 /* bytes_written */:
+        field.get(&bytes_written_);
+        break;
+      case 13 /* bytes_overwritten */:
+        field.get(&bytes_overwritten_);
+        break;
+      case 14 /* bytes_read */:
+        field.get(&bytes_read_);
+        break;
+      case 15 /* padding_bytes_written */:
+        field.get(&padding_bytes_written_);
+        break;
+      case 16 /* padding_bytes_cleared */:
+        field.get(&padding_bytes_cleared_);
+        break;
+      case 2 /* chunks_written */:
+        field.get(&chunks_written_);
+        break;
+      case 10 /* chunks_rewritten */:
+        field.get(&chunks_rewritten_);
+        break;
+      case 3 /* chunks_overwritten */:
+        field.get(&chunks_overwritten_);
+        break;
+      case 18 /* chunks_discarded */:
+        field.get(&chunks_discarded_);
+        break;
+      case 17 /* chunks_read */:
+        field.get(&chunks_read_);
+        break;
+      case 11 /* chunks_committed_out_of_order */:
+        field.get(&chunks_committed_out_of_order_);
+        break;
+      case 4 /* write_wrap_count */:
+        field.get(&write_wrap_count_);
+        break;
+      case 5 /* patches_succeeded */:
+        field.get(&patches_succeeded_);
+        break;
+      case 6 /* patches_failed */:
+        field.get(&patches_failed_);
+        break;
+      case 7 /* readaheads_succeeded */:
+        field.get(&readaheads_succeeded_);
+        break;
+      case 8 /* readaheads_failed */:
+        field.get(&readaheads_failed_);
+        break;
+      case 9 /* abi_violations */:
+        field.get(&abi_violations_);
+        break;
+      case 19 /* trace_writer_packet_loss */:
+        field.get(&trace_writer_packet_loss_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceStats_BufferStats::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceStats_BufferStats::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceStats_BufferStats::Serialize(::protozero::Message* msg) const {
+  // Field 12: buffer_size
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(12, buffer_size_, msg);
+  }
+
+  // Field 1: bytes_written
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, bytes_written_, msg);
+  }
+
+  // Field 13: bytes_overwritten
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, bytes_overwritten_, msg);
+  }
+
+  // Field 14: bytes_read
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(14, bytes_read_, msg);
+  }
+
+  // Field 15: padding_bytes_written
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(15, padding_bytes_written_, msg);
+  }
+
+  // Field 16: padding_bytes_cleared
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(16, padding_bytes_cleared_, msg);
+  }
+
+  // Field 2: chunks_written
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, chunks_written_, msg);
+  }
+
+  // Field 10: chunks_rewritten
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, chunks_rewritten_, msg);
+  }
+
+  // Field 3: chunks_overwritten
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, chunks_overwritten_, msg);
+  }
+
+  // Field 18: chunks_discarded
+  if (_has_field_[18]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(18, chunks_discarded_, msg);
+  }
+
+  // Field 17: chunks_read
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, chunks_read_, msg);
+  }
+
+  // Field 11: chunks_committed_out_of_order
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, chunks_committed_out_of_order_, msg);
+  }
+
+  // Field 4: write_wrap_count
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, write_wrap_count_, msg);
+  }
+
+  // Field 5: patches_succeeded
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, patches_succeeded_, msg);
+  }
+
+  // Field 6: patches_failed
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, patches_failed_, msg);
+  }
+
+  // Field 7: readaheads_succeeded
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, readaheads_succeeded_, msg);
+  }
+
+  // Field 8: readaheads_failed
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, readaheads_failed_, msg);
+  }
+
+  // Field 9: abi_violations
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, abi_violations_, msg);
+  }
+
+  // Field 19: trace_writer_packet_loss
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(19, trace_writer_packet_loss_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TracingServiceCapabilities::TracingServiceCapabilities() = default;
+TracingServiceCapabilities::~TracingServiceCapabilities() = default;
+TracingServiceCapabilities::TracingServiceCapabilities(const TracingServiceCapabilities&) = default;
+TracingServiceCapabilities& TracingServiceCapabilities::operator=(const TracingServiceCapabilities&) = default;
+TracingServiceCapabilities::TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept = default;
+TracingServiceCapabilities& TracingServiceCapabilities::operator=(TracingServiceCapabilities&&) = default;
+
+bool TracingServiceCapabilities::operator==(const TracingServiceCapabilities& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_query_capabilities_, other.has_query_capabilities_)
+   && ::protozero::internal::gen_helpers::EqualsField(observable_events_, other.observable_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_trace_config_output_path_, other.has_trace_config_output_path_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_clone_session_, other.has_clone_session_);
+}
+
+bool TracingServiceCapabilities::ParseFromArray(const void* raw, size_t size) {
+  observable_events_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* has_query_capabilities */:
+        field.get(&has_query_capabilities_);
+        break;
+      case 2 /* observable_events */:
+        observable_events_.emplace_back();
+        field.get(&observable_events_.back());
+        break;
+      case 3 /* has_trace_config_output_path */:
+        field.get(&has_trace_config_output_path_);
+        break;
+      case 4 /* has_clone_session */:
+        field.get(&has_clone_session_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceCapabilities::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceCapabilities::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceCapabilities::Serialize(::protozero::Message* msg) const {
+  // Field 1: has_query_capabilities
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, has_query_capabilities_, msg);
+  }
+
+  // Field 2: observable_events
+  for (auto& it : observable_events_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: has_trace_config_output_path
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, has_trace_config_output_path_, msg);
+  }
+
+  // Field 4: has_clone_session
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, has_clone_session_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TracingServiceState::TracingServiceState() = default;
+TracingServiceState::~TracingServiceState() = default;
+TracingServiceState::TracingServiceState(const TracingServiceState&) = default;
+TracingServiceState& TracingServiceState::operator=(const TracingServiceState&) = default;
+TracingServiceState::TracingServiceState(TracingServiceState&&) noexcept = default;
+TracingServiceState& TracingServiceState::operator=(TracingServiceState&&) = default;
+
+bool TracingServiceState::operator==(const TracingServiceState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(producers_, other.producers_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_sources_, other.data_sources_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_sessions_, other.tracing_sessions_)
+   && ::protozero::internal::gen_helpers::EqualsField(supports_tracing_sessions_, other.supports_tracing_sessions_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_sessions_, other.num_sessions_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_sessions_started_, other.num_sessions_started_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_service_version_, other.tracing_service_version_);
+}
+
+int TracingServiceState::producers_size() const { return static_cast<int>(producers_.size()); }
+void TracingServiceState::clear_producers() { producers_.clear(); }
+TracingServiceState_Producer* TracingServiceState::add_producers() { producers_.emplace_back(); return &producers_.back(); }
+int TracingServiceState::data_sources_size() const { return static_cast<int>(data_sources_.size()); }
+void TracingServiceState::clear_data_sources() { data_sources_.clear(); }
+TracingServiceState_DataSource* TracingServiceState::add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
+int TracingServiceState::tracing_sessions_size() const { return static_cast<int>(tracing_sessions_.size()); }
+void TracingServiceState::clear_tracing_sessions() { tracing_sessions_.clear(); }
+TracingServiceState_TracingSession* TracingServiceState::add_tracing_sessions() { tracing_sessions_.emplace_back(); return &tracing_sessions_.back(); }
+bool TracingServiceState::ParseFromArray(const void* raw, size_t size) {
+  producers_.clear();
+  data_sources_.clear();
+  tracing_sessions_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* producers */:
+        producers_.emplace_back();
+        producers_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* data_sources */:
+        data_sources_.emplace_back();
+        data_sources_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* tracing_sessions */:
+        tracing_sessions_.emplace_back();
+        tracing_sessions_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* supports_tracing_sessions */:
+        field.get(&supports_tracing_sessions_);
+        break;
+      case 3 /* num_sessions */:
+        field.get(&num_sessions_);
+        break;
+      case 4 /* num_sessions_started */:
+        field.get(&num_sessions_started_);
+        break;
+      case 5 /* tracing_service_version */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &tracing_service_version_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceState::Serialize(::protozero::Message* msg) const {
+  // Field 1: producers
+  for (auto& it : producers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: data_sources
+  for (auto& it : data_sources_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 6: tracing_sessions
+  for (auto& it : tracing_sessions_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 7: supports_tracing_sessions
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, supports_tracing_sessions_, msg);
+  }
+
+  // Field 3: num_sessions
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, num_sessions_, msg);
+  }
+
+  // Field 4: num_sessions_started
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, num_sessions_started_, msg);
+  }
+
+  // Field 5: tracing_service_version
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeString(5, tracing_service_version_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TracingServiceState_TracingSession::TracingServiceState_TracingSession() = default;
+TracingServiceState_TracingSession::~TracingServiceState_TracingSession() = default;
+TracingServiceState_TracingSession::TracingServiceState_TracingSession(const TracingServiceState_TracingSession&) = default;
+TracingServiceState_TracingSession& TracingServiceState_TracingSession::operator=(const TracingServiceState_TracingSession&) = default;
+TracingServiceState_TracingSession::TracingServiceState_TracingSession(TracingServiceState_TracingSession&&) noexcept = default;
+TracingServiceState_TracingSession& TracingServiceState_TracingSession::operator=(TracingServiceState_TracingSession&&) = default;
+
+bool TracingServiceState_TracingSession::operator==(const TracingServiceState_TracingSession& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
+   && ::protozero::internal::gen_helpers::EqualsField(consumer_uid_, other.consumer_uid_)
+   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_)
+   && ::protozero::internal::gen_helpers::EqualsField(unique_session_name_, other.unique_session_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_kb_, other.buffer_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(duration_ms_, other.duration_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_data_sources_, other.num_data_sources_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_realtime_ns_, other.start_realtime_ns_);
+}
+
+bool TracingServiceState_TracingSession::ParseFromArray(const void* raw, size_t size) {
+  buffer_size_kb_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* id */:
+        field.get(&id_);
+        break;
+      case 2 /* consumer_uid */:
+        field.get(&consumer_uid_);
+        break;
+      case 3 /* state */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &state_);
+        break;
+      case 4 /* unique_session_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &unique_session_name_);
+        break;
+      case 5 /* buffer_size_kb */:
+        buffer_size_kb_.emplace_back();
+        field.get(&buffer_size_kb_.back());
+        break;
+      case 6 /* duration_ms */:
+        field.get(&duration_ms_);
+        break;
+      case 7 /* num_data_sources */:
+        field.get(&num_data_sources_);
+        break;
+      case 8 /* start_realtime_ns */:
+        field.get(&start_realtime_ns_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceState_TracingSession::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState_TracingSession::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceState_TracingSession::Serialize(::protozero::Message* msg) const {
+  // Field 1: id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, id_, msg);
+  }
+
+  // Field 2: consumer_uid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, consumer_uid_, msg);
+  }
+
+  // Field 3: state
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, state_, msg);
+  }
+
+  // Field 4: unique_session_name
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, unique_session_name_, msg);
+  }
+
+  // Field 5: buffer_size_kb
+  for (auto& it : buffer_size_kb_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, it, msg);
+  }
+
+  // Field 6: duration_ms
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, duration_ms_, msg);
+  }
+
+  // Field 7: num_data_sources
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, num_data_sources_, msg);
+  }
+
+  // Field 8: start_realtime_ns
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, start_realtime_ns_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TracingServiceState_DataSource::TracingServiceState_DataSource() = default;
+TracingServiceState_DataSource::~TracingServiceState_DataSource() = default;
+TracingServiceState_DataSource::TracingServiceState_DataSource(const TracingServiceState_DataSource&) = default;
+TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(const TracingServiceState_DataSource&) = default;
+TracingServiceState_DataSource::TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept = default;
+TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(TracingServiceState_DataSource&&) = default;
+
+bool TracingServiceState_DataSource::operator==(const TracingServiceState_DataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(ds_descriptor_, other.ds_descriptor_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_id_, other.producer_id_);
+}
+
+bool TracingServiceState_DataSource::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* ds_descriptor */:
+        (*ds_descriptor_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* producer_id */:
+        field.get(&producer_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceState_DataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState_DataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceState_DataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: ds_descriptor
+  if (_has_field_[1]) {
+    (*ds_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: producer_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, producer_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TracingServiceState_Producer::TracingServiceState_Producer() = default;
+TracingServiceState_Producer::~TracingServiceState_Producer() = default;
+TracingServiceState_Producer::TracingServiceState_Producer(const TracingServiceState_Producer&) = default;
+TracingServiceState_Producer& TracingServiceState_Producer::operator=(const TracingServiceState_Producer&) = default;
+TracingServiceState_Producer::TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept = default;
+TracingServiceState_Producer& TracingServiceState_Producer::operator=(TracingServiceState_Producer&&) = default;
+
+bool TracingServiceState_Producer::operator==(const TracingServiceState_Producer& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(uid_, other.uid_)
+   && ::protozero::internal::gen_helpers::EqualsField(sdk_version_, other.sdk_version_);
+}
+
+bool TracingServiceState_Producer::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* id */:
+        field.get(&id_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 5 /* pid */:
+        field.get(&pid_);
+        break;
+      case 3 /* uid */:
+        field.get(&uid_);
+        break;
+      case 4 /* sdk_version */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &sdk_version_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TracingServiceState_Producer::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TracingServiceState_Producer::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TracingServiceState_Producer::Serialize(::protozero::Message* msg) const {
+  // Field 1: id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, id_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  // Field 5: pid
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, pid_, msg);
+  }
+
+  // Field 3: uid
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, uid_, msg);
+  }
+
+  // Field 4: sdk_version
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, sdk_version_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TrackEventDescriptor::TrackEventDescriptor() = default;
+TrackEventDescriptor::~TrackEventDescriptor() = default;
+TrackEventDescriptor::TrackEventDescriptor(const TrackEventDescriptor&) = default;
+TrackEventDescriptor& TrackEventDescriptor::operator=(const TrackEventDescriptor&) = default;
+TrackEventDescriptor::TrackEventDescriptor(TrackEventDescriptor&&) noexcept = default;
+TrackEventDescriptor& TrackEventDescriptor::operator=(TrackEventDescriptor&&) = default;
+
+bool TrackEventDescriptor::operator==(const TrackEventDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(available_categories_, other.available_categories_);
+}
+
+int TrackEventDescriptor::available_categories_size() const { return static_cast<int>(available_categories_.size()); }
+void TrackEventDescriptor::clear_available_categories() { available_categories_.clear(); }
+TrackEventCategory* TrackEventDescriptor::add_available_categories() { available_categories_.emplace_back(); return &available_categories_.back(); }
+bool TrackEventDescriptor::ParseFromArray(const void* raw, size_t size) {
+  available_categories_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* available_categories */:
+        available_categories_.emplace_back();
+        available_categories_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: available_categories
+  for (auto& it : available_categories_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TrackEventCategory::TrackEventCategory() = default;
+TrackEventCategory::~TrackEventCategory() = default;
+TrackEventCategory::TrackEventCategory(const TrackEventCategory&) = default;
+TrackEventCategory& TrackEventCategory::operator=(const TrackEventCategory&) = default;
+TrackEventCategory::TrackEventCategory(TrackEventCategory&&) noexcept = default;
+TrackEventCategory& TrackEventCategory::operator=(TrackEventCategory&&) = default;
+
+bool TrackEventCategory::operator==(const TrackEventCategory& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_)
+   && ::protozero::internal::gen_helpers::EqualsField(tags_, other.tags_);
+}
+
+bool TrackEventCategory::ParseFromArray(const void* raw, size_t size) {
+  tags_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* description */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
+        break;
+      case 3 /* tags */:
+        tags_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &tags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventCategory::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventCategory::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventCategory::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: description
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, description_, msg);
+  }
+
+  // Field 3: tags
+  for (auto& it : tags_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_game_intervention_list_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidGameInterventionListConfig::AndroidGameInterventionListConfig() = default;
+AndroidGameInterventionListConfig::~AndroidGameInterventionListConfig() = default;
+AndroidGameInterventionListConfig::AndroidGameInterventionListConfig(const AndroidGameInterventionListConfig&) = default;
+AndroidGameInterventionListConfig& AndroidGameInterventionListConfig::operator=(const AndroidGameInterventionListConfig&) = default;
+AndroidGameInterventionListConfig::AndroidGameInterventionListConfig(AndroidGameInterventionListConfig&&) noexcept = default;
+AndroidGameInterventionListConfig& AndroidGameInterventionListConfig::operator=(AndroidGameInterventionListConfig&&) = default;
+
+bool AndroidGameInterventionListConfig::operator==(const AndroidGameInterventionListConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(package_name_filter_, other.package_name_filter_);
+}
+
+bool AndroidGameInterventionListConfig::ParseFromArray(const void* raw, size_t size) {
+  package_name_filter_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* package_name_filter */:
+        package_name_filter_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &package_name_filter_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidGameInterventionListConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidGameInterventionListConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidGameInterventionListConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: package_name_filter
+  for (auto& it : package_name_filter_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidLogConfig::AndroidLogConfig() = default;
+AndroidLogConfig::~AndroidLogConfig() = default;
+AndroidLogConfig::AndroidLogConfig(const AndroidLogConfig&) = default;
+AndroidLogConfig& AndroidLogConfig::operator=(const AndroidLogConfig&) = default;
+AndroidLogConfig::AndroidLogConfig(AndroidLogConfig&&) noexcept = default;
+AndroidLogConfig& AndroidLogConfig::operator=(AndroidLogConfig&&) = default;
+
+bool AndroidLogConfig::operator==(const AndroidLogConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(log_ids_, other.log_ids_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_prio_, other.min_prio_)
+   && ::protozero::internal::gen_helpers::EqualsField(filter_tags_, other.filter_tags_);
+}
+
+bool AndroidLogConfig::ParseFromArray(const void* raw, size_t size) {
+  log_ids_.clear();
+  filter_tags_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* log_ids */:
+        log_ids_.emplace_back();
+        field.get(&log_ids_.back());
+        break;
+      case 3 /* min_prio */:
+        field.get(&min_prio_);
+        break;
+      case 4 /* filter_tags */:
+        filter_tags_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &filter_tags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidLogConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidLogConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidLogConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: log_ids
+  for (auto& it : log_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 3: min_prio
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, min_prio_, msg);
+  }
+
+  // Field 4: filter_tags
+  for (auto& it : filter_tags_) {
+    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidPolledStateConfig::AndroidPolledStateConfig() = default;
+AndroidPolledStateConfig::~AndroidPolledStateConfig() = default;
+AndroidPolledStateConfig::AndroidPolledStateConfig(const AndroidPolledStateConfig&) = default;
+AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(const AndroidPolledStateConfig&) = default;
+AndroidPolledStateConfig::AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept = default;
+AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(AndroidPolledStateConfig&&) = default;
+
+bool AndroidPolledStateConfig::operator==(const AndroidPolledStateConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(poll_ms_, other.poll_ms_);
+}
+
+bool AndroidPolledStateConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* poll_ms */:
+        field.get(&poll_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidPolledStateConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidPolledStateConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidPolledStateConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: poll_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, poll_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidSdkSyspropGuardConfig::AndroidSdkSyspropGuardConfig() = default;
+AndroidSdkSyspropGuardConfig::~AndroidSdkSyspropGuardConfig() = default;
+AndroidSdkSyspropGuardConfig::AndroidSdkSyspropGuardConfig(const AndroidSdkSyspropGuardConfig&) = default;
+AndroidSdkSyspropGuardConfig& AndroidSdkSyspropGuardConfig::operator=(const AndroidSdkSyspropGuardConfig&) = default;
+AndroidSdkSyspropGuardConfig::AndroidSdkSyspropGuardConfig(AndroidSdkSyspropGuardConfig&&) noexcept = default;
+AndroidSdkSyspropGuardConfig& AndroidSdkSyspropGuardConfig::operator=(AndroidSdkSyspropGuardConfig&&) = default;
+
+bool AndroidSdkSyspropGuardConfig::operator==(const AndroidSdkSyspropGuardConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(surfaceflinger_skia_track_events_, other.surfaceflinger_skia_track_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(hwui_skia_track_events_, other.hwui_skia_track_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(hwui_package_name_filter_, other.hwui_package_name_filter_);
+}
+
+bool AndroidSdkSyspropGuardConfig::ParseFromArray(const void* raw, size_t size) {
+  hwui_package_name_filter_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* surfaceflinger_skia_track_events */:
+        field.get(&surfaceflinger_skia_track_events_);
+        break;
+      case 2 /* hwui_skia_track_events */:
+        field.get(&hwui_skia_track_events_);
+        break;
+      case 3 /* hwui_package_name_filter */:
+        hwui_package_name_filter_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &hwui_package_name_filter_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidSdkSyspropGuardConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidSdkSyspropGuardConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidSdkSyspropGuardConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: surfaceflinger_skia_track_events
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, surfaceflinger_skia_track_events_, msg);
+  }
+
+  // Field 2: hwui_skia_track_events
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, hwui_skia_track_events_, msg);
+  }
+
+  // Field 3: hwui_package_name_filter
+  for (auto& it : hwui_package_name_filter_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_system_property_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidSystemPropertyConfig::AndroidSystemPropertyConfig() = default;
+AndroidSystemPropertyConfig::~AndroidSystemPropertyConfig() = default;
+AndroidSystemPropertyConfig::AndroidSystemPropertyConfig(const AndroidSystemPropertyConfig&) = default;
+AndroidSystemPropertyConfig& AndroidSystemPropertyConfig::operator=(const AndroidSystemPropertyConfig&) = default;
+AndroidSystemPropertyConfig::AndroidSystemPropertyConfig(AndroidSystemPropertyConfig&&) noexcept = default;
+AndroidSystemPropertyConfig& AndroidSystemPropertyConfig::operator=(AndroidSystemPropertyConfig&&) = default;
+
+bool AndroidSystemPropertyConfig::operator==(const AndroidSystemPropertyConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(poll_ms_, other.poll_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(property_name_, other.property_name_);
+}
+
+bool AndroidSystemPropertyConfig::ParseFromArray(const void* raw, size_t size) {
+  property_name_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* poll_ms */:
+        field.get(&poll_ms_);
+        break;
+      case 2 /* property_name */:
+        property_name_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &property_name_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidSystemPropertyConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidSystemPropertyConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidSystemPropertyConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: poll_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, poll_ms_, msg);
+  }
+
+  // Field 2: property_name
+  for (auto& it : property_name_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/network_trace_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+NetworkPacketTraceConfig::NetworkPacketTraceConfig() = default;
+NetworkPacketTraceConfig::~NetworkPacketTraceConfig() = default;
+NetworkPacketTraceConfig::NetworkPacketTraceConfig(const NetworkPacketTraceConfig&) = default;
+NetworkPacketTraceConfig& NetworkPacketTraceConfig::operator=(const NetworkPacketTraceConfig&) = default;
+NetworkPacketTraceConfig::NetworkPacketTraceConfig(NetworkPacketTraceConfig&&) noexcept = default;
+NetworkPacketTraceConfig& NetworkPacketTraceConfig::operator=(NetworkPacketTraceConfig&&) = default;
+
+bool NetworkPacketTraceConfig::operator==(const NetworkPacketTraceConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(poll_ms_, other.poll_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(aggregation_threshold_, other.aggregation_threshold_)
+   && ::protozero::internal::gen_helpers::EqualsField(intern_limit_, other.intern_limit_)
+   && ::protozero::internal::gen_helpers::EqualsField(drop_local_port_, other.drop_local_port_)
+   && ::protozero::internal::gen_helpers::EqualsField(drop_remote_port_, other.drop_remote_port_)
+   && ::protozero::internal::gen_helpers::EqualsField(drop_tcp_flags_, other.drop_tcp_flags_);
+}
+
+bool NetworkPacketTraceConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* poll_ms */:
+        field.get(&poll_ms_);
+        break;
+      case 2 /* aggregation_threshold */:
+        field.get(&aggregation_threshold_);
+        break;
+      case 3 /* intern_limit */:
+        field.get(&intern_limit_);
+        break;
+      case 4 /* drop_local_port */:
+        field.get(&drop_local_port_);
+        break;
+      case 5 /* drop_remote_port */:
+        field.get(&drop_remote_port_);
+        break;
+      case 6 /* drop_tcp_flags */:
+        field.get(&drop_tcp_flags_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NetworkPacketTraceConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NetworkPacketTraceConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NetworkPacketTraceConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: poll_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, poll_ms_, msg);
+  }
+
+  // Field 2: aggregation_threshold
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, aggregation_threshold_, msg);
+  }
+
+  // Field 3: intern_limit
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, intern_limit_, msg);
+  }
+
+  // Field 4: drop_local_port
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, drop_local_port_, msg);
+  }
+
+  // Field 5: drop_remote_port
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, drop_remote_port_, msg);
+  }
+
+  // Field 6: drop_tcp_flags
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, drop_tcp_flags_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+PackagesListConfig::PackagesListConfig() = default;
+PackagesListConfig::~PackagesListConfig() = default;
+PackagesListConfig::PackagesListConfig(const PackagesListConfig&) = default;
+PackagesListConfig& PackagesListConfig::operator=(const PackagesListConfig&) = default;
+PackagesListConfig::PackagesListConfig(PackagesListConfig&&) noexcept = default;
+PackagesListConfig& PackagesListConfig::operator=(PackagesListConfig&&) = default;
+
+bool PackagesListConfig::operator==(const PackagesListConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(package_name_filter_, other.package_name_filter_);
+}
+
+bool PackagesListConfig::ParseFromArray(const void* raw, size_t size) {
+  package_name_filter_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* package_name_filter */:
+        package_name_filter_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &package_name_filter_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PackagesListConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PackagesListConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PackagesListConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: package_name_filter
+  for (auto& it : package_name_filter_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_layers_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SurfaceFlingerLayersConfig::SurfaceFlingerLayersConfig() = default;
+SurfaceFlingerLayersConfig::~SurfaceFlingerLayersConfig() = default;
+SurfaceFlingerLayersConfig::SurfaceFlingerLayersConfig(const SurfaceFlingerLayersConfig&) = default;
+SurfaceFlingerLayersConfig& SurfaceFlingerLayersConfig::operator=(const SurfaceFlingerLayersConfig&) = default;
+SurfaceFlingerLayersConfig::SurfaceFlingerLayersConfig(SurfaceFlingerLayersConfig&&) noexcept = default;
+SurfaceFlingerLayersConfig& SurfaceFlingerLayersConfig::operator=(SurfaceFlingerLayersConfig&&) = default;
+
+bool SurfaceFlingerLayersConfig::operator==(const SurfaceFlingerLayersConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(mode_, other.mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_flags_, other.trace_flags_);
+}
+
+bool SurfaceFlingerLayersConfig::ParseFromArray(const void* raw, size_t size) {
+  trace_flags_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* mode */:
+        field.get(&mode_);
+        break;
+      case 2 /* trace_flags */:
+        trace_flags_.emplace_back();
+        field.get(&trace_flags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SurfaceFlingerLayersConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SurfaceFlingerLayersConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SurfaceFlingerLayersConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: mode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, mode_, msg);
+  }
+
+  // Field 2: trace_flags
+  for (auto& it : trace_flags_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_transactions_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SurfaceFlingerTransactionsConfig::SurfaceFlingerTransactionsConfig() = default;
+SurfaceFlingerTransactionsConfig::~SurfaceFlingerTransactionsConfig() = default;
+SurfaceFlingerTransactionsConfig::SurfaceFlingerTransactionsConfig(const SurfaceFlingerTransactionsConfig&) = default;
+SurfaceFlingerTransactionsConfig& SurfaceFlingerTransactionsConfig::operator=(const SurfaceFlingerTransactionsConfig&) = default;
+SurfaceFlingerTransactionsConfig::SurfaceFlingerTransactionsConfig(SurfaceFlingerTransactionsConfig&&) noexcept = default;
+SurfaceFlingerTransactionsConfig& SurfaceFlingerTransactionsConfig::operator=(SurfaceFlingerTransactionsConfig&&) = default;
+
+bool SurfaceFlingerTransactionsConfig::operator==(const SurfaceFlingerTransactionsConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(mode_, other.mode_);
+}
+
+bool SurfaceFlingerTransactionsConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* mode */:
+        field.get(&mode_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SurfaceFlingerTransactionsConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SurfaceFlingerTransactionsConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SurfaceFlingerTransactionsConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: mode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, mode_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+FtraceConfig::FtraceConfig() = default;
+FtraceConfig::~FtraceConfig() = default;
+FtraceConfig::FtraceConfig(const FtraceConfig&) = default;
+FtraceConfig& FtraceConfig::operator=(const FtraceConfig&) = default;
+FtraceConfig::FtraceConfig(FtraceConfig&&) noexcept = default;
+FtraceConfig& FtraceConfig::operator=(FtraceConfig&&) = default;
+
+bool FtraceConfig::operator==(const FtraceConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(ftrace_events_, other.ftrace_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(atrace_categories_, other.atrace_categories_)
+   && ::protozero::internal::gen_helpers::EqualsField(atrace_apps_, other.atrace_apps_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_kb_, other.buffer_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(drain_period_ms_, other.drain_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(compact_sched_, other.compact_sched_)
+   && ::protozero::internal::gen_helpers::EqualsField(print_filter_, other.print_filter_)
+   && ::protozero::internal::gen_helpers::EqualsField(symbolize_ksyms_, other.symbolize_ksyms_)
+   && ::protozero::internal::gen_helpers::EqualsField(ksyms_mem_policy_, other.ksyms_mem_policy_)
+   && ::protozero::internal::gen_helpers::EqualsField(initialize_ksyms_synchronously_for_testing_, other.initialize_ksyms_synchronously_for_testing_)
+   && ::protozero::internal::gen_helpers::EqualsField(throttle_rss_stat_, other.throttle_rss_stat_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_generic_events_, other.disable_generic_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(syscall_events_, other.syscall_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(enable_function_graph_, other.enable_function_graph_)
+   && ::protozero::internal::gen_helpers::EqualsField(function_filters_, other.function_filters_)
+   && ::protozero::internal::gen_helpers::EqualsField(function_graph_roots_, other.function_graph_roots_)
+   && ::protozero::internal::gen_helpers::EqualsField(preserve_ftrace_buffer_, other.preserve_ftrace_buffer_)
+   && ::protozero::internal::gen_helpers::EqualsField(use_monotonic_raw_clock_, other.use_monotonic_raw_clock_)
+   && ::protozero::internal::gen_helpers::EqualsField(instance_name_, other.instance_name_);
+}
+
+bool FtraceConfig::ParseFromArray(const void* raw, size_t size) {
+  ftrace_events_.clear();
+  atrace_categories_.clear();
+  atrace_apps_.clear();
+  syscall_events_.clear();
+  function_filters_.clear();
+  function_graph_roots_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* ftrace_events */:
+        ftrace_events_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &ftrace_events_.back());
+        break;
+      case 2 /* atrace_categories */:
+        atrace_categories_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &atrace_categories_.back());
+        break;
+      case 3 /* atrace_apps */:
+        atrace_apps_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &atrace_apps_.back());
+        break;
+      case 10 /* buffer_size_kb */:
+        field.get(&buffer_size_kb_);
+        break;
+      case 11 /* drain_period_ms */:
+        field.get(&drain_period_ms_);
+        break;
+      case 12 /* compact_sched */:
+        (*compact_sched_).ParseFromArray(field.data(), field.size());
+        break;
+      case 22 /* print_filter */:
+        (*print_filter_).ParseFromArray(field.data(), field.size());
+        break;
+      case 13 /* symbolize_ksyms */:
+        field.get(&symbolize_ksyms_);
+        break;
+      case 17 /* ksyms_mem_policy */:
+        field.get(&ksyms_mem_policy_);
+        break;
+      case 14 /* initialize_ksyms_synchronously_for_testing */:
+        field.get(&initialize_ksyms_synchronously_for_testing_);
+        break;
+      case 15 /* throttle_rss_stat */:
+        field.get(&throttle_rss_stat_);
+        break;
+      case 16 /* disable_generic_events */:
+        field.get(&disable_generic_events_);
+        break;
+      case 18 /* syscall_events */:
+        syscall_events_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &syscall_events_.back());
+        break;
+      case 19 /* enable_function_graph */:
+        field.get(&enable_function_graph_);
+        break;
+      case 20 /* function_filters */:
+        function_filters_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &function_filters_.back());
+        break;
+      case 21 /* function_graph_roots */:
+        function_graph_roots_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &function_graph_roots_.back());
+        break;
+      case 23 /* preserve_ftrace_buffer */:
+        field.get(&preserve_ftrace_buffer_);
+        break;
+      case 24 /* use_monotonic_raw_clock */:
+        field.get(&use_monotonic_raw_clock_);
+        break;
+      case 25 /* instance_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &instance_name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: ftrace_events
+  for (auto& it : ftrace_events_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  // Field 2: atrace_categories
+  for (auto& it : atrace_categories_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: atrace_apps
+  for (auto& it : atrace_apps_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  // Field 10: buffer_size_kb
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, buffer_size_kb_, msg);
+  }
+
+  // Field 11: drain_period_ms
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, drain_period_ms_, msg);
+  }
+
+  // Field 12: compact_sched
+  if (_has_field_[12]) {
+    (*compact_sched_).Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
+  }
+
+  // Field 22: print_filter
+  if (_has_field_[22]) {
+    (*print_filter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(22));
+  }
+
+  // Field 13: symbolize_ksyms
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(13, symbolize_ksyms_, msg);
+  }
+
+  // Field 17: ksyms_mem_policy
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, ksyms_mem_policy_, msg);
+  }
+
+  // Field 14: initialize_ksyms_synchronously_for_testing
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(14, initialize_ksyms_synchronously_for_testing_, msg);
+  }
+
+  // Field 15: throttle_rss_stat
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(15, throttle_rss_stat_, msg);
+  }
+
+  // Field 16: disable_generic_events
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(16, disable_generic_events_, msg);
+  }
+
+  // Field 18: syscall_events
+  for (auto& it : syscall_events_) {
+    ::protozero::internal::gen_helpers::SerializeString(18, it, msg);
+  }
+
+  // Field 19: enable_function_graph
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, enable_function_graph_, msg);
+  }
+
+  // Field 20: function_filters
+  for (auto& it : function_filters_) {
+    ::protozero::internal::gen_helpers::SerializeString(20, it, msg);
+  }
+
+  // Field 21: function_graph_roots
+  for (auto& it : function_graph_roots_) {
+    ::protozero::internal::gen_helpers::SerializeString(21, it, msg);
+  }
+
+  // Field 23: preserve_ftrace_buffer
+  if (_has_field_[23]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(23, preserve_ftrace_buffer_, msg);
+  }
+
+  // Field 24: use_monotonic_raw_clock
+  if (_has_field_[24]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(24, use_monotonic_raw_clock_, msg);
+  }
+
+  // Field 25: instance_name
+  if (_has_field_[25]) {
+    ::protozero::internal::gen_helpers::SerializeString(25, instance_name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FtraceConfig_PrintFilter::FtraceConfig_PrintFilter() = default;
+FtraceConfig_PrintFilter::~FtraceConfig_PrintFilter() = default;
+FtraceConfig_PrintFilter::FtraceConfig_PrintFilter(const FtraceConfig_PrintFilter&) = default;
+FtraceConfig_PrintFilter& FtraceConfig_PrintFilter::operator=(const FtraceConfig_PrintFilter&) = default;
+FtraceConfig_PrintFilter::FtraceConfig_PrintFilter(FtraceConfig_PrintFilter&&) noexcept = default;
+FtraceConfig_PrintFilter& FtraceConfig_PrintFilter::operator=(FtraceConfig_PrintFilter&&) = default;
+
+bool FtraceConfig_PrintFilter::operator==(const FtraceConfig_PrintFilter& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(rules_, other.rules_);
+}
+
+int FtraceConfig_PrintFilter::rules_size() const { return static_cast<int>(rules_.size()); }
+void FtraceConfig_PrintFilter::clear_rules() { rules_.clear(); }
+FtraceConfig_PrintFilter_Rule* FtraceConfig_PrintFilter::add_rules() { rules_.emplace_back(); return &rules_.back(); }
+bool FtraceConfig_PrintFilter::ParseFromArray(const void* raw, size_t size) {
+  rules_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* rules */:
+        rules_.emplace_back();
+        rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig_PrintFilter::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig_PrintFilter::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig_PrintFilter::Serialize(::protozero::Message* msg) const {
+  // Field 1: rules
+  for (auto& it : rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FtraceConfig_PrintFilter_Rule::FtraceConfig_PrintFilter_Rule() = default;
+FtraceConfig_PrintFilter_Rule::~FtraceConfig_PrintFilter_Rule() = default;
+FtraceConfig_PrintFilter_Rule::FtraceConfig_PrintFilter_Rule(const FtraceConfig_PrintFilter_Rule&) = default;
+FtraceConfig_PrintFilter_Rule& FtraceConfig_PrintFilter_Rule::operator=(const FtraceConfig_PrintFilter_Rule&) = default;
+FtraceConfig_PrintFilter_Rule::FtraceConfig_PrintFilter_Rule(FtraceConfig_PrintFilter_Rule&&) noexcept = default;
+FtraceConfig_PrintFilter_Rule& FtraceConfig_PrintFilter_Rule::operator=(FtraceConfig_PrintFilter_Rule&&) = default;
+
+bool FtraceConfig_PrintFilter_Rule::operator==(const FtraceConfig_PrintFilter_Rule& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(prefix_, other.prefix_)
+   && ::protozero::internal::gen_helpers::EqualsField(atrace_msg_, other.atrace_msg_)
+   && ::protozero::internal::gen_helpers::EqualsField(allow_, other.allow_);
+}
+
+bool FtraceConfig_PrintFilter_Rule::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* prefix */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &prefix_);
+        break;
+      case 3 /* atrace_msg */:
+        (*atrace_msg_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* allow */:
+        field.get(&allow_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig_PrintFilter_Rule::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig_PrintFilter_Rule::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig_PrintFilter_Rule::Serialize(::protozero::Message* msg) const {
+  // Field 1: prefix
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, prefix_, msg);
+  }
+
+  // Field 3: atrace_msg
+  if (_has_field_[3]) {
+    (*atrace_msg_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 2: allow
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, allow_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FtraceConfig_PrintFilter_Rule_AtraceMessage::FtraceConfig_PrintFilter_Rule_AtraceMessage() = default;
+FtraceConfig_PrintFilter_Rule_AtraceMessage::~FtraceConfig_PrintFilter_Rule_AtraceMessage() = default;
+FtraceConfig_PrintFilter_Rule_AtraceMessage::FtraceConfig_PrintFilter_Rule_AtraceMessage(const FtraceConfig_PrintFilter_Rule_AtraceMessage&) = default;
+FtraceConfig_PrintFilter_Rule_AtraceMessage& FtraceConfig_PrintFilter_Rule_AtraceMessage::operator=(const FtraceConfig_PrintFilter_Rule_AtraceMessage&) = default;
+FtraceConfig_PrintFilter_Rule_AtraceMessage::FtraceConfig_PrintFilter_Rule_AtraceMessage(FtraceConfig_PrintFilter_Rule_AtraceMessage&&) noexcept = default;
+FtraceConfig_PrintFilter_Rule_AtraceMessage& FtraceConfig_PrintFilter_Rule_AtraceMessage::operator=(FtraceConfig_PrintFilter_Rule_AtraceMessage&&) = default;
+
+bool FtraceConfig_PrintFilter_Rule_AtraceMessage::operator==(const FtraceConfig_PrintFilter_Rule_AtraceMessage& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(prefix_, other.prefix_);
+}
+
+bool FtraceConfig_PrintFilter_Rule_AtraceMessage::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* type */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &type_);
+        break;
+      case 2 /* prefix */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &prefix_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig_PrintFilter_Rule_AtraceMessage::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig_PrintFilter_Rule_AtraceMessage::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig_PrintFilter_Rule_AtraceMessage::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, type_, msg);
+  }
+
+  // Field 2: prefix
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, prefix_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig() = default;
+FtraceConfig_CompactSchedConfig::~FtraceConfig_CompactSchedConfig() = default;
+FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&) = default;
+FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(const FtraceConfig_CompactSchedConfig&) = default;
+FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept = default;
+FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(FtraceConfig_CompactSchedConfig&&) = default;
+
+bool FtraceConfig_CompactSchedConfig::operator==(const FtraceConfig_CompactSchedConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(enabled_, other.enabled_);
+}
+
+bool FtraceConfig_CompactSchedConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* enabled */:
+        field.get(&enabled_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FtraceConfig_CompactSchedConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FtraceConfig_CompactSchedConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FtraceConfig_CompactSchedConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: enabled
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, enabled_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+GpuCounterConfig::GpuCounterConfig() = default;
+GpuCounterConfig::~GpuCounterConfig() = default;
+GpuCounterConfig::GpuCounterConfig(const GpuCounterConfig&) = default;
+GpuCounterConfig& GpuCounterConfig::operator=(const GpuCounterConfig&) = default;
+GpuCounterConfig::GpuCounterConfig(GpuCounterConfig&&) noexcept = default;
+GpuCounterConfig& GpuCounterConfig::operator=(GpuCounterConfig&&) = default;
+
+bool GpuCounterConfig::operator==(const GpuCounterConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_period_ns_, other.counter_period_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_ids_, other.counter_ids_)
+   && ::protozero::internal::gen_helpers::EqualsField(instrumented_sampling_, other.instrumented_sampling_)
+   && ::protozero::internal::gen_helpers::EqualsField(fix_gpu_clock_, other.fix_gpu_clock_);
+}
+
+bool GpuCounterConfig::ParseFromArray(const void* raw, size_t size) {
+  counter_ids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* counter_period_ns */:
+        field.get(&counter_period_ns_);
+        break;
+      case 2 /* counter_ids */:
+        counter_ids_.emplace_back();
+        field.get(&counter_ids_.back());
+        break;
+      case 3 /* instrumented_sampling */:
+        field.get(&instrumented_sampling_);
+        break;
+      case 4 /* fix_gpu_clock */:
+        field.get(&fix_gpu_clock_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GpuCounterConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GpuCounterConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GpuCounterConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: counter_period_ns
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, counter_period_ns_, msg);
+  }
+
+  // Field 2: counter_ids
+  for (auto& it : counter_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: instrumented_sampling
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, instrumented_sampling_, msg);
+  }
+
+  // Field 4: fix_gpu_clock
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, fix_gpu_clock_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+VulkanMemoryConfig::VulkanMemoryConfig() = default;
+VulkanMemoryConfig::~VulkanMemoryConfig() = default;
+VulkanMemoryConfig::VulkanMemoryConfig(const VulkanMemoryConfig&) = default;
+VulkanMemoryConfig& VulkanMemoryConfig::operator=(const VulkanMemoryConfig&) = default;
+VulkanMemoryConfig::VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept = default;
+VulkanMemoryConfig& VulkanMemoryConfig::operator=(VulkanMemoryConfig&&) = default;
+
+bool VulkanMemoryConfig::operator==(const VulkanMemoryConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_driver_memory_usage_, other.track_driver_memory_usage_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_device_memory_usage_, other.track_device_memory_usage_);
+}
+
+bool VulkanMemoryConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* track_driver_memory_usage */:
+        field.get(&track_driver_memory_usage_);
+        break;
+      case 2 /* track_device_memory_usage */:
+        field.get(&track_device_memory_usage_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string VulkanMemoryConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> VulkanMemoryConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void VulkanMemoryConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: track_driver_memory_usage
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, track_driver_memory_usage_, msg);
+  }
+
+  // Field 2: track_device_memory_usage
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, track_device_memory_usage_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+InodeFileConfig::InodeFileConfig() = default;
+InodeFileConfig::~InodeFileConfig() = default;
+InodeFileConfig::InodeFileConfig(const InodeFileConfig&) = default;
+InodeFileConfig& InodeFileConfig::operator=(const InodeFileConfig&) = default;
+InodeFileConfig::InodeFileConfig(InodeFileConfig&&) noexcept = default;
+InodeFileConfig& InodeFileConfig::operator=(InodeFileConfig&&) = default;
+
+bool InodeFileConfig::operator==(const InodeFileConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_interval_ms_, other.scan_interval_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_delay_ms_, other.scan_delay_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_batch_size_, other.scan_batch_size_)
+   && ::protozero::internal::gen_helpers::EqualsField(do_not_scan_, other.do_not_scan_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_mount_points_, other.scan_mount_points_)
+   && ::protozero::internal::gen_helpers::EqualsField(mount_point_mapping_, other.mount_point_mapping_);
+}
+
+int InodeFileConfig::mount_point_mapping_size() const { return static_cast<int>(mount_point_mapping_.size()); }
+void InodeFileConfig::clear_mount_point_mapping() { mount_point_mapping_.clear(); }
+InodeFileConfig_MountPointMappingEntry* InodeFileConfig::add_mount_point_mapping() { mount_point_mapping_.emplace_back(); return &mount_point_mapping_.back(); }
+bool InodeFileConfig::ParseFromArray(const void* raw, size_t size) {
+  scan_mount_points_.clear();
+  mount_point_mapping_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* scan_interval_ms */:
+        field.get(&scan_interval_ms_);
+        break;
+      case 2 /* scan_delay_ms */:
+        field.get(&scan_delay_ms_);
+        break;
+      case 3 /* scan_batch_size */:
+        field.get(&scan_batch_size_);
+        break;
+      case 4 /* do_not_scan */:
+        field.get(&do_not_scan_);
+        break;
+      case 5 /* scan_mount_points */:
+        scan_mount_points_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &scan_mount_points_.back());
+        break;
+      case 6 /* mount_point_mapping */:
+        mount_point_mapping_.emplace_back();
+        mount_point_mapping_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InodeFileConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InodeFileConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InodeFileConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: scan_interval_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, scan_interval_ms_, msg);
+  }
+
+  // Field 2: scan_delay_ms
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, scan_delay_ms_, msg);
+  }
+
+  // Field 3: scan_batch_size
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, scan_batch_size_, msg);
+  }
+
+  // Field 4: do_not_scan
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, do_not_scan_, msg);
+  }
+
+  // Field 5: scan_mount_points
+  for (auto& it : scan_mount_points_) {
+    ::protozero::internal::gen_helpers::SerializeString(5, it, msg);
+  }
+
+  // Field 6: mount_point_mapping
+  for (auto& it : mount_point_mapping_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry() = default;
+InodeFileConfig_MountPointMappingEntry::~InodeFileConfig_MountPointMappingEntry() = default;
+InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&) = default;
+InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(const InodeFileConfig_MountPointMappingEntry&) = default;
+InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept = default;
+InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(InodeFileConfig_MountPointMappingEntry&&) = default;
+
+bool InodeFileConfig_MountPointMappingEntry::operator==(const InodeFileConfig_MountPointMappingEntry& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(mountpoint_, other.mountpoint_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_roots_, other.scan_roots_);
+}
+
+bool InodeFileConfig_MountPointMappingEntry::ParseFromArray(const void* raw, size_t size) {
+  scan_roots_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* mountpoint */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &mountpoint_);
+        break;
+      case 2 /* scan_roots */:
+        scan_roots_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &scan_roots_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InodeFileConfig_MountPointMappingEntry::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InodeFileConfig_MountPointMappingEntry::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InodeFileConfig_MountPointMappingEntry::Serialize(::protozero::Message* msg) const {
+  // Field 1: mountpoint
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, mountpoint_, msg);
+  }
+
+  // Field 2: scan_roots
+  for (auto& it : scan_roots_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/interceptors/console_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ConsoleConfig::ConsoleConfig() = default;
+ConsoleConfig::~ConsoleConfig() = default;
+ConsoleConfig::ConsoleConfig(const ConsoleConfig&) = default;
+ConsoleConfig& ConsoleConfig::operator=(const ConsoleConfig&) = default;
+ConsoleConfig::ConsoleConfig(ConsoleConfig&&) noexcept = default;
+ConsoleConfig& ConsoleConfig::operator=(ConsoleConfig&&) = default;
+
+bool ConsoleConfig::operator==(const ConsoleConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(output_, other.output_)
+   && ::protozero::internal::gen_helpers::EqualsField(enable_colors_, other.enable_colors_);
+}
+
+bool ConsoleConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* output */:
+        field.get(&output_);
+        break;
+      case 2 /* enable_colors */:
+        field.get(&enable_colors_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ConsoleConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ConsoleConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ConsoleConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: output
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, output_, msg);
+  }
+
+  // Field 2: enable_colors
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, enable_colors_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+AndroidPowerConfig::AndroidPowerConfig() = default;
+AndroidPowerConfig::~AndroidPowerConfig() = default;
+AndroidPowerConfig::AndroidPowerConfig(const AndroidPowerConfig&) = default;
+AndroidPowerConfig& AndroidPowerConfig::operator=(const AndroidPowerConfig&) = default;
+AndroidPowerConfig::AndroidPowerConfig(AndroidPowerConfig&&) noexcept = default;
+AndroidPowerConfig& AndroidPowerConfig::operator=(AndroidPowerConfig&&) = default;
+
+bool AndroidPowerConfig::operator==(const AndroidPowerConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(battery_poll_ms_, other.battery_poll_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(battery_counters_, other.battery_counters_)
+   && ::protozero::internal::gen_helpers::EqualsField(collect_power_rails_, other.collect_power_rails_)
+   && ::protozero::internal::gen_helpers::EqualsField(collect_energy_estimation_breakdown_, other.collect_energy_estimation_breakdown_)
+   && ::protozero::internal::gen_helpers::EqualsField(collect_entity_state_residency_, other.collect_entity_state_residency_);
+}
+
+bool AndroidPowerConfig::ParseFromArray(const void* raw, size_t size) {
+  battery_counters_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* battery_poll_ms */:
+        field.get(&battery_poll_ms_);
+        break;
+      case 2 /* battery_counters */:
+        battery_counters_.emplace_back();
+        field.get(&battery_counters_.back());
+        break;
+      case 3 /* collect_power_rails */:
+        field.get(&collect_power_rails_);
+        break;
+      case 4 /* collect_energy_estimation_breakdown */:
+        field.get(&collect_energy_estimation_breakdown_);
+        break;
+      case 5 /* collect_entity_state_residency */:
+        field.get(&collect_entity_state_residency_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AndroidPowerConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AndroidPowerConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AndroidPowerConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: battery_poll_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, battery_poll_ms_, msg);
+  }
+
+  // Field 2: battery_counters
+  for (auto& it : battery_counters_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: collect_power_rails
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, collect_power_rails_, msg);
+  }
+
+  // Field 4: collect_energy_estimation_breakdown
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, collect_energy_estimation_breakdown_, msg);
+  }
+
+  // Field 5: collect_entity_state_residency
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, collect_entity_state_residency_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ProcessStatsConfig::ProcessStatsConfig() = default;
+ProcessStatsConfig::~ProcessStatsConfig() = default;
+ProcessStatsConfig::ProcessStatsConfig(const ProcessStatsConfig&) = default;
+ProcessStatsConfig& ProcessStatsConfig::operator=(const ProcessStatsConfig&) = default;
+ProcessStatsConfig::ProcessStatsConfig(ProcessStatsConfig&&) noexcept = default;
+ProcessStatsConfig& ProcessStatsConfig::operator=(ProcessStatsConfig&&) = default;
+
+bool ProcessStatsConfig::operator==(const ProcessStatsConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(quirks_, other.quirks_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_all_processes_on_start_, other.scan_all_processes_on_start_)
+   && ::protozero::internal::gen_helpers::EqualsField(record_thread_names_, other.record_thread_names_)
+   && ::protozero::internal::gen_helpers::EqualsField(proc_stats_poll_ms_, other.proc_stats_poll_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(proc_stats_cache_ttl_ms_, other.proc_stats_cache_ttl_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(resolve_process_fds_, other.resolve_process_fds_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_smaps_rollup_, other.scan_smaps_rollup_);
+}
+
+bool ProcessStatsConfig::ParseFromArray(const void* raw, size_t size) {
+  quirks_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* quirks */:
+        quirks_.emplace_back();
+        field.get(&quirks_.back());
+        break;
+      case 2 /* scan_all_processes_on_start */:
+        field.get(&scan_all_processes_on_start_);
+        break;
+      case 3 /* record_thread_names */:
+        field.get(&record_thread_names_);
+        break;
+      case 4 /* proc_stats_poll_ms */:
+        field.get(&proc_stats_poll_ms_);
+        break;
+      case 6 /* proc_stats_cache_ttl_ms */:
+        field.get(&proc_stats_cache_ttl_ms_);
+        break;
+      case 9 /* resolve_process_fds */:
+        field.get(&resolve_process_fds_);
+        break;
+      case 10 /* scan_smaps_rollup */:
+        field.get(&scan_smaps_rollup_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ProcessStatsConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ProcessStatsConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ProcessStatsConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: quirks
+  for (auto& it : quirks_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 2: scan_all_processes_on_start
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, scan_all_processes_on_start_, msg);
+  }
+
+  // Field 3: record_thread_names
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, record_thread_names_, msg);
+  }
+
+  // Field 4: proc_stats_poll_ms
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, proc_stats_poll_ms_, msg);
+  }
+
+  // Field 6: proc_stats_cache_ttl_ms
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, proc_stats_cache_ttl_ms_, msg);
+  }
+
+  // Field 9: resolve_process_fds
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, resolve_process_fds_, msg);
+  }
+
+  // Field 10: scan_smaps_rollup
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, scan_smaps_rollup_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+HeapprofdConfig::HeapprofdConfig() = default;
+HeapprofdConfig::~HeapprofdConfig() = default;
+HeapprofdConfig::HeapprofdConfig(const HeapprofdConfig&) = default;
+HeapprofdConfig& HeapprofdConfig::operator=(const HeapprofdConfig&) = default;
+HeapprofdConfig::HeapprofdConfig(HeapprofdConfig&&) noexcept = default;
+HeapprofdConfig& HeapprofdConfig::operator=(HeapprofdConfig&&) = default;
+
+bool HeapprofdConfig::operator==(const HeapprofdConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(sampling_interval_bytes_, other.sampling_interval_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(adaptive_sampling_shmem_threshold_, other.adaptive_sampling_shmem_threshold_)
+   && ::protozero::internal::gen_helpers::EqualsField(adaptive_sampling_max_sampling_interval_bytes_, other.adaptive_sampling_max_sampling_interval_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_cmdline_, other.process_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_installed_by_, other.target_installed_by_)
+   && ::protozero::internal::gen_helpers::EqualsField(heaps_, other.heaps_)
+   && ::protozero::internal::gen_helpers::EqualsField(exclude_heaps_, other.exclude_heaps_)
+   && ::protozero::internal::gen_helpers::EqualsField(stream_allocations_, other.stream_allocations_)
+   && ::protozero::internal::gen_helpers::EqualsField(heap_sampling_intervals_, other.heap_sampling_intervals_)
+   && ::protozero::internal::gen_helpers::EqualsField(all_heaps_, other.all_heaps_)
+   && ::protozero::internal::gen_helpers::EqualsField(all_, other.all_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_anonymous_memory_kb_, other.min_anonymous_memory_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_heapprofd_memory_kb_, other.max_heapprofd_memory_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_heapprofd_cpu_secs_, other.max_heapprofd_cpu_secs_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_symbol_prefix_, other.skip_symbol_prefix_)
+   && ::protozero::internal::gen_helpers::EqualsField(continuous_dump_config_, other.continuous_dump_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(shmem_size_bytes_, other.shmem_size_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(block_client_, other.block_client_)
+   && ::protozero::internal::gen_helpers::EqualsField(block_client_timeout_us_, other.block_client_timeout_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(no_startup_, other.no_startup_)
+   && ::protozero::internal::gen_helpers::EqualsField(no_running_, other.no_running_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_at_max_, other.dump_at_max_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_fork_teardown_, other.disable_fork_teardown_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_vfork_detection_, other.disable_vfork_detection_);
+}
+
+bool HeapprofdConfig::ParseFromArray(const void* raw, size_t size) {
+  process_cmdline_.clear();
+  pid_.clear();
+  target_installed_by_.clear();
+  heaps_.clear();
+  exclude_heaps_.clear();
+  heap_sampling_intervals_.clear();
+  skip_symbol_prefix_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* sampling_interval_bytes */:
+        field.get(&sampling_interval_bytes_);
+        break;
+      case 24 /* adaptive_sampling_shmem_threshold */:
+        field.get(&adaptive_sampling_shmem_threshold_);
+        break;
+      case 25 /* adaptive_sampling_max_sampling_interval_bytes */:
+        field.get(&adaptive_sampling_max_sampling_interval_bytes_);
+        break;
+      case 2 /* process_cmdline */:
+        process_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &process_cmdline_.back());
+        break;
+      case 4 /* pid */:
+        pid_.emplace_back();
+        field.get(&pid_.back());
+        break;
+      case 26 /* target_installed_by */:
+        target_installed_by_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &target_installed_by_.back());
+        break;
+      case 20 /* heaps */:
+        heaps_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &heaps_.back());
+        break;
+      case 27 /* exclude_heaps */:
+        exclude_heaps_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &exclude_heaps_.back());
+        break;
+      case 23 /* stream_allocations */:
+        field.get(&stream_allocations_);
+        break;
+      case 22 /* heap_sampling_intervals */:
+        heap_sampling_intervals_.emplace_back();
+        field.get(&heap_sampling_intervals_.back());
+        break;
+      case 21 /* all_heaps */:
+        field.get(&all_heaps_);
+        break;
+      case 5 /* all */:
+        field.get(&all_);
+        break;
+      case 15 /* min_anonymous_memory_kb */:
+        field.get(&min_anonymous_memory_kb_);
+        break;
+      case 16 /* max_heapprofd_memory_kb */:
+        field.get(&max_heapprofd_memory_kb_);
+        break;
+      case 17 /* max_heapprofd_cpu_secs */:
+        field.get(&max_heapprofd_cpu_secs_);
+        break;
+      case 7 /* skip_symbol_prefix */:
+        skip_symbol_prefix_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &skip_symbol_prefix_.back());
+        break;
+      case 6 /* continuous_dump_config */:
+        (*continuous_dump_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* shmem_size_bytes */:
+        field.get(&shmem_size_bytes_);
+        break;
+      case 9 /* block_client */:
+        field.get(&block_client_);
+        break;
+      case 14 /* block_client_timeout_us */:
+        field.get(&block_client_timeout_us_);
+        break;
+      case 10 /* no_startup */:
+        field.get(&no_startup_);
+        break;
+      case 11 /* no_running */:
+        field.get(&no_running_);
+        break;
+      case 13 /* dump_at_max */:
+        field.get(&dump_at_max_);
+        break;
+      case 18 /* disable_fork_teardown */:
+        field.get(&disable_fork_teardown_);
+        break;
+      case 19 /* disable_vfork_detection */:
+        field.get(&disable_vfork_detection_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string HeapprofdConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> HeapprofdConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void HeapprofdConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: sampling_interval_bytes
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, sampling_interval_bytes_, msg);
+  }
+
+  // Field 24: adaptive_sampling_shmem_threshold
+  if (_has_field_[24]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(24, adaptive_sampling_shmem_threshold_, msg);
+  }
+
+  // Field 25: adaptive_sampling_max_sampling_interval_bytes
+  if (_has_field_[25]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(25, adaptive_sampling_max_sampling_interval_bytes_, msg);
+  }
+
+  // Field 2: process_cmdline
+  for (auto& it : process_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 4: pid
+  for (auto& it : pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, it, msg);
+  }
+
+  // Field 26: target_installed_by
+  for (auto& it : target_installed_by_) {
+    ::protozero::internal::gen_helpers::SerializeString(26, it, msg);
+  }
+
+  // Field 20: heaps
+  for (auto& it : heaps_) {
+    ::protozero::internal::gen_helpers::SerializeString(20, it, msg);
+  }
+
+  // Field 27: exclude_heaps
+  for (auto& it : exclude_heaps_) {
+    ::protozero::internal::gen_helpers::SerializeString(27, it, msg);
+  }
+
+  // Field 23: stream_allocations
+  if (_has_field_[23]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(23, stream_allocations_, msg);
+  }
+
+  // Field 22: heap_sampling_intervals
+  for (auto& it : heap_sampling_intervals_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(22, it, msg);
+  }
+
+  // Field 21: all_heaps
+  if (_has_field_[21]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(21, all_heaps_, msg);
+  }
+
+  // Field 5: all
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, all_, msg);
+  }
+
+  // Field 15: min_anonymous_memory_kb
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(15, min_anonymous_memory_kb_, msg);
+  }
+
+  // Field 16: max_heapprofd_memory_kb
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(16, max_heapprofd_memory_kb_, msg);
+  }
+
+  // Field 17: max_heapprofd_cpu_secs
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, max_heapprofd_cpu_secs_, msg);
+  }
+
+  // Field 7: skip_symbol_prefix
+  for (auto& it : skip_symbol_prefix_) {
+    ::protozero::internal::gen_helpers::SerializeString(7, it, msg);
+  }
+
+  // Field 6: continuous_dump_config
+  if (_has_field_[6]) {
+    (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 8: shmem_size_bytes
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, shmem_size_bytes_, msg);
+  }
+
+  // Field 9: block_client
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, block_client_, msg);
+  }
+
+  // Field 14: block_client_timeout_us
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(14, block_client_timeout_us_, msg);
+  }
+
+  // Field 10: no_startup
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, no_startup_, msg);
+  }
+
+  // Field 11: no_running
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(11, no_running_, msg);
+  }
+
+  // Field 13: dump_at_max
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(13, dump_at_max_, msg);
+  }
+
+  // Field 18: disable_fork_teardown
+  if (_has_field_[18]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(18, disable_fork_teardown_, msg);
+  }
+
+  // Field 19: disable_vfork_detection
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, disable_vfork_detection_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig() = default;
+HeapprofdConfig_ContinuousDumpConfig::~HeapprofdConfig_ContinuousDumpConfig() = default;
+HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&) = default;
+HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(const HeapprofdConfig_ContinuousDumpConfig&) = default;
+HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept = default;
+HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(HeapprofdConfig_ContinuousDumpConfig&&) = default;
+
+bool HeapprofdConfig_ContinuousDumpConfig::operator==(const HeapprofdConfig_ContinuousDumpConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_phase_ms_, other.dump_phase_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_interval_ms_, other.dump_interval_ms_);
+}
+
+bool HeapprofdConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 5 /* dump_phase_ms */:
+        field.get(&dump_phase_ms_);
+        break;
+      case 6 /* dump_interval_ms */:
+        field.get(&dump_interval_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string HeapprofdConfig_ContinuousDumpConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> HeapprofdConfig_ContinuousDumpConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void HeapprofdConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
+  // Field 5: dump_phase_ms
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, dump_phase_ms_, msg);
+  }
+
+  // Field 6: dump_interval_ms
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, dump_interval_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+JavaHprofConfig::JavaHprofConfig() = default;
+JavaHprofConfig::~JavaHprofConfig() = default;
+JavaHprofConfig::JavaHprofConfig(const JavaHprofConfig&) = default;
+JavaHprofConfig& JavaHprofConfig::operator=(const JavaHprofConfig&) = default;
+JavaHprofConfig::JavaHprofConfig(JavaHprofConfig&&) noexcept = default;
+JavaHprofConfig& JavaHprofConfig::operator=(JavaHprofConfig&&) = default;
+
+bool JavaHprofConfig::operator==(const JavaHprofConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_cmdline_, other.process_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_installed_by_, other.target_installed_by_)
+   && ::protozero::internal::gen_helpers::EqualsField(continuous_dump_config_, other.continuous_dump_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_anonymous_memory_kb_, other.min_anonymous_memory_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_smaps_, other.dump_smaps_)
+   && ::protozero::internal::gen_helpers::EqualsField(ignored_types_, other.ignored_types_);
+}
+
+bool JavaHprofConfig::ParseFromArray(const void* raw, size_t size) {
+  process_cmdline_.clear();
+  pid_.clear();
+  target_installed_by_.clear();
+  ignored_types_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* process_cmdline */:
+        process_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &process_cmdline_.back());
+        break;
+      case 2 /* pid */:
+        pid_.emplace_back();
+        field.get(&pid_.back());
+        break;
+      case 7 /* target_installed_by */:
+        target_installed_by_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &target_installed_by_.back());
+        break;
+      case 3 /* continuous_dump_config */:
+        (*continuous_dump_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* min_anonymous_memory_kb */:
+        field.get(&min_anonymous_memory_kb_);
+        break;
+      case 5 /* dump_smaps */:
+        field.get(&dump_smaps_);
+        break;
+      case 6 /* ignored_types */:
+        ignored_types_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &ignored_types_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string JavaHprofConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> JavaHprofConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void JavaHprofConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: process_cmdline
+  for (auto& it : process_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  // Field 2: pid
+  for (auto& it : pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 7: target_installed_by
+  for (auto& it : target_installed_by_) {
+    ::protozero::internal::gen_helpers::SerializeString(7, it, msg);
+  }
+
+  // Field 3: continuous_dump_config
+  if (_has_field_[3]) {
+    (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: min_anonymous_memory_kb
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, min_anonymous_memory_kb_, msg);
+  }
+
+  // Field 5: dump_smaps
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, dump_smaps_, msg);
+  }
+
+  // Field 6: ignored_types
+  for (auto& it : ignored_types_) {
+    ::protozero::internal::gen_helpers::SerializeString(6, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig() = default;
+JavaHprofConfig_ContinuousDumpConfig::~JavaHprofConfig_ContinuousDumpConfig() = default;
+JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&) = default;
+JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(const JavaHprofConfig_ContinuousDumpConfig&) = default;
+JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept = default;
+JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(JavaHprofConfig_ContinuousDumpConfig&&) = default;
+
+bool JavaHprofConfig_ContinuousDumpConfig::operator==(const JavaHprofConfig_ContinuousDumpConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_phase_ms_, other.dump_phase_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(dump_interval_ms_, other.dump_interval_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(scan_pids_only_on_start_, other.scan_pids_only_on_start_);
+}
+
+bool JavaHprofConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* dump_phase_ms */:
+        field.get(&dump_phase_ms_);
+        break;
+      case 2 /* dump_interval_ms */:
+        field.get(&dump_interval_ms_);
+        break;
+      case 3 /* scan_pids_only_on_start */:
+        field.get(&scan_pids_only_on_start_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string JavaHprofConfig_ContinuousDumpConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> JavaHprofConfig_ContinuousDumpConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void JavaHprofConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: dump_phase_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, dump_phase_ms_, msg);
+  }
+
+  // Field 2: dump_interval_ms
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, dump_interval_ms_, msg);
+  }
+
+  // Field 3: scan_pids_only_on_start
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, scan_pids_only_on_start_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+PerfEventConfig::PerfEventConfig() = default;
+PerfEventConfig::~PerfEventConfig() = default;
+PerfEventConfig::PerfEventConfig(const PerfEventConfig&) = default;
+PerfEventConfig& PerfEventConfig::operator=(const PerfEventConfig&) = default;
+PerfEventConfig::PerfEventConfig(PerfEventConfig&&) noexcept = default;
+PerfEventConfig& PerfEventConfig::operator=(PerfEventConfig&&) = default;
+
+bool PerfEventConfig::operator==(const PerfEventConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(timebase_, other.timebase_)
+   && ::protozero::internal::gen_helpers::EqualsField(callstack_sampling_, other.callstack_sampling_)
+   && ::protozero::internal::gen_helpers::EqualsField(ring_buffer_read_period_ms_, other.ring_buffer_read_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(ring_buffer_pages_, other.ring_buffer_pages_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_enqueued_footprint_kb_, other.max_enqueued_footprint_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_daemon_memory_kb_, other.max_daemon_memory_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(remote_descriptor_timeout_ms_, other.remote_descriptor_timeout_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(unwind_state_clear_period_ms_, other.unwind_state_clear_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_installed_by_, other.target_installed_by_)
+   && ::protozero::internal::gen_helpers::EqualsField(all_cpus_, other.all_cpus_)
+   && ::protozero::internal::gen_helpers::EqualsField(sampling_frequency_, other.sampling_frequency_)
+   && ::protozero::internal::gen_helpers::EqualsField(kernel_frames_, other.kernel_frames_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_pid_, other.target_pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_cmdline_, other.target_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(exclude_pid_, other.exclude_pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(exclude_cmdline_, other.exclude_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(additional_cmdline_count_, other.additional_cmdline_count_);
+}
+
+bool PerfEventConfig::ParseFromArray(const void* raw, size_t size) {
+  target_installed_by_.clear();
+  target_pid_.clear();
+  target_cmdline_.clear();
+  exclude_pid_.clear();
+  exclude_cmdline_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 15 /* timebase */:
+        (*timebase_).ParseFromArray(field.data(), field.size());
+        break;
+      case 16 /* callstack_sampling */:
+        (*callstack_sampling_).ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* ring_buffer_read_period_ms */:
+        field.get(&ring_buffer_read_period_ms_);
+        break;
+      case 3 /* ring_buffer_pages */:
+        field.get(&ring_buffer_pages_);
+        break;
+      case 17 /* max_enqueued_footprint_kb */:
+        field.get(&max_enqueued_footprint_kb_);
+        break;
+      case 13 /* max_daemon_memory_kb */:
+        field.get(&max_daemon_memory_kb_);
+        break;
+      case 9 /* remote_descriptor_timeout_ms */:
+        field.get(&remote_descriptor_timeout_ms_);
+        break;
+      case 10 /* unwind_state_clear_period_ms */:
+        field.get(&unwind_state_clear_period_ms_);
+        break;
+      case 18 /* target_installed_by */:
+        target_installed_by_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &target_installed_by_.back());
+        break;
+      case 1 /* all_cpus */:
+        field.get(&all_cpus_);
+        break;
+      case 2 /* sampling_frequency */:
+        field.get(&sampling_frequency_);
+        break;
+      case 12 /* kernel_frames */:
+        field.get(&kernel_frames_);
+        break;
+      case 4 /* target_pid */:
+        target_pid_.emplace_back();
+        field.get(&target_pid_.back());
+        break;
+      case 5 /* target_cmdline */:
+        target_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &target_cmdline_.back());
+        break;
+      case 6 /* exclude_pid */:
+        exclude_pid_.emplace_back();
+        field.get(&exclude_pid_.back());
+        break;
+      case 7 /* exclude_cmdline */:
+        exclude_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &exclude_cmdline_.back());
+        break;
+      case 11 /* additional_cmdline_count */:
+        field.get(&additional_cmdline_count_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEventConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEventConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEventConfig::Serialize(::protozero::Message* msg) const {
+  // Field 15: timebase
+  if (_has_field_[15]) {
+    (*timebase_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
+  }
+
+  // Field 16: callstack_sampling
+  if (_has_field_[16]) {
+    (*callstack_sampling_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
+  }
+
+  // Field 8: ring_buffer_read_period_ms
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, ring_buffer_read_period_ms_, msg);
+  }
+
+  // Field 3: ring_buffer_pages
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, ring_buffer_pages_, msg);
+  }
+
+  // Field 17: max_enqueued_footprint_kb
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, max_enqueued_footprint_kb_, msg);
+  }
+
+  // Field 13: max_daemon_memory_kb
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, max_daemon_memory_kb_, msg);
+  }
+
+  // Field 9: remote_descriptor_timeout_ms
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, remote_descriptor_timeout_ms_, msg);
+  }
+
+  // Field 10: unwind_state_clear_period_ms
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, unwind_state_clear_period_ms_, msg);
+  }
+
+  // Field 18: target_installed_by
+  for (auto& it : target_installed_by_) {
+    ::protozero::internal::gen_helpers::SerializeString(18, it, msg);
+  }
+
+  // Field 1: all_cpus
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, all_cpus_, msg);
+  }
+
+  // Field 2: sampling_frequency
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, sampling_frequency_, msg);
+  }
+
+  // Field 12: kernel_frames
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, kernel_frames_, msg);
+  }
+
+  // Field 4: target_pid
+  for (auto& it : target_pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, it, msg);
+  }
+
+  // Field 5: target_cmdline
+  for (auto& it : target_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(5, it, msg);
+  }
+
+  // Field 6: exclude_pid
+  for (auto& it : exclude_pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, it, msg);
+  }
+
+  // Field 7: exclude_cmdline
+  for (auto& it : exclude_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(7, it, msg);
+  }
+
+  // Field 11: additional_cmdline_count
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, additional_cmdline_count_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling() = default;
+PerfEventConfig_CallstackSampling::~PerfEventConfig_CallstackSampling() = default;
+PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling(const PerfEventConfig_CallstackSampling&) = default;
+PerfEventConfig_CallstackSampling& PerfEventConfig_CallstackSampling::operator=(const PerfEventConfig_CallstackSampling&) = default;
+PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling(PerfEventConfig_CallstackSampling&&) noexcept = default;
+PerfEventConfig_CallstackSampling& PerfEventConfig_CallstackSampling::operator=(PerfEventConfig_CallstackSampling&&) = default;
+
+bool PerfEventConfig_CallstackSampling::operator==(const PerfEventConfig_CallstackSampling& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(scope_, other.scope_)
+   && ::protozero::internal::gen_helpers::EqualsField(kernel_frames_, other.kernel_frames_)
+   && ::protozero::internal::gen_helpers::EqualsField(user_frames_, other.user_frames_);
+}
+
+bool PerfEventConfig_CallstackSampling::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* scope */:
+        (*scope_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* kernel_frames */:
+        field.get(&kernel_frames_);
+        break;
+      case 3 /* user_frames */:
+        field.get(&user_frames_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEventConfig_CallstackSampling::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEventConfig_CallstackSampling::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEventConfig_CallstackSampling::Serialize(::protozero::Message* msg) const {
+  // Field 1: scope
+  if (_has_field_[1]) {
+    (*scope_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: kernel_frames
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, kernel_frames_, msg);
+  }
+
+  // Field 3: user_frames
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, user_frames_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+PerfEventConfig_Scope::PerfEventConfig_Scope() = default;
+PerfEventConfig_Scope::~PerfEventConfig_Scope() = default;
+PerfEventConfig_Scope::PerfEventConfig_Scope(const PerfEventConfig_Scope&) = default;
+PerfEventConfig_Scope& PerfEventConfig_Scope::operator=(const PerfEventConfig_Scope&) = default;
+PerfEventConfig_Scope::PerfEventConfig_Scope(PerfEventConfig_Scope&&) noexcept = default;
+PerfEventConfig_Scope& PerfEventConfig_Scope::operator=(PerfEventConfig_Scope&&) = default;
+
+bool PerfEventConfig_Scope::operator==(const PerfEventConfig_Scope& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_pid_, other.target_pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_cmdline_, other.target_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(exclude_pid_, other.exclude_pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(exclude_cmdline_, other.exclude_cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(additional_cmdline_count_, other.additional_cmdline_count_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_shard_count_, other.process_shard_count_);
+}
+
+bool PerfEventConfig_Scope::ParseFromArray(const void* raw, size_t size) {
+  target_pid_.clear();
+  target_cmdline_.clear();
+  exclude_pid_.clear();
+  exclude_cmdline_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* target_pid */:
+        target_pid_.emplace_back();
+        field.get(&target_pid_.back());
+        break;
+      case 2 /* target_cmdline */:
+        target_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &target_cmdline_.back());
+        break;
+      case 3 /* exclude_pid */:
+        exclude_pid_.emplace_back();
+        field.get(&exclude_pid_.back());
+        break;
+      case 4 /* exclude_cmdline */:
+        exclude_cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &exclude_cmdline_.back());
+        break;
+      case 5 /* additional_cmdline_count */:
+        field.get(&additional_cmdline_count_);
+        break;
+      case 6 /* process_shard_count */:
+        field.get(&process_shard_count_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string PerfEventConfig_Scope::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> PerfEventConfig_Scope::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void PerfEventConfig_Scope::Serialize(::protozero::Message* msg) const {
+  // Field 1: target_pid
+  for (auto& it : target_pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 2: target_cmdline
+  for (auto& it : target_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: exclude_pid
+  for (auto& it : exclude_pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, it, msg);
+  }
+
+  // Field 4: exclude_cmdline
+  for (auto& it : exclude_cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
+  }
+
+  // Field 5: additional_cmdline_count
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, additional_cmdline_count_, msg);
+  }
+
+  // Field 6: process_shard_count
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, process_shard_count_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/atom_ids.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/statsd_tracing_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+StatsdPullAtomConfig::StatsdPullAtomConfig() = default;
+StatsdPullAtomConfig::~StatsdPullAtomConfig() = default;
+StatsdPullAtomConfig::StatsdPullAtomConfig(const StatsdPullAtomConfig&) = default;
+StatsdPullAtomConfig& StatsdPullAtomConfig::operator=(const StatsdPullAtomConfig&) = default;
+StatsdPullAtomConfig::StatsdPullAtomConfig(StatsdPullAtomConfig&&) noexcept = default;
+StatsdPullAtomConfig& StatsdPullAtomConfig::operator=(StatsdPullAtomConfig&&) = default;
+
+bool StatsdPullAtomConfig::operator==(const StatsdPullAtomConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(pull_atom_id_, other.pull_atom_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(raw_pull_atom_id_, other.raw_pull_atom_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(pull_frequency_ms_, other.pull_frequency_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(packages_, other.packages_);
+}
+
+bool StatsdPullAtomConfig::ParseFromArray(const void* raw, size_t size) {
+  pull_atom_id_.clear();
+  raw_pull_atom_id_.clear();
+  packages_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* pull_atom_id */:
+        pull_atom_id_.emplace_back();
+        field.get(&pull_atom_id_.back());
+        break;
+      case 2 /* raw_pull_atom_id */:
+        raw_pull_atom_id_.emplace_back();
+        field.get(&raw_pull_atom_id_.back());
+        break;
+      case 3 /* pull_frequency_ms */:
+        field.get(&pull_frequency_ms_);
+        break;
+      case 4 /* packages */:
+        packages_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &packages_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StatsdPullAtomConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StatsdPullAtomConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StatsdPullAtomConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: pull_atom_id
+  for (auto& it : pull_atom_id_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 2: raw_pull_atom_id
+  for (auto& it : raw_pull_atom_id_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: pull_frequency_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, pull_frequency_ms_, msg);
+  }
+
+  // Field 4: packages
+  for (auto& it : packages_) {
+    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+StatsdTracingConfig::StatsdTracingConfig() = default;
+StatsdTracingConfig::~StatsdTracingConfig() = default;
+StatsdTracingConfig::StatsdTracingConfig(const StatsdTracingConfig&) = default;
+StatsdTracingConfig& StatsdTracingConfig::operator=(const StatsdTracingConfig&) = default;
+StatsdTracingConfig::StatsdTracingConfig(StatsdTracingConfig&&) noexcept = default;
+StatsdTracingConfig& StatsdTracingConfig::operator=(StatsdTracingConfig&&) = default;
+
+bool StatsdTracingConfig::operator==(const StatsdTracingConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(push_atom_id_, other.push_atom_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(raw_push_atom_id_, other.raw_push_atom_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(pull_config_, other.pull_config_);
+}
+
+int StatsdTracingConfig::pull_config_size() const { return static_cast<int>(pull_config_.size()); }
+void StatsdTracingConfig::clear_pull_config() { pull_config_.clear(); }
+StatsdPullAtomConfig* StatsdTracingConfig::add_pull_config() { pull_config_.emplace_back(); return &pull_config_.back(); }
+bool StatsdTracingConfig::ParseFromArray(const void* raw, size_t size) {
+  push_atom_id_.clear();
+  raw_push_atom_id_.clear();
+  pull_config_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* push_atom_id */:
+        push_atom_id_.emplace_back();
+        field.get(&push_atom_id_.back());
+        break;
+      case 2 /* raw_push_atom_id */:
+        raw_push_atom_id_.emplace_back();
+        field.get(&raw_push_atom_id_.back());
+        break;
+      case 3 /* pull_config */:
+        pull_config_.emplace_back();
+        pull_config_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StatsdTracingConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StatsdTracingConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StatsdTracingConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: push_atom_id
+  for (auto& it : push_atom_id_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 2: raw_push_atom_id
+  for (auto& it : raw_push_atom_id_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: pull_config
+  for (auto& it : pull_config_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SysStatsConfig::SysStatsConfig() = default;
+SysStatsConfig::~SysStatsConfig() = default;
+SysStatsConfig::SysStatsConfig(const SysStatsConfig&) = default;
+SysStatsConfig& SysStatsConfig::operator=(const SysStatsConfig&) = default;
+SysStatsConfig::SysStatsConfig(SysStatsConfig&&) noexcept = default;
+SysStatsConfig& SysStatsConfig::operator=(SysStatsConfig&&) = default;
+
+bool SysStatsConfig::operator==(const SysStatsConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(meminfo_period_ms_, other.meminfo_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(meminfo_counters_, other.meminfo_counters_)
+   && ::protozero::internal::gen_helpers::EqualsField(vmstat_period_ms_, other.vmstat_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(vmstat_counters_, other.vmstat_counters_)
+   && ::protozero::internal::gen_helpers::EqualsField(stat_period_ms_, other.stat_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(stat_counters_, other.stat_counters_)
+   && ::protozero::internal::gen_helpers::EqualsField(devfreq_period_ms_, other.devfreq_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(cpufreq_period_ms_, other.cpufreq_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(buddyinfo_period_ms_, other.buddyinfo_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(diskstat_period_ms_, other.diskstat_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(psi_period_ms_, other.psi_period_ms_);
+}
+
+bool SysStatsConfig::ParseFromArray(const void* raw, size_t size) {
+  meminfo_counters_.clear();
+  vmstat_counters_.clear();
+  stat_counters_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* meminfo_period_ms */:
+        field.get(&meminfo_period_ms_);
+        break;
+      case 2 /* meminfo_counters */:
+        meminfo_counters_.emplace_back();
+        field.get(&meminfo_counters_.back());
+        break;
+      case 3 /* vmstat_period_ms */:
+        field.get(&vmstat_period_ms_);
+        break;
+      case 4 /* vmstat_counters */:
+        vmstat_counters_.emplace_back();
+        field.get(&vmstat_counters_.back());
+        break;
+      case 5 /* stat_period_ms */:
+        field.get(&stat_period_ms_);
+        break;
+      case 6 /* stat_counters */:
+        stat_counters_.emplace_back();
+        field.get(&stat_counters_.back());
+        break;
+      case 7 /* devfreq_period_ms */:
+        field.get(&devfreq_period_ms_);
+        break;
+      case 8 /* cpufreq_period_ms */:
+        field.get(&cpufreq_period_ms_);
+        break;
+      case 9 /* buddyinfo_period_ms */:
+        field.get(&buddyinfo_period_ms_);
+        break;
+      case 10 /* diskstat_period_ms */:
+        field.get(&diskstat_period_ms_);
+        break;
+      case 11 /* psi_period_ms */:
+        field.get(&psi_period_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SysStatsConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SysStatsConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SysStatsConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: meminfo_period_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, meminfo_period_ms_, msg);
+  }
+
+  // Field 2: meminfo_counters
+  for (auto& it : meminfo_counters_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
+  }
+
+  // Field 3: vmstat_period_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, vmstat_period_ms_, msg);
+  }
+
+  // Field 4: vmstat_counters
+  for (auto& it : vmstat_counters_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, it, msg);
+  }
+
+  // Field 5: stat_period_ms
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, stat_period_ms_, msg);
+  }
+
+  // Field 6: stat_counters
+  for (auto& it : stat_counters_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, it, msg);
+  }
+
+  // Field 7: devfreq_period_ms
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, devfreq_period_ms_, msg);
+  }
+
+  // Field 8: cpufreq_period_ms
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, cpufreq_period_ms_, msg);
+  }
+
+  // Field 9: buddyinfo_period_ms
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, buddyinfo_period_ms_, msg);
+  }
+
+  // Field 10: diskstat_period_ms
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, diskstat_period_ms_, msg);
+  }
+
+  // Field 11: psi_period_ms
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, psi_period_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/system_info/system_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SystemInfoConfig::SystemInfoConfig() = default;
+SystemInfoConfig::~SystemInfoConfig() = default;
+SystemInfoConfig::SystemInfoConfig(const SystemInfoConfig&) = default;
+SystemInfoConfig& SystemInfoConfig::operator=(const SystemInfoConfig&) = default;
+SystemInfoConfig::SystemInfoConfig(SystemInfoConfig&&) noexcept = default;
+SystemInfoConfig& SystemInfoConfig::operator=(SystemInfoConfig&&) = default;
+
+bool SystemInfoConfig::operator==(const SystemInfoConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool SystemInfoConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SystemInfoConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SystemInfoConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SystemInfoConfig::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TrackEventConfig::TrackEventConfig() = default;
+TrackEventConfig::~TrackEventConfig() = default;
+TrackEventConfig::TrackEventConfig(const TrackEventConfig&) = default;
+TrackEventConfig& TrackEventConfig::operator=(const TrackEventConfig&) = default;
+TrackEventConfig::TrackEventConfig(TrackEventConfig&&) noexcept = default;
+TrackEventConfig& TrackEventConfig::operator=(TrackEventConfig&&) = default;
+
+bool TrackEventConfig::operator==(const TrackEventConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(disabled_categories_, other.disabled_categories_)
+   && ::protozero::internal::gen_helpers::EqualsField(enabled_categories_, other.enabled_categories_)
+   && ::protozero::internal::gen_helpers::EqualsField(disabled_tags_, other.disabled_tags_)
+   && ::protozero::internal::gen_helpers::EqualsField(enabled_tags_, other.enabled_tags_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_incremental_timestamps_, other.disable_incremental_timestamps_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamp_unit_multiplier_, other.timestamp_unit_multiplier_)
+   && ::protozero::internal::gen_helpers::EqualsField(filter_debug_annotations_, other.filter_debug_annotations_)
+   && ::protozero::internal::gen_helpers::EqualsField(enable_thread_time_sampling_, other.enable_thread_time_sampling_)
+   && ::protozero::internal::gen_helpers::EqualsField(filter_dynamic_event_names_, other.filter_dynamic_event_names_);
+}
+
+bool TrackEventConfig::ParseFromArray(const void* raw, size_t size) {
+  disabled_categories_.clear();
+  enabled_categories_.clear();
+  disabled_tags_.clear();
+  enabled_tags_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* disabled_categories */:
+        disabled_categories_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &disabled_categories_.back());
+        break;
+      case 2 /* enabled_categories */:
+        enabled_categories_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &enabled_categories_.back());
+        break;
+      case 3 /* disabled_tags */:
+        disabled_tags_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &disabled_tags_.back());
+        break;
+      case 4 /* enabled_tags */:
+        enabled_tags_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &enabled_tags_.back());
+        break;
+      case 5 /* disable_incremental_timestamps */:
+        field.get(&disable_incremental_timestamps_);
+        break;
+      case 6 /* timestamp_unit_multiplier */:
+        field.get(&timestamp_unit_multiplier_);
+        break;
+      case 7 /* filter_debug_annotations */:
+        field.get(&filter_debug_annotations_);
+        break;
+      case 8 /* enable_thread_time_sampling */:
+        field.get(&enable_thread_time_sampling_);
+        break;
+      case 9 /* filter_dynamic_event_names */:
+        field.get(&filter_dynamic_event_names_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: disabled_categories
+  for (auto& it : disabled_categories_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  // Field 2: enabled_categories
+  for (auto& it : enabled_categories_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: disabled_tags
+  for (auto& it : disabled_tags_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  // Field 4: enabled_tags
+  for (auto& it : enabled_tags_) {
+    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
+  }
+
+  // Field 5: disable_incremental_timestamps
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, disable_incremental_timestamps_, msg);
+  }
+
+  // Field 6: timestamp_unit_multiplier
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, timestamp_unit_multiplier_, msg);
+  }
+
+  // Field 7: filter_debug_annotations
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, filter_debug_annotations_, msg);
+  }
+
+  // Field 8: enable_thread_time_sampling
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, enable_thread_time_sampling_, msg);
+  }
+
+  // Field 9: filter_dynamic_event_names
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, filter_dynamic_event_names_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeConfig::ChromeConfig() = default;
+ChromeConfig::~ChromeConfig() = default;
+ChromeConfig::ChromeConfig(const ChromeConfig&) = default;
+ChromeConfig& ChromeConfig::operator=(const ChromeConfig&) = default;
+ChromeConfig::ChromeConfig(ChromeConfig&&) noexcept = default;
+ChromeConfig& ChromeConfig::operator=(ChromeConfig&&) = default;
+
+bool ChromeConfig::operator==(const ChromeConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(privacy_filtering_enabled_, other.privacy_filtering_enabled_)
+   && ::protozero::internal::gen_helpers::EqualsField(convert_to_legacy_json_, other.convert_to_legacy_json_)
+   && ::protozero::internal::gen_helpers::EqualsField(client_priority_, other.client_priority_)
+   && ::protozero::internal::gen_helpers::EqualsField(json_agent_label_filter_, other.json_agent_label_filter_);
+}
+
+bool ChromeConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &trace_config_);
+        break;
+      case 2 /* privacy_filtering_enabled */:
+        field.get(&privacy_filtering_enabled_);
+        break;
+      case 3 /* convert_to_legacy_json */:
+        field.get(&convert_to_legacy_json_);
+        break;
+      case 4 /* client_priority */:
+        field.get(&client_priority_);
+        break;
+      case 5 /* json_agent_label_filter */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &json_agent_label_filter_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, trace_config_, msg);
+  }
+
+  // Field 2: privacy_filtering_enabled
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, privacy_filtering_enabled_, msg);
+  }
+
+  // Field 3: convert_to_legacy_json
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, convert_to_legacy_json_, msg);
+  }
+
+  // Field 4: client_priority
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, client_priority_, msg);
+  }
+
+  // Field 5: json_agent_label_filter
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeString(5, json_agent_label_filter_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/scenario_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/scenario_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeFieldTracingConfig::ChromeFieldTracingConfig() = default;
+ChromeFieldTracingConfig::~ChromeFieldTracingConfig() = default;
+ChromeFieldTracingConfig::ChromeFieldTracingConfig(const ChromeFieldTracingConfig&) = default;
+ChromeFieldTracingConfig& ChromeFieldTracingConfig::operator=(const ChromeFieldTracingConfig&) = default;
+ChromeFieldTracingConfig::ChromeFieldTracingConfig(ChromeFieldTracingConfig&&) noexcept = default;
+ChromeFieldTracingConfig& ChromeFieldTracingConfig::operator=(ChromeFieldTracingConfig&&) = default;
+
+bool ChromeFieldTracingConfig::operator==(const ChromeFieldTracingConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(scenarios_, other.scenarios_);
+}
+
+int ChromeFieldTracingConfig::scenarios_size() const { return static_cast<int>(scenarios_.size()); }
+void ChromeFieldTracingConfig::clear_scenarios() { scenarios_.clear(); }
+ScenarioConfig* ChromeFieldTracingConfig::add_scenarios() { scenarios_.emplace_back(); return &scenarios_.back(); }
+bool ChromeFieldTracingConfig::ParseFromArray(const void* raw, size_t size) {
+  scenarios_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* scenarios */:
+        scenarios_.emplace_back();
+        scenarios_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeFieldTracingConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeFieldTracingConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeFieldTracingConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: scenarios
+  for (auto& it : scenarios_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ScenarioConfig::ScenarioConfig() = default;
+ScenarioConfig::~ScenarioConfig() = default;
+ScenarioConfig::ScenarioConfig(const ScenarioConfig&) = default;
+ScenarioConfig& ScenarioConfig::operator=(const ScenarioConfig&) = default;
+ScenarioConfig::ScenarioConfig(ScenarioConfig&&) noexcept = default;
+ScenarioConfig& ScenarioConfig::operator=(ScenarioConfig&&) = default;
+
+bool ScenarioConfig::operator==(const ScenarioConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(scenario_name_, other.scenario_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_rules_, other.start_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(stop_rules_, other.stop_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(upload_rules_, other.upload_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(setup_rules_, other.setup_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(nested_scenarios_, other.nested_scenarios_);
+}
+
+int ScenarioConfig::start_rules_size() const { return static_cast<int>(start_rules_.size()); }
+void ScenarioConfig::clear_start_rules() { start_rules_.clear(); }
+TriggerRule* ScenarioConfig::add_start_rules() { start_rules_.emplace_back(); return &start_rules_.back(); }
+int ScenarioConfig::stop_rules_size() const { return static_cast<int>(stop_rules_.size()); }
+void ScenarioConfig::clear_stop_rules() { stop_rules_.clear(); }
+TriggerRule* ScenarioConfig::add_stop_rules() { stop_rules_.emplace_back(); return &stop_rules_.back(); }
+int ScenarioConfig::upload_rules_size() const { return static_cast<int>(upload_rules_.size()); }
+void ScenarioConfig::clear_upload_rules() { upload_rules_.clear(); }
+TriggerRule* ScenarioConfig::add_upload_rules() { upload_rules_.emplace_back(); return &upload_rules_.back(); }
+int ScenarioConfig::setup_rules_size() const { return static_cast<int>(setup_rules_.size()); }
+void ScenarioConfig::clear_setup_rules() { setup_rules_.clear(); }
+TriggerRule* ScenarioConfig::add_setup_rules() { setup_rules_.emplace_back(); return &setup_rules_.back(); }
+int ScenarioConfig::nested_scenarios_size() const { return static_cast<int>(nested_scenarios_.size()); }
+void ScenarioConfig::clear_nested_scenarios() { nested_scenarios_.clear(); }
+NestedScenarioConfig* ScenarioConfig::add_nested_scenarios() { nested_scenarios_.emplace_back(); return &nested_scenarios_.back(); }
+bool ScenarioConfig::ParseFromArray(const void* raw, size_t size) {
+  start_rules_.clear();
+  stop_rules_.clear();
+  upload_rules_.clear();
+  setup_rules_.clear();
+  nested_scenarios_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* scenario_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &scenario_name_);
+        break;
+      case 2 /* start_rules */:
+        start_rules_.emplace_back();
+        start_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* stop_rules */:
+        stop_rules_.emplace_back();
+        stop_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* upload_rules */:
+        upload_rules_.emplace_back();
+        upload_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* setup_rules */:
+        setup_rules_.emplace_back();
+        setup_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* trace_config */:
+        (*trace_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* nested_scenarios */:
+        nested_scenarios_.emplace_back();
+        nested_scenarios_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ScenarioConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ScenarioConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ScenarioConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: scenario_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, scenario_name_, msg);
+  }
+
+  // Field 2: start_rules
+  for (auto& it : start_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: stop_rules
+  for (auto& it : stop_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: upload_rules
+  for (auto& it : upload_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: setup_rules
+  for (auto& it : setup_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 6: trace_config
+  if (_has_field_[6]) {
+    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 7: nested_scenarios
+  for (auto& it : nested_scenarios_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+NestedScenarioConfig::NestedScenarioConfig() = default;
+NestedScenarioConfig::~NestedScenarioConfig() = default;
+NestedScenarioConfig::NestedScenarioConfig(const NestedScenarioConfig&) = default;
+NestedScenarioConfig& NestedScenarioConfig::operator=(const NestedScenarioConfig&) = default;
+NestedScenarioConfig::NestedScenarioConfig(NestedScenarioConfig&&) noexcept = default;
+NestedScenarioConfig& NestedScenarioConfig::operator=(NestedScenarioConfig&&) = default;
+
+bool NestedScenarioConfig::operator==(const NestedScenarioConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(scenario_name_, other.scenario_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_rules_, other.start_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(stop_rules_, other.stop_rules_)
+   && ::protozero::internal::gen_helpers::EqualsField(upload_rules_, other.upload_rules_);
+}
+
+int NestedScenarioConfig::start_rules_size() const { return static_cast<int>(start_rules_.size()); }
+void NestedScenarioConfig::clear_start_rules() { start_rules_.clear(); }
+TriggerRule* NestedScenarioConfig::add_start_rules() { start_rules_.emplace_back(); return &start_rules_.back(); }
+int NestedScenarioConfig::stop_rules_size() const { return static_cast<int>(stop_rules_.size()); }
+void NestedScenarioConfig::clear_stop_rules() { stop_rules_.clear(); }
+TriggerRule* NestedScenarioConfig::add_stop_rules() { stop_rules_.emplace_back(); return &stop_rules_.back(); }
+int NestedScenarioConfig::upload_rules_size() const { return static_cast<int>(upload_rules_.size()); }
+void NestedScenarioConfig::clear_upload_rules() { upload_rules_.clear(); }
+TriggerRule* NestedScenarioConfig::add_upload_rules() { upload_rules_.emplace_back(); return &upload_rules_.back(); }
+bool NestedScenarioConfig::ParseFromArray(const void* raw, size_t size) {
+  start_rules_.clear();
+  stop_rules_.clear();
+  upload_rules_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* scenario_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &scenario_name_);
+        break;
+      case 2 /* start_rules */:
+        start_rules_.emplace_back();
+        start_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* stop_rules */:
+        stop_rules_.emplace_back();
+        stop_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* upload_rules */:
+        upload_rules_.emplace_back();
+        upload_rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NestedScenarioConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NestedScenarioConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NestedScenarioConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: scenario_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, scenario_name_, msg);
+  }
+
+  // Field 2: start_rules
+  for (auto& it : start_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: stop_rules
+  for (auto& it : stop_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: upload_rules
+  for (auto& it : upload_rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TriggerRule::TriggerRule() = default;
+TriggerRule::~TriggerRule() = default;
+TriggerRule::TriggerRule(const TriggerRule&) = default;
+TriggerRule& TriggerRule::operator=(const TriggerRule&) = default;
+TriggerRule::TriggerRule(TriggerRule&&) noexcept = default;
+TriggerRule& TriggerRule::operator=(TriggerRule&&) = default;
+
+bool TriggerRule::operator==(const TriggerRule& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(trigger_chance_, other.trigger_chance_)
+   && ::protozero::internal::gen_helpers::EqualsField(delay_ms_, other.delay_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(activation_delay_ms_, other.activation_delay_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(manual_trigger_name_, other.manual_trigger_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(histogram_, other.histogram_)
+   && ::protozero::internal::gen_helpers::EqualsField(repeating_interval_, other.repeating_interval_);
+}
+
+bool TriggerRule::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* trigger_chance */:
+        field.get(&trigger_chance_);
+        break;
+      case 3 /* delay_ms */:
+        field.get(&delay_ms_);
+        break;
+      case 8 /* activation_delay_ms */:
+        field.get(&activation_delay_ms_);
+        break;
+      case 4 /* manual_trigger_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &manual_trigger_name_);
+        break;
+      case 5 /* histogram */:
+        (*histogram_).ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* repeating_interval */:
+        (*repeating_interval_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TriggerRule::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TriggerRule::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TriggerRule::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: trigger_chance
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(2, trigger_chance_, msg);
+  }
+
+  // Field 3: delay_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, delay_ms_, msg);
+  }
+
+  // Field 8: activation_delay_ms
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, activation_delay_ms_, msg);
+  }
+
+  // Field 4: manual_trigger_name
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, manual_trigger_name_, msg);
+  }
+
+  // Field 5: histogram
+  if (_has_field_[5]) {
+    (*histogram_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 6: repeating_interval
+  if (_has_field_[6]) {
+    (*repeating_interval_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TriggerRule_RepeatingInterval::TriggerRule_RepeatingInterval() = default;
+TriggerRule_RepeatingInterval::~TriggerRule_RepeatingInterval() = default;
+TriggerRule_RepeatingInterval::TriggerRule_RepeatingInterval(const TriggerRule_RepeatingInterval&) = default;
+TriggerRule_RepeatingInterval& TriggerRule_RepeatingInterval::operator=(const TriggerRule_RepeatingInterval&) = default;
+TriggerRule_RepeatingInterval::TriggerRule_RepeatingInterval(TriggerRule_RepeatingInterval&&) noexcept = default;
+TriggerRule_RepeatingInterval& TriggerRule_RepeatingInterval::operator=(TriggerRule_RepeatingInterval&&) = default;
+
+bool TriggerRule_RepeatingInterval::operator==(const TriggerRule_RepeatingInterval& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(period_ms_, other.period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(randomized_, other.randomized_);
+}
+
+bool TriggerRule_RepeatingInterval::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* period_ms */:
+        field.get(&period_ms_);
+        break;
+      case 2 /* randomized */:
+        field.get(&randomized_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TriggerRule_RepeatingInterval::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TriggerRule_RepeatingInterval::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TriggerRule_RepeatingInterval::Serialize(::protozero::Message* msg) const {
+  // Field 1: period_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, period_ms_, msg);
+  }
+
+  // Field 2: randomized
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, randomized_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TriggerRule_HistogramTrigger::TriggerRule_HistogramTrigger() = default;
+TriggerRule_HistogramTrigger::~TriggerRule_HistogramTrigger() = default;
+TriggerRule_HistogramTrigger::TriggerRule_HistogramTrigger(const TriggerRule_HistogramTrigger&) = default;
+TriggerRule_HistogramTrigger& TriggerRule_HistogramTrigger::operator=(const TriggerRule_HistogramTrigger&) = default;
+TriggerRule_HistogramTrigger::TriggerRule_HistogramTrigger(TriggerRule_HistogramTrigger&&) noexcept = default;
+TriggerRule_HistogramTrigger& TriggerRule_HistogramTrigger::operator=(TriggerRule_HistogramTrigger&&) = default;
+
+bool TriggerRule_HistogramTrigger::operator==(const TriggerRule_HistogramTrigger& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(histogram_name_, other.histogram_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_value_, other.min_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_value_, other.max_value_);
+}
+
+bool TriggerRule_HistogramTrigger::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* histogram_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &histogram_name_);
+        break;
+      case 2 /* min_value */:
+        field.get(&min_value_);
+        break;
+      case 3 /* max_value */:
+        field.get(&max_value_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TriggerRule_HistogramTrigger::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TriggerRule_HistogramTrigger::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TriggerRule_HistogramTrigger::Serialize(::protozero::Message* msg) const {
+  // Field 1: histogram_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, histogram_name_, msg);
+  }
+
+  // Field 2: min_value
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, min_value_, msg);
+  }
+
+  // Field 3: max_value
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, max_value_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+DataSourceConfig::DataSourceConfig() = default;
+DataSourceConfig::~DataSourceConfig() = default;
+DataSourceConfig::DataSourceConfig(const DataSourceConfig&) = default;
+DataSourceConfig& DataSourceConfig::operator=(const DataSourceConfig&) = default;
+DataSourceConfig::DataSourceConfig(DataSourceConfig&&) noexcept = default;
+DataSourceConfig& DataSourceConfig::operator=(DataSourceConfig&&) = default;
+
+bool DataSourceConfig::operator==(const DataSourceConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_duration_ms_, other.trace_duration_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(prefer_suspend_clock_for_duration_, other.prefer_suspend_clock_for_duration_)
+   && ::protozero::internal::gen_helpers::EqualsField(stop_timeout_ms_, other.stop_timeout_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(enable_extra_guardrails_, other.enable_extra_guardrails_)
+   && ::protozero::internal::gen_helpers::EqualsField(session_initiator_, other.session_initiator_)
+   && ::protozero::internal::gen_helpers::EqualsField(tracing_session_id_, other.tracing_session_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(ftrace_config_, other.ftrace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(inode_file_config_, other.inode_file_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_stats_config_, other.process_stats_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(sys_stats_config_, other.sys_stats_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(heapprofd_config_, other.heapprofd_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(java_hprof_config_, other.java_hprof_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_power_config_, other.android_power_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_log_config_, other.android_log_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(gpu_counter_config_, other.gpu_counter_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_game_intervention_list_config_, other.android_game_intervention_list_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(packages_list_config_, other.packages_list_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(perf_event_config_, other.perf_event_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(vulkan_memory_config_, other.vulkan_memory_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_event_config_, other.track_event_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_polled_state_config_, other.android_polled_state_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_system_property_config_, other.android_system_property_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(statsd_tracing_config_, other.statsd_tracing_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(system_info_config_, other.system_info_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_config_, other.chrome_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(interceptor_config_, other.interceptor_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(network_packet_trace_config_, other.network_packet_trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(surfaceflinger_layers_config_, other.surfaceflinger_layers_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(surfaceflinger_transactions_config_, other.surfaceflinger_transactions_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_sdk_sysprop_guard_config_, other.android_sdk_sysprop_guard_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(etw_config_, other.etw_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_config_, other.legacy_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(for_testing_, other.for_testing_);
+}
+
+bool DataSourceConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* target_buffer */:
+        field.get(&target_buffer_);
+        break;
+      case 3 /* trace_duration_ms */:
+        field.get(&trace_duration_ms_);
+        break;
+      case 122 /* prefer_suspend_clock_for_duration */:
+        field.get(&prefer_suspend_clock_for_duration_);
+        break;
+      case 7 /* stop_timeout_ms */:
+        field.get(&stop_timeout_ms_);
+        break;
+      case 6 /* enable_extra_guardrails */:
+        field.get(&enable_extra_guardrails_);
+        break;
+      case 8 /* session_initiator */:
+        field.get(&session_initiator_);
+        break;
+      case 4 /* tracing_session_id */:
+        field.get(&tracing_session_id_);
+        break;
+      case 100 /* ftrace_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &ftrace_config_);
+        break;
+      case 102 /* inode_file_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &inode_file_config_);
+        break;
+      case 103 /* process_stats_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &process_stats_config_);
+        break;
+      case 104 /* sys_stats_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &sys_stats_config_);
+        break;
+      case 105 /* heapprofd_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &heapprofd_config_);
+        break;
+      case 110 /* java_hprof_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &java_hprof_config_);
+        break;
+      case 106 /* android_power_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_power_config_);
+        break;
+      case 107 /* android_log_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_log_config_);
+        break;
+      case 108 /* gpu_counter_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &gpu_counter_config_);
+        break;
+      case 116 /* android_game_intervention_list_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_game_intervention_list_config_);
+        break;
+      case 109 /* packages_list_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &packages_list_config_);
+        break;
+      case 111 /* perf_event_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &perf_event_config_);
+        break;
+      case 112 /* vulkan_memory_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &vulkan_memory_config_);
+        break;
+      case 113 /* track_event_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &track_event_config_);
+        break;
+      case 114 /* android_polled_state_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_polled_state_config_);
+        break;
+      case 118 /* android_system_property_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_system_property_config_);
+        break;
+      case 117 /* statsd_tracing_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &statsd_tracing_config_);
+        break;
+      case 119 /* system_info_config */:
+        (*system_info_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 101 /* chrome_config */:
+        (*chrome_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 115 /* interceptor_config */:
+        (*interceptor_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 120 /* network_packet_trace_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &network_packet_trace_config_);
+        break;
+      case 121 /* surfaceflinger_layers_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &surfaceflinger_layers_config_);
+        break;
+      case 123 /* surfaceflinger_transactions_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &surfaceflinger_transactions_config_);
+        break;
+      case 124 /* android_sdk_sysprop_guard_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &android_sdk_sysprop_guard_config_);
+        break;
+      case 125 /* etw_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &etw_config_);
+        break;
+      case 1000 /* legacy_config */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &legacy_config_);
+        break;
+      case 1001 /* for_testing */:
+        (*for_testing_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DataSourceConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DataSourceConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DataSourceConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: target_buffer
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, target_buffer_, msg);
+  }
+
+  // Field 3: trace_duration_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, trace_duration_ms_, msg);
+  }
+
+  // Field 122: prefer_suspend_clock_for_duration
+  if (_has_field_[122]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(122, prefer_suspend_clock_for_duration_, msg);
+  }
+
+  // Field 7: stop_timeout_ms
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, stop_timeout_ms_, msg);
+  }
+
+  // Field 6: enable_extra_guardrails
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, enable_extra_guardrails_, msg);
+  }
+
+  // Field 8: session_initiator
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, session_initiator_, msg);
+  }
+
+  // Field 4: tracing_session_id
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, tracing_session_id_, msg);
+  }
+
+  // Field 100: ftrace_config
+  if (_has_field_[100]) {
+    msg->AppendString(100, ftrace_config_);
+  }
+
+  // Field 102: inode_file_config
+  if (_has_field_[102]) {
+    msg->AppendString(102, inode_file_config_);
+  }
+
+  // Field 103: process_stats_config
+  if (_has_field_[103]) {
+    msg->AppendString(103, process_stats_config_);
+  }
+
+  // Field 104: sys_stats_config
+  if (_has_field_[104]) {
+    msg->AppendString(104, sys_stats_config_);
+  }
+
+  // Field 105: heapprofd_config
+  if (_has_field_[105]) {
+    msg->AppendString(105, heapprofd_config_);
+  }
+
+  // Field 110: java_hprof_config
+  if (_has_field_[110]) {
+    msg->AppendString(110, java_hprof_config_);
+  }
+
+  // Field 106: android_power_config
+  if (_has_field_[106]) {
+    msg->AppendString(106, android_power_config_);
+  }
+
+  // Field 107: android_log_config
+  if (_has_field_[107]) {
+    msg->AppendString(107, android_log_config_);
+  }
+
+  // Field 108: gpu_counter_config
+  if (_has_field_[108]) {
+    msg->AppendString(108, gpu_counter_config_);
+  }
+
+  // Field 116: android_game_intervention_list_config
+  if (_has_field_[116]) {
+    msg->AppendString(116, android_game_intervention_list_config_);
+  }
+
+  // Field 109: packages_list_config
+  if (_has_field_[109]) {
+    msg->AppendString(109, packages_list_config_);
+  }
+
+  // Field 111: perf_event_config
+  if (_has_field_[111]) {
+    msg->AppendString(111, perf_event_config_);
+  }
+
+  // Field 112: vulkan_memory_config
+  if (_has_field_[112]) {
+    msg->AppendString(112, vulkan_memory_config_);
+  }
+
+  // Field 113: track_event_config
+  if (_has_field_[113]) {
+    msg->AppendString(113, track_event_config_);
+  }
+
+  // Field 114: android_polled_state_config
+  if (_has_field_[114]) {
+    msg->AppendString(114, android_polled_state_config_);
+  }
+
+  // Field 118: android_system_property_config
+  if (_has_field_[118]) {
+    msg->AppendString(118, android_system_property_config_);
+  }
+
+  // Field 117: statsd_tracing_config
+  if (_has_field_[117]) {
+    msg->AppendString(117, statsd_tracing_config_);
+  }
+
+  // Field 119: system_info_config
+  if (_has_field_[119]) {
+    (*system_info_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(119));
+  }
+
+  // Field 101: chrome_config
+  if (_has_field_[101]) {
+    (*chrome_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(101));
+  }
+
+  // Field 115: interceptor_config
+  if (_has_field_[115]) {
+    (*interceptor_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(115));
+  }
+
+  // Field 120: network_packet_trace_config
+  if (_has_field_[120]) {
+    msg->AppendString(120, network_packet_trace_config_);
+  }
+
+  // Field 121: surfaceflinger_layers_config
+  if (_has_field_[121]) {
+    msg->AppendString(121, surfaceflinger_layers_config_);
+  }
+
+  // Field 123: surfaceflinger_transactions_config
+  if (_has_field_[123]) {
+    msg->AppendString(123, surfaceflinger_transactions_config_);
+  }
+
+  // Field 124: android_sdk_sysprop_guard_config
+  if (_has_field_[124]) {
+    msg->AppendString(124, android_sdk_sysprop_guard_config_);
+  }
+
+  // Field 125: etw_config
+  if (_has_field_[125]) {
+    msg->AppendString(125, etw_config_);
+  }
+
+  // Field 1000: legacy_config
+  if (_has_field_[1000]) {
+    ::protozero::internal::gen_helpers::SerializeString(1000, legacy_config_, msg);
+  }
+
+  // Field 1001: for_testing
+  if (_has_field_[1001]) {
+    (*for_testing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1001));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/etw/etw_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+EtwConfig::EtwConfig() = default;
+EtwConfig::~EtwConfig() = default;
+EtwConfig::EtwConfig(const EtwConfig&) = default;
+EtwConfig& EtwConfig::operator=(const EtwConfig&) = default;
+EtwConfig::EtwConfig(EtwConfig&&) noexcept = default;
+EtwConfig& EtwConfig::operator=(EtwConfig&&) = default;
+
+bool EtwConfig::operator==(const EtwConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(kernel_flags_, other.kernel_flags_);
+}
+
+bool EtwConfig::ParseFromArray(const void* raw, size_t size) {
+  kernel_flags_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* kernel_flags */:
+        kernel_flags_.emplace_back();
+        field.get(&kernel_flags_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EtwConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EtwConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EtwConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: kernel_flags
+  for (auto& it : kernel_flags_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/interceptor_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+InterceptorConfig::InterceptorConfig() = default;
+InterceptorConfig::~InterceptorConfig() = default;
+InterceptorConfig::InterceptorConfig(const InterceptorConfig&) = default;
+InterceptorConfig& InterceptorConfig::operator=(const InterceptorConfig&) = default;
+InterceptorConfig::InterceptorConfig(InterceptorConfig&&) noexcept = default;
+InterceptorConfig& InterceptorConfig::operator=(InterceptorConfig&&) = default;
+
+bool InterceptorConfig::operator==(const InterceptorConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(console_config_, other.console_config_);
+}
+
+bool InterceptorConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 100 /* console_config */:
+        (*console_config_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InterceptorConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InterceptorConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InterceptorConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 100: console_config
+  if (_has_field_[100]) {
+    (*console_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(100));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/stress_test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+StressTestConfig::StressTestConfig() = default;
+StressTestConfig::~StressTestConfig() = default;
+StressTestConfig::StressTestConfig(const StressTestConfig&) = default;
+StressTestConfig& StressTestConfig::operator=(const StressTestConfig&) = default;
+StressTestConfig::StressTestConfig(StressTestConfig&&) noexcept = default;
+StressTestConfig& StressTestConfig::operator=(StressTestConfig&&) = default;
+
+bool StressTestConfig::operator==(const StressTestConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(shmem_size_kb_, other.shmem_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(shmem_page_size_kb_, other.shmem_page_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_processes_, other.num_processes_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_threads_, other.num_threads_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_events_, other.max_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(nesting_, other.nesting_)
+   && ::protozero::internal::gen_helpers::EqualsField(steady_state_timings_, other.steady_state_timings_)
+   && ::protozero::internal::gen_helpers::EqualsField(burst_period_ms_, other.burst_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(burst_duration_ms_, other.burst_duration_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(burst_timings_, other.burst_timings_);
+}
+
+bool StressTestConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_config */:
+        (*trace_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* shmem_size_kb */:
+        field.get(&shmem_size_kb_);
+        break;
+      case 3 /* shmem_page_size_kb */:
+        field.get(&shmem_page_size_kb_);
+        break;
+      case 4 /* num_processes */:
+        field.get(&num_processes_);
+        break;
+      case 5 /* num_threads */:
+        field.get(&num_threads_);
+        break;
+      case 6 /* max_events */:
+        field.get(&max_events_);
+        break;
+      case 7 /* nesting */:
+        field.get(&nesting_);
+        break;
+      case 8 /* steady_state_timings */:
+        (*steady_state_timings_).ParseFromArray(field.data(), field.size());
+        break;
+      case 9 /* burst_period_ms */:
+        field.get(&burst_period_ms_);
+        break;
+      case 10 /* burst_duration_ms */:
+        field.get(&burst_duration_ms_);
+        break;
+      case 11 /* burst_timings */:
+        (*burst_timings_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StressTestConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StressTestConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StressTestConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: shmem_size_kb
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, shmem_size_kb_, msg);
+  }
+
+  // Field 3: shmem_page_size_kb
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, shmem_page_size_kb_, msg);
+  }
+
+  // Field 4: num_processes
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, num_processes_, msg);
+  }
+
+  // Field 5: num_threads
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, num_threads_, msg);
+  }
+
+  // Field 6: max_events
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, max_events_, msg);
+  }
+
+  // Field 7: nesting
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, nesting_, msg);
+  }
+
+  // Field 8: steady_state_timings
+  if (_has_field_[8]) {
+    (*steady_state_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 9: burst_period_ms
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, burst_period_ms_, msg);
+  }
+
+  // Field 10: burst_duration_ms
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, burst_duration_ms_, msg);
+  }
+
+  // Field 11: burst_timings
+  if (_has_field_[11]) {
+    (*burst_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+StressTestConfig_WriterTiming::StressTestConfig_WriterTiming() = default;
+StressTestConfig_WriterTiming::~StressTestConfig_WriterTiming() = default;
+StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&) = default;
+StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(const StressTestConfig_WriterTiming&) = default;
+StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept = default;
+StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(StressTestConfig_WriterTiming&&) = default;
+
+bool StressTestConfig_WriterTiming::operator==(const StressTestConfig_WriterTiming& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(payload_mean_, other.payload_mean_)
+   && ::protozero::internal::gen_helpers::EqualsField(payload_stddev_, other.payload_stddev_)
+   && ::protozero::internal::gen_helpers::EqualsField(rate_mean_, other.rate_mean_)
+   && ::protozero::internal::gen_helpers::EqualsField(rate_stddev_, other.rate_stddev_)
+   && ::protozero::internal::gen_helpers::EqualsField(payload_write_time_ms_, other.payload_write_time_ms_);
+}
+
+bool StressTestConfig_WriterTiming::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* payload_mean */:
+        field.get(&payload_mean_);
+        break;
+      case 2 /* payload_stddev */:
+        field.get(&payload_stddev_);
+        break;
+      case 3 /* rate_mean */:
+        field.get(&rate_mean_);
+        break;
+      case 4 /* rate_stddev */:
+        field.get(&rate_stddev_);
+        break;
+      case 5 /* payload_write_time_ms */:
+        field.get(&payload_write_time_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StressTestConfig_WriterTiming::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StressTestConfig_WriterTiming::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StressTestConfig_WriterTiming::Serialize(::protozero::Message* msg) const {
+  // Field 1: payload_mean
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(1, payload_mean_, msg);
+  }
+
+  // Field 2: payload_stddev
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(2, payload_stddev_, msg);
+  }
+
+  // Field 3: rate_mean
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(3, rate_mean_, msg);
+  }
+
+  // Field 4: rate_stddev
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(4, rate_stddev_, msg);
+  }
+
+  // Field 5: payload_write_time_ms
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, payload_write_time_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/test_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TestConfig::TestConfig() = default;
+TestConfig::~TestConfig() = default;
+TestConfig::TestConfig(const TestConfig&) = default;
+TestConfig& TestConfig::operator=(const TestConfig&) = default;
+TestConfig::TestConfig(TestConfig&&) noexcept = default;
+TestConfig& TestConfig::operator=(TestConfig&&) = default;
+
+bool TestConfig::operator==(const TestConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_count_, other.message_count_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_messages_per_second_, other.max_messages_per_second_)
+   && ::protozero::internal::gen_helpers::EqualsField(seed_, other.seed_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_size_, other.message_size_)
+   && ::protozero::internal::gen_helpers::EqualsField(send_batch_on_register_, other.send_batch_on_register_)
+   && ::protozero::internal::gen_helpers::EqualsField(dummy_fields_, other.dummy_fields_);
+}
+
+bool TestConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* message_count */:
+        field.get(&message_count_);
+        break;
+      case 2 /* max_messages_per_second */:
+        field.get(&max_messages_per_second_);
+        break;
+      case 3 /* seed */:
+        field.get(&seed_);
+        break;
+      case 4 /* message_size */:
+        field.get(&message_size_);
+        break;
+      case 5 /* send_batch_on_register */:
+        field.get(&send_batch_on_register_);
+        break;
+      case 6 /* dummy_fields */:
+        (*dummy_fields_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TestConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TestConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TestConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: message_count
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, message_count_, msg);
+  }
+
+  // Field 2: max_messages_per_second
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, max_messages_per_second_, msg);
+  }
+
+  // Field 3: seed
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, seed_, msg);
+  }
+
+  // Field 4: message_size
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, message_size_, msg);
+  }
+
+  // Field 5: send_batch_on_register
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, send_batch_on_register_, msg);
+  }
+
+  // Field 6: dummy_fields
+  if (_has_field_[6]) {
+    (*dummy_fields_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TestConfig_DummyFields::TestConfig_DummyFields() = default;
+TestConfig_DummyFields::~TestConfig_DummyFields() = default;
+TestConfig_DummyFields::TestConfig_DummyFields(const TestConfig_DummyFields&) = default;
+TestConfig_DummyFields& TestConfig_DummyFields::operator=(const TestConfig_DummyFields&) = default;
+TestConfig_DummyFields::TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept = default;
+TestConfig_DummyFields& TestConfig_DummyFields::operator=(TestConfig_DummyFields&&) = default;
+
+bool TestConfig_DummyFields::operator==(const TestConfig_DummyFields& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_uint32_, other.field_uint32_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_int32_, other.field_int32_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_uint64_, other.field_uint64_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_int64_, other.field_int64_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_fixed64_, other.field_fixed64_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_sfixed64_, other.field_sfixed64_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_fixed32_, other.field_fixed32_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_sfixed32_, other.field_sfixed32_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_double_, other.field_double_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_float_, other.field_float_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_sint64_, other.field_sint64_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_sint32_, other.field_sint32_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_string_, other.field_string_)
+   && ::protozero::internal::gen_helpers::EqualsField(field_bytes_, other.field_bytes_);
+}
+
+bool TestConfig_DummyFields::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* field_uint32 */:
+        field.get(&field_uint32_);
+        break;
+      case 2 /* field_int32 */:
+        field.get(&field_int32_);
+        break;
+      case 3 /* field_uint64 */:
+        field.get(&field_uint64_);
+        break;
+      case 4 /* field_int64 */:
+        field.get(&field_int64_);
+        break;
+      case 5 /* field_fixed64 */:
+        field.get(&field_fixed64_);
+        break;
+      case 6 /* field_sfixed64 */:
+        field.get(&field_sfixed64_);
+        break;
+      case 7 /* field_fixed32 */:
+        field.get(&field_fixed32_);
+        break;
+      case 8 /* field_sfixed32 */:
+        field.get(&field_sfixed32_);
+        break;
+      case 9 /* field_double */:
+        field.get(&field_double_);
+        break;
+      case 10 /* field_float */:
+        field.get(&field_float_);
+        break;
+      case 11 /* field_sint64 */:
+        field.get_signed(&field_sint64_);
+        break;
+      case 12 /* field_sint32 */:
+        field.get_signed(&field_sint32_);
+        break;
+      case 13 /* field_string */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &field_string_);
+        break;
+      case 14 /* field_bytes */:
+        field.get(&field_bytes_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TestConfig_DummyFields::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TestConfig_DummyFields::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TestConfig_DummyFields::Serialize(::protozero::Message* msg) const {
+  // Field 1: field_uint32
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, field_uint32_, msg);
+  }
+
+  // Field 2: field_int32
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, field_int32_, msg);
+  }
+
+  // Field 3: field_uint64
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, field_uint64_, msg);
+  }
+
+  // Field 4: field_int64
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, field_int64_, msg);
+  }
+
+  // Field 5: field_fixed64
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(5, field_fixed64_, msg);
+  }
+
+  // Field 6: field_sfixed64
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(6, field_sfixed64_, msg);
+  }
+
+  // Field 7: field_fixed32
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(7, field_fixed32_, msg);
+  }
+
+  // Field 8: field_sfixed32
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(8, field_sfixed32_, msg);
+  }
+
+  // Field 9: field_double
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(9, field_double_, msg);
+  }
+
+  // Field 10: field_float
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(10, field_float_, msg);
+  }
+
+  // Field 11: field_sint64
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeSignedVarInt(11, field_sint64_, msg);
+  }
+
+  // Field 12: field_sint32
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeSignedVarInt(12, field_sint32_, msg);
+  }
+
+  // Field 13: field_string
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeString(13, field_string_, msg);
+  }
+
+  // Field 14: field_bytes
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeString(14, field_bytes_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TraceConfig::TraceConfig() = default;
+TraceConfig::~TraceConfig() = default;
+TraceConfig::TraceConfig(const TraceConfig&) = default;
+TraceConfig& TraceConfig::operator=(const TraceConfig&) = default;
+TraceConfig::TraceConfig(TraceConfig&&) noexcept = default;
+TraceConfig& TraceConfig::operator=(TraceConfig&&) = default;
+
+bool TraceConfig::operator==(const TraceConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffers_, other.buffers_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_sources_, other.data_sources_)
+   && ::protozero::internal::gen_helpers::EqualsField(builtin_data_sources_, other.builtin_data_sources_)
+   && ::protozero::internal::gen_helpers::EqualsField(duration_ms_, other.duration_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(prefer_suspend_clock_for_duration_, other.prefer_suspend_clock_for_duration_)
+   && ::protozero::internal::gen_helpers::EqualsField(enable_extra_guardrails_, other.enable_extra_guardrails_)
+   && ::protozero::internal::gen_helpers::EqualsField(lockdown_mode_, other.lockdown_mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(producers_, other.producers_)
+   && ::protozero::internal::gen_helpers::EqualsField(statsd_metadata_, other.statsd_metadata_)
+   && ::protozero::internal::gen_helpers::EqualsField(write_into_file_, other.write_into_file_)
+   && ::protozero::internal::gen_helpers::EqualsField(output_path_, other.output_path_)
+   && ::protozero::internal::gen_helpers::EqualsField(file_write_period_ms_, other.file_write_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_file_size_bytes_, other.max_file_size_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(guardrail_overrides_, other.guardrail_overrides_)
+   && ::protozero::internal::gen_helpers::EqualsField(deferred_start_, other.deferred_start_)
+   && ::protozero::internal::gen_helpers::EqualsField(flush_period_ms_, other.flush_period_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(flush_timeout_ms_, other.flush_timeout_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_stop_timeout_ms_, other.data_source_stop_timeout_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(notify_traceur_, other.notify_traceur_)
+   && ::protozero::internal::gen_helpers::EqualsField(bugreport_score_, other.bugreport_score_)
+   && ::protozero::internal::gen_helpers::EqualsField(trigger_config_, other.trigger_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(activate_triggers_, other.activate_triggers_)
+   && ::protozero::internal::gen_helpers::EqualsField(incremental_state_config_, other.incremental_state_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(allow_user_build_tracing_, other.allow_user_build_tracing_)
+   && ::protozero::internal::gen_helpers::EqualsField(unique_session_name_, other.unique_session_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(compression_type_, other.compression_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(compress_from_cli_, other.compress_from_cli_)
+   && ::protozero::internal::gen_helpers::EqualsField(incident_report_config_, other.incident_report_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(statsd_logging_, other.statsd_logging_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_uuid_msb_, other.trace_uuid_msb_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_uuid_lsb_, other.trace_uuid_lsb_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_filter_, other.trace_filter_)
+   && ::protozero::internal::gen_helpers::EqualsField(android_report_config_, other.android_report_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(cmd_trace_start_delay_, other.cmd_trace_start_delay_);
+}
+
+int TraceConfig::buffers_size() const { return static_cast<int>(buffers_.size()); }
+void TraceConfig::clear_buffers() { buffers_.clear(); }
+TraceConfig_BufferConfig* TraceConfig::add_buffers() { buffers_.emplace_back(); return &buffers_.back(); }
+int TraceConfig::data_sources_size() const { return static_cast<int>(data_sources_.size()); }
+void TraceConfig::clear_data_sources() { data_sources_.clear(); }
+TraceConfig_DataSource* TraceConfig::add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
+int TraceConfig::producers_size() const { return static_cast<int>(producers_.size()); }
+void TraceConfig::clear_producers() { producers_.clear(); }
+TraceConfig_ProducerConfig* TraceConfig::add_producers() { producers_.emplace_back(); return &producers_.back(); }
+bool TraceConfig::ParseFromArray(const void* raw, size_t size) {
+  buffers_.clear();
+  data_sources_.clear();
+  producers_.clear();
+  activate_triggers_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* buffers */:
+        buffers_.emplace_back();
+        buffers_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* data_sources */:
+        data_sources_.emplace_back();
+        data_sources_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 20 /* builtin_data_sources */:
+        (*builtin_data_sources_).ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* duration_ms */:
+        field.get(&duration_ms_);
+        break;
+      case 36 /* prefer_suspend_clock_for_duration */:
+        field.get(&prefer_suspend_clock_for_duration_);
+        break;
+      case 4 /* enable_extra_guardrails */:
+        field.get(&enable_extra_guardrails_);
+        break;
+      case 5 /* lockdown_mode */:
+        field.get(&lockdown_mode_);
+        break;
+      case 6 /* producers */:
+        producers_.emplace_back();
+        producers_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* statsd_metadata */:
+        (*statsd_metadata_).ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* write_into_file */:
+        field.get(&write_into_file_);
+        break;
+      case 29 /* output_path */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &output_path_);
+        break;
+      case 9 /* file_write_period_ms */:
+        field.get(&file_write_period_ms_);
+        break;
+      case 10 /* max_file_size_bytes */:
+        field.get(&max_file_size_bytes_);
+        break;
+      case 11 /* guardrail_overrides */:
+        (*guardrail_overrides_).ParseFromArray(field.data(), field.size());
+        break;
+      case 12 /* deferred_start */:
+        field.get(&deferred_start_);
+        break;
+      case 13 /* flush_period_ms */:
+        field.get(&flush_period_ms_);
+        break;
+      case 14 /* flush_timeout_ms */:
+        field.get(&flush_timeout_ms_);
+        break;
+      case 23 /* data_source_stop_timeout_ms */:
+        field.get(&data_source_stop_timeout_ms_);
+        break;
+      case 16 /* notify_traceur */:
+        field.get(&notify_traceur_);
+        break;
+      case 30 /* bugreport_score */:
+        field.get(&bugreport_score_);
+        break;
+      case 17 /* trigger_config */:
+        (*trigger_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 18 /* activate_triggers */:
+        activate_triggers_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &activate_triggers_.back());
+        break;
+      case 21 /* incremental_state_config */:
+        (*incremental_state_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 19 /* allow_user_build_tracing */:
+        field.get(&allow_user_build_tracing_);
+        break;
+      case 22 /* unique_session_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &unique_session_name_);
+        break;
+      case 24 /* compression_type */:
+        field.get(&compression_type_);
+        break;
+      case 37 /* compress_from_cli */:
+        field.get(&compress_from_cli_);
+        break;
+      case 25 /* incident_report_config */:
+        (*incident_report_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 31 /* statsd_logging */:
+        field.get(&statsd_logging_);
+        break;
+      case 27 /* trace_uuid_msb */:
+        field.get(&trace_uuid_msb_);
+        break;
+      case 28 /* trace_uuid_lsb */:
+        field.get(&trace_uuid_lsb_);
+        break;
+      case 33 /* trace_filter */:
+        (*trace_filter_).ParseFromArray(field.data(), field.size());
+        break;
+      case 34 /* android_report_config */:
+        (*android_report_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 35 /* cmd_trace_start_delay */:
+        (*cmd_trace_start_delay_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: buffers
+  for (auto& it : buffers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: data_sources
+  for (auto& it : data_sources_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 20: builtin_data_sources
+  if (_has_field_[20]) {
+    (*builtin_data_sources_).Serialize(msg->BeginNestedMessage<::protozero::Message>(20));
+  }
+
+  // Field 3: duration_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, duration_ms_, msg);
+  }
+
+  // Field 36: prefer_suspend_clock_for_duration
+  if (_has_field_[36]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(36, prefer_suspend_clock_for_duration_, msg);
+  }
+
+  // Field 4: enable_extra_guardrails
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, enable_extra_guardrails_, msg);
+  }
+
+  // Field 5: lockdown_mode
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, lockdown_mode_, msg);
+  }
+
+  // Field 6: producers
+  for (auto& it : producers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 7: statsd_metadata
+  if (_has_field_[7]) {
+    (*statsd_metadata_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  // Field 8: write_into_file
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, write_into_file_, msg);
+  }
+
+  // Field 29: output_path
+  if (_has_field_[29]) {
+    ::protozero::internal::gen_helpers::SerializeString(29, output_path_, msg);
+  }
+
+  // Field 9: file_write_period_ms
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, file_write_period_ms_, msg);
+  }
+
+  // Field 10: max_file_size_bytes
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, max_file_size_bytes_, msg);
+  }
+
+  // Field 11: guardrail_overrides
+  if (_has_field_[11]) {
+    (*guardrail_overrides_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  // Field 12: deferred_start
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, deferred_start_, msg);
+  }
+
+  // Field 13: flush_period_ms
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, flush_period_ms_, msg);
+  }
+
+  // Field 14: flush_timeout_ms
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(14, flush_timeout_ms_, msg);
+  }
+
+  // Field 23: data_source_stop_timeout_ms
+  if (_has_field_[23]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(23, data_source_stop_timeout_ms_, msg);
+  }
+
+  // Field 16: notify_traceur
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(16, notify_traceur_, msg);
+  }
+
+  // Field 30: bugreport_score
+  if (_has_field_[30]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(30, bugreport_score_, msg);
+  }
+
+  // Field 17: trigger_config
+  if (_has_field_[17]) {
+    (*trigger_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
+  }
+
+  // Field 18: activate_triggers
+  for (auto& it : activate_triggers_) {
+    ::protozero::internal::gen_helpers::SerializeString(18, it, msg);
+  }
+
+  // Field 21: incremental_state_config
+  if (_has_field_[21]) {
+    (*incremental_state_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
+  }
+
+  // Field 19: allow_user_build_tracing
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, allow_user_build_tracing_, msg);
+  }
+
+  // Field 22: unique_session_name
+  if (_has_field_[22]) {
+    ::protozero::internal::gen_helpers::SerializeString(22, unique_session_name_, msg);
+  }
+
+  // Field 24: compression_type
+  if (_has_field_[24]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(24, compression_type_, msg);
+  }
+
+  // Field 37: compress_from_cli
+  if (_has_field_[37]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(37, compress_from_cli_, msg);
+  }
+
+  // Field 25: incident_report_config
+  if (_has_field_[25]) {
+    (*incident_report_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
+  }
+
+  // Field 31: statsd_logging
+  if (_has_field_[31]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(31, statsd_logging_, msg);
+  }
+
+  // Field 27: trace_uuid_msb
+  if (_has_field_[27]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(27, trace_uuid_msb_, msg);
+  }
+
+  // Field 28: trace_uuid_lsb
+  if (_has_field_[28]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(28, trace_uuid_lsb_, msg);
+  }
+
+  // Field 33: trace_filter
+  if (_has_field_[33]) {
+    (*trace_filter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(33));
+  }
+
+  // Field 34: android_report_config
+  if (_has_field_[34]) {
+    (*android_report_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(34));
+  }
+
+  // Field 35: cmd_trace_start_delay
+  if (_has_field_[35]) {
+    (*cmd_trace_start_delay_).Serialize(msg->BeginNestedMessage<::protozero::Message>(35));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_CmdTraceStartDelay::TraceConfig_CmdTraceStartDelay() = default;
+TraceConfig_CmdTraceStartDelay::~TraceConfig_CmdTraceStartDelay() = default;
+TraceConfig_CmdTraceStartDelay::TraceConfig_CmdTraceStartDelay(const TraceConfig_CmdTraceStartDelay&) = default;
+TraceConfig_CmdTraceStartDelay& TraceConfig_CmdTraceStartDelay::operator=(const TraceConfig_CmdTraceStartDelay&) = default;
+TraceConfig_CmdTraceStartDelay::TraceConfig_CmdTraceStartDelay(TraceConfig_CmdTraceStartDelay&&) noexcept = default;
+TraceConfig_CmdTraceStartDelay& TraceConfig_CmdTraceStartDelay::operator=(TraceConfig_CmdTraceStartDelay&&) = default;
+
+bool TraceConfig_CmdTraceStartDelay::operator==(const TraceConfig_CmdTraceStartDelay& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(min_delay_ms_, other.min_delay_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_delay_ms_, other.max_delay_ms_);
+}
+
+bool TraceConfig_CmdTraceStartDelay::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* min_delay_ms */:
+        field.get(&min_delay_ms_);
+        break;
+      case 2 /* max_delay_ms */:
+        field.get(&max_delay_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_CmdTraceStartDelay::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_CmdTraceStartDelay::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_CmdTraceStartDelay::Serialize(::protozero::Message* msg) const {
+  // Field 1: min_delay_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, min_delay_ms_, msg);
+  }
+
+  // Field 2: max_delay_ms
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, max_delay_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_AndroidReportConfig::TraceConfig_AndroidReportConfig() = default;
+TraceConfig_AndroidReportConfig::~TraceConfig_AndroidReportConfig() = default;
+TraceConfig_AndroidReportConfig::TraceConfig_AndroidReportConfig(const TraceConfig_AndroidReportConfig&) = default;
+TraceConfig_AndroidReportConfig& TraceConfig_AndroidReportConfig::operator=(const TraceConfig_AndroidReportConfig&) = default;
+TraceConfig_AndroidReportConfig::TraceConfig_AndroidReportConfig(TraceConfig_AndroidReportConfig&&) noexcept = default;
+TraceConfig_AndroidReportConfig& TraceConfig_AndroidReportConfig::operator=(TraceConfig_AndroidReportConfig&&) = default;
+
+bool TraceConfig_AndroidReportConfig::operator==(const TraceConfig_AndroidReportConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(reporter_service_package_, other.reporter_service_package_)
+   && ::protozero::internal::gen_helpers::EqualsField(reporter_service_class_, other.reporter_service_class_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_report_, other.skip_report_)
+   && ::protozero::internal::gen_helpers::EqualsField(use_pipe_in_framework_for_testing_, other.use_pipe_in_framework_for_testing_);
+}
+
+bool TraceConfig_AndroidReportConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* reporter_service_package */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &reporter_service_package_);
+        break;
+      case 2 /* reporter_service_class */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &reporter_service_class_);
+        break;
+      case 3 /* skip_report */:
+        field.get(&skip_report_);
+        break;
+      case 4 /* use_pipe_in_framework_for_testing */:
+        field.get(&use_pipe_in_framework_for_testing_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_AndroidReportConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_AndroidReportConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_AndroidReportConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: reporter_service_package
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, reporter_service_package_, msg);
+  }
+
+  // Field 2: reporter_service_class
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, reporter_service_class_, msg);
+  }
+
+  // Field 3: skip_report
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, skip_report_, msg);
+  }
+
+  // Field 4: use_pipe_in_framework_for_testing
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, use_pipe_in_framework_for_testing_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_TraceFilter::TraceConfig_TraceFilter() = default;
+TraceConfig_TraceFilter::~TraceConfig_TraceFilter() = default;
+TraceConfig_TraceFilter::TraceConfig_TraceFilter(const TraceConfig_TraceFilter&) = default;
+TraceConfig_TraceFilter& TraceConfig_TraceFilter::operator=(const TraceConfig_TraceFilter&) = default;
+TraceConfig_TraceFilter::TraceConfig_TraceFilter(TraceConfig_TraceFilter&&) noexcept = default;
+TraceConfig_TraceFilter& TraceConfig_TraceFilter::operator=(TraceConfig_TraceFilter&&) = default;
+
+bool TraceConfig_TraceFilter::operator==(const TraceConfig_TraceFilter& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytecode_, other.bytecode_)
+   && ::protozero::internal::gen_helpers::EqualsField(bytecode_v2_, other.bytecode_v2_)
+   && ::protozero::internal::gen_helpers::EqualsField(string_filter_chain_, other.string_filter_chain_);
+}
+
+bool TraceConfig_TraceFilter::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* bytecode */:
+        field.get(&bytecode_);
+        break;
+      case 2 /* bytecode_v2 */:
+        field.get(&bytecode_v2_);
+        break;
+      case 3 /* string_filter_chain */:
+        (*string_filter_chain_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TraceFilter::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TraceFilter::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TraceFilter::Serialize(::protozero::Message* msg) const {
+  // Field 1: bytecode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, bytecode_, msg);
+  }
+
+  // Field 2: bytecode_v2
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, bytecode_v2_, msg);
+  }
+
+  // Field 3: string_filter_chain
+  if (_has_field_[3]) {
+    (*string_filter_chain_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_TraceFilter_StringFilterChain::TraceConfig_TraceFilter_StringFilterChain() = default;
+TraceConfig_TraceFilter_StringFilterChain::~TraceConfig_TraceFilter_StringFilterChain() = default;
+TraceConfig_TraceFilter_StringFilterChain::TraceConfig_TraceFilter_StringFilterChain(const TraceConfig_TraceFilter_StringFilterChain&) = default;
+TraceConfig_TraceFilter_StringFilterChain& TraceConfig_TraceFilter_StringFilterChain::operator=(const TraceConfig_TraceFilter_StringFilterChain&) = default;
+TraceConfig_TraceFilter_StringFilterChain::TraceConfig_TraceFilter_StringFilterChain(TraceConfig_TraceFilter_StringFilterChain&&) noexcept = default;
+TraceConfig_TraceFilter_StringFilterChain& TraceConfig_TraceFilter_StringFilterChain::operator=(TraceConfig_TraceFilter_StringFilterChain&&) = default;
+
+bool TraceConfig_TraceFilter_StringFilterChain::operator==(const TraceConfig_TraceFilter_StringFilterChain& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(rules_, other.rules_);
+}
+
+int TraceConfig_TraceFilter_StringFilterChain::rules_size() const { return static_cast<int>(rules_.size()); }
+void TraceConfig_TraceFilter_StringFilterChain::clear_rules() { rules_.clear(); }
+TraceConfig_TraceFilter_StringFilterRule* TraceConfig_TraceFilter_StringFilterChain::add_rules() { rules_.emplace_back(); return &rules_.back(); }
+bool TraceConfig_TraceFilter_StringFilterChain::ParseFromArray(const void* raw, size_t size) {
+  rules_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* rules */:
+        rules_.emplace_back();
+        rules_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TraceFilter_StringFilterChain::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TraceFilter_StringFilterChain::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TraceFilter_StringFilterChain::Serialize(::protozero::Message* msg) const {
+  // Field 1: rules
+  for (auto& it : rules_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_TraceFilter_StringFilterRule::TraceConfig_TraceFilter_StringFilterRule() = default;
+TraceConfig_TraceFilter_StringFilterRule::~TraceConfig_TraceFilter_StringFilterRule() = default;
+TraceConfig_TraceFilter_StringFilterRule::TraceConfig_TraceFilter_StringFilterRule(const TraceConfig_TraceFilter_StringFilterRule&) = default;
+TraceConfig_TraceFilter_StringFilterRule& TraceConfig_TraceFilter_StringFilterRule::operator=(const TraceConfig_TraceFilter_StringFilterRule&) = default;
+TraceConfig_TraceFilter_StringFilterRule::TraceConfig_TraceFilter_StringFilterRule(TraceConfig_TraceFilter_StringFilterRule&&) noexcept = default;
+TraceConfig_TraceFilter_StringFilterRule& TraceConfig_TraceFilter_StringFilterRule::operator=(TraceConfig_TraceFilter_StringFilterRule&&) = default;
+
+bool TraceConfig_TraceFilter_StringFilterRule::operator==(const TraceConfig_TraceFilter_StringFilterRule& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(policy_, other.policy_)
+   && ::protozero::internal::gen_helpers::EqualsField(regex_pattern_, other.regex_pattern_)
+   && ::protozero::internal::gen_helpers::EqualsField(atrace_payload_starts_with_, other.atrace_payload_starts_with_);
+}
+
+bool TraceConfig_TraceFilter_StringFilterRule::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* policy */:
+        field.get(&policy_);
+        break;
+      case 2 /* regex_pattern */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &regex_pattern_);
+        break;
+      case 3 /* atrace_payload_starts_with */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &atrace_payload_starts_with_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TraceFilter_StringFilterRule::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TraceFilter_StringFilterRule::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TraceFilter_StringFilterRule::Serialize(::protozero::Message* msg) const {
+  // Field 1: policy
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, policy_, msg);
+  }
+
+  // Field 2: regex_pattern
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, regex_pattern_, msg);
+  }
+
+  // Field 3: atrace_payload_starts_with
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, atrace_payload_starts_with_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig() = default;
+TraceConfig_IncidentReportConfig::~TraceConfig_IncidentReportConfig() = default;
+TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(const TraceConfig_IncidentReportConfig&) = default;
+TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(const TraceConfig_IncidentReportConfig&) = default;
+TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(TraceConfig_IncidentReportConfig&&) noexcept = default;
+TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(TraceConfig_IncidentReportConfig&&) = default;
+
+bool TraceConfig_IncidentReportConfig::operator==(const TraceConfig_IncidentReportConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(destination_package_, other.destination_package_)
+   && ::protozero::internal::gen_helpers::EqualsField(destination_class_, other.destination_class_)
+   && ::protozero::internal::gen_helpers::EqualsField(privacy_level_, other.privacy_level_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_incidentd_, other.skip_incidentd_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_dropbox_, other.skip_dropbox_);
+}
+
+bool TraceConfig_IncidentReportConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* destination_package */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &destination_package_);
+        break;
+      case 2 /* destination_class */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &destination_class_);
+        break;
+      case 3 /* privacy_level */:
+        field.get(&privacy_level_);
+        break;
+      case 5 /* skip_incidentd */:
+        field.get(&skip_incidentd_);
+        break;
+      case 4 /* skip_dropbox */:
+        field.get(&skip_dropbox_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_IncidentReportConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_IncidentReportConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_IncidentReportConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: destination_package
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, destination_package_, msg);
+  }
+
+  // Field 2: destination_class
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, destination_class_, msg);
+  }
+
+  // Field 3: privacy_level
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, privacy_level_, msg);
+  }
+
+  // Field 5: skip_incidentd
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, skip_incidentd_, msg);
+  }
+
+  // Field 4: skip_dropbox
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, skip_dropbox_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig() = default;
+TraceConfig_IncrementalStateConfig::~TraceConfig_IncrementalStateConfig() = default;
+TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(const TraceConfig_IncrementalStateConfig&) = default;
+TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(const TraceConfig_IncrementalStateConfig&) = default;
+TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(TraceConfig_IncrementalStateConfig&&) noexcept = default;
+TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(TraceConfig_IncrementalStateConfig&&) = default;
+
+bool TraceConfig_IncrementalStateConfig::operator==(const TraceConfig_IncrementalStateConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(clear_period_ms_, other.clear_period_ms_);
+}
+
+bool TraceConfig_IncrementalStateConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* clear_period_ms */:
+        field.get(&clear_period_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_IncrementalStateConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_IncrementalStateConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_IncrementalStateConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: clear_period_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, clear_period_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_TriggerConfig::TraceConfig_TriggerConfig() = default;
+TraceConfig_TriggerConfig::~TraceConfig_TriggerConfig() = default;
+TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(const TraceConfig_TriggerConfig&) = default;
+TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(const TraceConfig_TriggerConfig&) = default;
+TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(TraceConfig_TriggerConfig&&) noexcept = default;
+TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(TraceConfig_TriggerConfig&&) = default;
+
+bool TraceConfig_TriggerConfig::operator==(const TraceConfig_TriggerConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trigger_mode_, other.trigger_mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(use_clone_snapshot_if_available_, other.use_clone_snapshot_if_available_)
+   && ::protozero::internal::gen_helpers::EqualsField(triggers_, other.triggers_)
+   && ::protozero::internal::gen_helpers::EqualsField(trigger_timeout_ms_, other.trigger_timeout_ms_);
+}
+
+int TraceConfig_TriggerConfig::triggers_size() const { return static_cast<int>(triggers_.size()); }
+void TraceConfig_TriggerConfig::clear_triggers() { triggers_.clear(); }
+TraceConfig_TriggerConfig_Trigger* TraceConfig_TriggerConfig::add_triggers() { triggers_.emplace_back(); return &triggers_.back(); }
+bool TraceConfig_TriggerConfig::ParseFromArray(const void* raw, size_t size) {
+  triggers_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trigger_mode */:
+        field.get(&trigger_mode_);
+        break;
+      case 5 /* use_clone_snapshot_if_available */:
+        field.get(&use_clone_snapshot_if_available_);
+        break;
+      case 2 /* triggers */:
+        triggers_.emplace_back();
+        triggers_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 3 /* trigger_timeout_ms */:
+        field.get(&trigger_timeout_ms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TriggerConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TriggerConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TriggerConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: trigger_mode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, trigger_mode_, msg);
+  }
+
+  // Field 5: use_clone_snapshot_if_available
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, use_clone_snapshot_if_available_, msg);
+  }
+
+  // Field 2: triggers
+  for (auto& it : triggers_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 3: trigger_timeout_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, trigger_timeout_ms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger() = default;
+TraceConfig_TriggerConfig_Trigger::~TraceConfig_TriggerConfig_Trigger() = default;
+TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(const TraceConfig_TriggerConfig_Trigger&) = default;
+TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(const TraceConfig_TriggerConfig_Trigger&) = default;
+TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(TraceConfig_TriggerConfig_Trigger&&) noexcept = default;
+TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(TraceConfig_TriggerConfig_Trigger&&) = default;
+
+bool TraceConfig_TriggerConfig_Trigger::operator==(const TraceConfig_TriggerConfig_Trigger& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_regex_, other.producer_name_regex_)
+   && ::protozero::internal::gen_helpers::EqualsField(stop_delay_ms_, other.stop_delay_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_per_24_h_, other.max_per_24_h_)
+   && ::protozero::internal::gen_helpers::EqualsField(skip_probability_, other.skip_probability_);
+}
+
+bool TraceConfig_TriggerConfig_Trigger::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* producer_name_regex */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_regex_);
+        break;
+      case 3 /* stop_delay_ms */:
+        field.get(&stop_delay_ms_);
+        break;
+      case 4 /* max_per_24_h */:
+        field.get(&max_per_24_h_);
+        break;
+      case 5 /* skip_probability */:
+        field.get(&skip_probability_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_TriggerConfig_Trigger::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_TriggerConfig_Trigger::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_TriggerConfig_Trigger::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  // Field 2: producer_name_regex
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, producer_name_regex_, msg);
+  }
+
+  // Field 3: stop_delay_ms
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, stop_delay_ms_, msg);
+  }
+
+  // Field 4: max_per_24_h
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, max_per_24_h_, msg);
+  }
+
+  // Field 5: skip_probability
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(5, skip_probability_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides() = default;
+TraceConfig_GuardrailOverrides::~TraceConfig_GuardrailOverrides() = default;
+TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(const TraceConfig_GuardrailOverrides&) = default;
+TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(const TraceConfig_GuardrailOverrides&) = default;
+TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(TraceConfig_GuardrailOverrides&&) noexcept = default;
+TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(TraceConfig_GuardrailOverrides&&) = default;
+
+bool TraceConfig_GuardrailOverrides::operator==(const TraceConfig_GuardrailOverrides& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_upload_per_day_bytes_, other.max_upload_per_day_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(max_tracing_buffer_size_kb_, other.max_tracing_buffer_size_kb_);
+}
+
+bool TraceConfig_GuardrailOverrides::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* max_upload_per_day_bytes */:
+        field.get(&max_upload_per_day_bytes_);
+        break;
+      case 2 /* max_tracing_buffer_size_kb */:
+        field.get(&max_tracing_buffer_size_kb_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_GuardrailOverrides::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_GuardrailOverrides::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_GuardrailOverrides::Serialize(::protozero::Message* msg) const {
+  // Field 1: max_upload_per_day_bytes
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, max_upload_per_day_bytes_, msg);
+  }
+
+  // Field 2: max_tracing_buffer_size_kb
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, max_tracing_buffer_size_kb_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata() = default;
+TraceConfig_StatsdMetadata::~TraceConfig_StatsdMetadata() = default;
+TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(const TraceConfig_StatsdMetadata&) = default;
+TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(const TraceConfig_StatsdMetadata&) = default;
+TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(TraceConfig_StatsdMetadata&&) noexcept = default;
+TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(TraceConfig_StatsdMetadata&&) = default;
+
+bool TraceConfig_StatsdMetadata::operator==(const TraceConfig_StatsdMetadata& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(triggering_alert_id_, other.triggering_alert_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(triggering_config_uid_, other.triggering_config_uid_)
+   && ::protozero::internal::gen_helpers::EqualsField(triggering_config_id_, other.triggering_config_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(triggering_subscription_id_, other.triggering_subscription_id_);
+}
+
+bool TraceConfig_StatsdMetadata::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* triggering_alert_id */:
+        field.get(&triggering_alert_id_);
+        break;
+      case 2 /* triggering_config_uid */:
+        field.get(&triggering_config_uid_);
+        break;
+      case 3 /* triggering_config_id */:
+        field.get(&triggering_config_id_);
+        break;
+      case 4 /* triggering_subscription_id */:
+        field.get(&triggering_subscription_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_StatsdMetadata::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_StatsdMetadata::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_StatsdMetadata::Serialize(::protozero::Message* msg) const {
+  // Field 1: triggering_alert_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, triggering_alert_id_, msg);
+  }
+
+  // Field 2: triggering_config_uid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, triggering_config_uid_, msg);
+  }
+
+  // Field 3: triggering_config_id
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, triggering_config_id_, msg);
+  }
+
+  // Field 4: triggering_subscription_id
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, triggering_subscription_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_ProducerConfig::TraceConfig_ProducerConfig() = default;
+TraceConfig_ProducerConfig::~TraceConfig_ProducerConfig() = default;
+TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(const TraceConfig_ProducerConfig&) = default;
+TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(const TraceConfig_ProducerConfig&) = default;
+TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(TraceConfig_ProducerConfig&&) noexcept = default;
+TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(TraceConfig_ProducerConfig&&) = default;
+
+bool TraceConfig_ProducerConfig::operator==(const TraceConfig_ProducerConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_, other.producer_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(shm_size_kb_, other.shm_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(page_size_kb_, other.page_size_kb_);
+}
+
+bool TraceConfig_ProducerConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* producer_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_);
+        break;
+      case 2 /* shm_size_kb */:
+        field.get(&shm_size_kb_);
+        break;
+      case 3 /* page_size_kb */:
+        field.get(&page_size_kb_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_ProducerConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_ProducerConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_ProducerConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: producer_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, producer_name_, msg);
+  }
+
+  // Field 2: shm_size_kb
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, shm_size_kb_, msg);
+  }
+
+  // Field 3: page_size_kb
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, page_size_kb_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource() = default;
+TraceConfig_BuiltinDataSource::~TraceConfig_BuiltinDataSource() = default;
+TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(const TraceConfig_BuiltinDataSource&) = default;
+TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(const TraceConfig_BuiltinDataSource&) = default;
+TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(TraceConfig_BuiltinDataSource&&) noexcept = default;
+TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(TraceConfig_BuiltinDataSource&&) = default;
+
+bool TraceConfig_BuiltinDataSource::operator==(const TraceConfig_BuiltinDataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_clock_snapshotting_, other.disable_clock_snapshotting_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_trace_config_, other.disable_trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_system_info_, other.disable_system_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_service_events_, other.disable_service_events_)
+   && ::protozero::internal::gen_helpers::EqualsField(primary_trace_clock_, other.primary_trace_clock_)
+   && ::protozero::internal::gen_helpers::EqualsField(snapshot_interval_ms_, other.snapshot_interval_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(prefer_suspend_clock_for_snapshot_, other.prefer_suspend_clock_for_snapshot_)
+   && ::protozero::internal::gen_helpers::EqualsField(disable_chunk_usage_histograms_, other.disable_chunk_usage_histograms_);
+}
+
+bool TraceConfig_BuiltinDataSource::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* disable_clock_snapshotting */:
+        field.get(&disable_clock_snapshotting_);
+        break;
+      case 2 /* disable_trace_config */:
+        field.get(&disable_trace_config_);
+        break;
+      case 3 /* disable_system_info */:
+        field.get(&disable_system_info_);
+        break;
+      case 4 /* disable_service_events */:
+        field.get(&disable_service_events_);
+        break;
+      case 5 /* primary_trace_clock */:
+        field.get(&primary_trace_clock_);
+        break;
+      case 6 /* snapshot_interval_ms */:
+        field.get(&snapshot_interval_ms_);
+        break;
+      case 7 /* prefer_suspend_clock_for_snapshot */:
+        field.get(&prefer_suspend_clock_for_snapshot_);
+        break;
+      case 8 /* disable_chunk_usage_histograms */:
+        field.get(&disable_chunk_usage_histograms_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_BuiltinDataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_BuiltinDataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_BuiltinDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: disable_clock_snapshotting
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, disable_clock_snapshotting_, msg);
+  }
+
+  // Field 2: disable_trace_config
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, disable_trace_config_, msg);
+  }
+
+  // Field 3: disable_system_info
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, disable_system_info_, msg);
+  }
+
+  // Field 4: disable_service_events
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, disable_service_events_, msg);
+  }
+
+  // Field 5: primary_trace_clock
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, primary_trace_clock_, msg);
+  }
+
+  // Field 6: snapshot_interval_ms
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, snapshot_interval_ms_, msg);
+  }
+
+  // Field 7: prefer_suspend_clock_for_snapshot
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, prefer_suspend_clock_for_snapshot_, msg);
+  }
+
+  // Field 8: disable_chunk_usage_histograms
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, disable_chunk_usage_histograms_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_DataSource::TraceConfig_DataSource() = default;
+TraceConfig_DataSource::~TraceConfig_DataSource() = default;
+TraceConfig_DataSource::TraceConfig_DataSource(const TraceConfig_DataSource&) = default;
+TraceConfig_DataSource& TraceConfig_DataSource::operator=(const TraceConfig_DataSource&) = default;
+TraceConfig_DataSource::TraceConfig_DataSource(TraceConfig_DataSource&&) noexcept = default;
+TraceConfig_DataSource& TraceConfig_DataSource::operator=(TraceConfig_DataSource&&) = default;
+
+bool TraceConfig_DataSource::operator==(const TraceConfig_DataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_filter_, other.producer_name_filter_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_regex_filter_, other.producer_name_regex_filter_);
+}
+
+bool TraceConfig_DataSource::ParseFromArray(const void* raw, size_t size) {
+  producer_name_filter_.clear();
+  producer_name_regex_filter_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* config */:
+        (*config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* producer_name_filter */:
+        producer_name_filter_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_filter_.back());
+        break;
+      case 3 /* producer_name_regex_filter */:
+        producer_name_regex_filter_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_regex_filter_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_DataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_DataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_DataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: config
+  if (_has_field_[1]) {
+    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: producer_name_filter
+  for (auto& it : producer_name_filter_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: producer_name_regex_filter
+  for (auto& it : producer_name_regex_filter_) {
+    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TraceConfig_BufferConfig::TraceConfig_BufferConfig() = default;
+TraceConfig_BufferConfig::~TraceConfig_BufferConfig() = default;
+TraceConfig_BufferConfig::TraceConfig_BufferConfig(const TraceConfig_BufferConfig&) = default;
+TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(const TraceConfig_BufferConfig&) = default;
+TraceConfig_BufferConfig::TraceConfig_BufferConfig(TraceConfig_BufferConfig&&) noexcept = default;
+TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(TraceConfig_BufferConfig&&) = default;
+
+bool TraceConfig_BufferConfig::operator==(const TraceConfig_BufferConfig& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(size_kb_, other.size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(fill_policy_, other.fill_policy_)
+   && ::protozero::internal::gen_helpers::EqualsField(transfer_on_clone_, other.transfer_on_clone_)
+   && ::protozero::internal::gen_helpers::EqualsField(clear_before_clone_, other.clear_before_clone_);
+}
+
+bool TraceConfig_BufferConfig::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* size_kb */:
+        field.get(&size_kb_);
+        break;
+      case 4 /* fill_policy */:
+        field.get(&fill_policy_);
+        break;
+      case 5 /* transfer_on_clone */:
+        field.get(&transfer_on_clone_);
+        break;
+      case 6 /* clear_before_clone */:
+        field.get(&clear_before_clone_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TraceConfig_BufferConfig::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TraceConfig_BufferConfig::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TraceConfig_BufferConfig::Serialize(::protozero::Message* msg) const {
+  // Field 1: size_kb
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, size_kb_, msg);
+  }
+
+  // Field 4: fill_policy
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, fill_policy_, msg);
+  }
+
+  // Field 5: transfer_on_clone
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, transfer_on_clone_, msg);
+  }
+
+  // Field 6: clear_before_clone
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, clear_before_clone_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/ftrace_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/perf_events.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_game_intervention_list.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_log.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_system_property.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/camera_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/frame_timeline_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/gpu_mem_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/initial_display_state.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/network_trace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/packages_list.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/shell_transition.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/surfaceflinger_common.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/surfaceflinger_layers.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/android/surfaceflinger_transactions.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_log.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/deobfuscation.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/heap_graph.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_common.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_packet.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/smaps.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_active_processes.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/range_of_interest.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/screenshot.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/interned_data/interned_data.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_active_processes.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_active_processes.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeActiveProcesses::ChromeActiveProcesses() = default;
+ChromeActiveProcesses::~ChromeActiveProcesses() = default;
+ChromeActiveProcesses::ChromeActiveProcesses(const ChromeActiveProcesses&) = default;
+ChromeActiveProcesses& ChromeActiveProcesses::operator=(const ChromeActiveProcesses&) = default;
+ChromeActiveProcesses::ChromeActiveProcesses(ChromeActiveProcesses&&) noexcept = default;
+ChromeActiveProcesses& ChromeActiveProcesses::operator=(ChromeActiveProcesses&&) = default;
+
+bool ChromeActiveProcesses::operator==(const ChromeActiveProcesses& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_);
+}
+
+bool ChromeActiveProcesses::ParseFromArray(const void* raw, size_t size) {
+  pid_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* pid */:
+        pid_.emplace_back();
+        field.get(&pid_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeActiveProcesses::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeActiveProcesses::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeActiveProcesses::Serialize(::protozero::Message* msg) const {
+  // Field 1: pid
+  for (auto& it : pid_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_application_state_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_application_state_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeApplicationStateInfo::ChromeApplicationStateInfo() = default;
+ChromeApplicationStateInfo::~ChromeApplicationStateInfo() = default;
+ChromeApplicationStateInfo::ChromeApplicationStateInfo(const ChromeApplicationStateInfo&) = default;
+ChromeApplicationStateInfo& ChromeApplicationStateInfo::operator=(const ChromeApplicationStateInfo&) = default;
+ChromeApplicationStateInfo::ChromeApplicationStateInfo(ChromeApplicationStateInfo&&) noexcept = default;
+ChromeApplicationStateInfo& ChromeApplicationStateInfo::operator=(ChromeApplicationStateInfo&&) = default;
+
+bool ChromeApplicationStateInfo::operator==(const ChromeApplicationStateInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(application_state_, other.application_state_);
+}
+
+bool ChromeApplicationStateInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* application_state */:
+        field.get(&application_state_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeApplicationStateInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeApplicationStateInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeApplicationStateInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: application_state
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, application_state_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+CompositorTimingHistory::CompositorTimingHistory() = default;
+CompositorTimingHistory::~CompositorTimingHistory() = default;
+CompositorTimingHistory::CompositorTimingHistory(const CompositorTimingHistory&) = default;
+CompositorTimingHistory& CompositorTimingHistory::operator=(const CompositorTimingHistory&) = default;
+CompositorTimingHistory::CompositorTimingHistory(CompositorTimingHistory&&) noexcept = default;
+CompositorTimingHistory& CompositorTimingHistory::operator=(CompositorTimingHistory&&) = default;
+
+bool CompositorTimingHistory::operator==(const CompositorTimingHistory& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_queue_critical_estimate_delta_us_, other.begin_main_frame_queue_critical_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_queue_not_critical_estimate_delta_us_, other.begin_main_frame_queue_not_critical_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_start_to_ready_to_commit_estimate_delta_us_, other.begin_main_frame_start_to_ready_to_commit_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(commit_to_ready_to_activate_estimate_delta_us_, other.commit_to_ready_to_activate_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(prepare_tiles_estimate_delta_us_, other.prepare_tiles_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(activate_estimate_delta_us_, other.activate_estimate_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(draw_estimate_delta_us_, other.draw_estimate_delta_us_);
+}
+
+bool CompositorTimingHistory::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* begin_main_frame_queue_critical_estimate_delta_us */:
+        field.get(&begin_main_frame_queue_critical_estimate_delta_us_);
+        break;
+      case 2 /* begin_main_frame_queue_not_critical_estimate_delta_us */:
+        field.get(&begin_main_frame_queue_not_critical_estimate_delta_us_);
+        break;
+      case 3 /* begin_main_frame_start_to_ready_to_commit_estimate_delta_us */:
+        field.get(&begin_main_frame_start_to_ready_to_commit_estimate_delta_us_);
+        break;
+      case 4 /* commit_to_ready_to_activate_estimate_delta_us */:
+        field.get(&commit_to_ready_to_activate_estimate_delta_us_);
+        break;
+      case 5 /* prepare_tiles_estimate_delta_us */:
+        field.get(&prepare_tiles_estimate_delta_us_);
+        break;
+      case 6 /* activate_estimate_delta_us */:
+        field.get(&activate_estimate_delta_us_);
+        break;
+      case 7 /* draw_estimate_delta_us */:
+        field.get(&draw_estimate_delta_us_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CompositorTimingHistory::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CompositorTimingHistory::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CompositorTimingHistory::Serialize(::protozero::Message* msg) const {
+  // Field 1: begin_main_frame_queue_critical_estimate_delta_us
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, begin_main_frame_queue_critical_estimate_delta_us_, msg);
+  }
+
+  // Field 2: begin_main_frame_queue_not_critical_estimate_delta_us
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, begin_main_frame_queue_not_critical_estimate_delta_us_, msg);
+  }
+
+  // Field 3: begin_main_frame_start_to_ready_to_commit_estimate_delta_us
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, begin_main_frame_start_to_ready_to_commit_estimate_delta_us_, msg);
+  }
+
+  // Field 4: commit_to_ready_to_activate_estimate_delta_us
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, commit_to_ready_to_activate_estimate_delta_us_, msg);
+  }
+
+  // Field 5: prepare_tiles_estimate_delta_us
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, prepare_tiles_estimate_delta_us_, msg);
+  }
+
+  // Field 6: activate_estimate_delta_us
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, activate_estimate_delta_us_, msg);
+  }
+
+  // Field 7: draw_estimate_delta_us
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, draw_estimate_delta_us_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+BeginFrameSourceState::BeginFrameSourceState() = default;
+BeginFrameSourceState::~BeginFrameSourceState() = default;
+BeginFrameSourceState::BeginFrameSourceState(const BeginFrameSourceState&) = default;
+BeginFrameSourceState& BeginFrameSourceState::operator=(const BeginFrameSourceState&) = default;
+BeginFrameSourceState::BeginFrameSourceState(BeginFrameSourceState&&) noexcept = default;
+BeginFrameSourceState& BeginFrameSourceState::operator=(BeginFrameSourceState&&) = default;
+
+bool BeginFrameSourceState::operator==(const BeginFrameSourceState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_id_, other.source_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(paused_, other.paused_)
+   && ::protozero::internal::gen_helpers::EqualsField(num_observers_, other.num_observers_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_begin_frame_args_, other.last_begin_frame_args_);
+}
+
+bool BeginFrameSourceState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* source_id */:
+        field.get(&source_id_);
+        break;
+      case 2 /* paused */:
+        field.get(&paused_);
+        break;
+      case 3 /* num_observers */:
+        field.get(&num_observers_);
+        break;
+      case 4 /* last_begin_frame_args */:
+        (*last_begin_frame_args_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string BeginFrameSourceState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginFrameSourceState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginFrameSourceState::Serialize(::protozero::Message* msg) const {
+  // Field 1: source_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, source_id_, msg);
+  }
+
+  // Field 2: paused
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, paused_, msg);
+  }
+
+  // Field 3: num_observers
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, num_observers_, msg);
+  }
+
+  // Field 4: last_begin_frame_args
+  if (_has_field_[4]) {
+    (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+BeginFrameArgs::BeginFrameArgs() = default;
+BeginFrameArgs::~BeginFrameArgs() = default;
+BeginFrameArgs::BeginFrameArgs(const BeginFrameArgs&) = default;
+BeginFrameArgs& BeginFrameArgs::operator=(const BeginFrameArgs&) = default;
+BeginFrameArgs::BeginFrameArgs(BeginFrameArgs&&) noexcept = default;
+BeginFrameArgs& BeginFrameArgs::operator=(BeginFrameArgs&&) = default;
+
+bool BeginFrameArgs::operator==(const BeginFrameArgs& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_id_, other.source_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(sequence_number_, other.sequence_number_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_time_us_, other.frame_time_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(deadline_us_, other.deadline_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(interval_delta_us_, other.interval_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(on_critical_path_, other.on_critical_path_)
+   && ::protozero::internal::gen_helpers::EqualsField(animate_only_, other.animate_only_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_location_iid_, other.source_location_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_location_, other.source_location_)
+   && ::protozero::internal::gen_helpers::EqualsField(frames_throttled_since_last_, other.frames_throttled_since_last_);
+}
+
+bool BeginFrameArgs::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* type */:
+        field.get(&type_);
+        break;
+      case 2 /* source_id */:
+        field.get(&source_id_);
+        break;
+      case 3 /* sequence_number */:
+        field.get(&sequence_number_);
+        break;
+      case 4 /* frame_time_us */:
+        field.get(&frame_time_us_);
+        break;
+      case 5 /* deadline_us */:
+        field.get(&deadline_us_);
+        break;
+      case 6 /* interval_delta_us */:
+        field.get(&interval_delta_us_);
+        break;
+      case 7 /* on_critical_path */:
+        field.get(&on_critical_path_);
+        break;
+      case 8 /* animate_only */:
+        field.get(&animate_only_);
+        break;
+      case 9 /* source_location_iid */:
+        field.get(&source_location_iid_);
+        break;
+      case 10 /* source_location */:
+        (*source_location_).ParseFromArray(field.data(), field.size());
+        break;
+      case 12 /* frames_throttled_since_last */:
+        field.get(&frames_throttled_since_last_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string BeginFrameArgs::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginFrameArgs::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginFrameArgs::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, type_, msg);
+  }
+
+  // Field 2: source_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, source_id_, msg);
+  }
+
+  // Field 3: sequence_number
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, sequence_number_, msg);
+  }
+
+  // Field 4: frame_time_us
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, frame_time_us_, msg);
+  }
+
+  // Field 5: deadline_us
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, deadline_us_, msg);
+  }
+
+  // Field 6: interval_delta_us
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, interval_delta_us_, msg);
+  }
+
+  // Field 7: on_critical_path
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, on_critical_path_, msg);
+  }
+
+  // Field 8: animate_only
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, animate_only_, msg);
+  }
+
+  // Field 9: source_location_iid
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, source_location_iid_, msg);
+  }
+
+  // Field 10: source_location
+  if (_has_field_[10]) {
+    (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(10));
+  }
+
+  // Field 12: frames_throttled_since_last
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(12, frames_throttled_since_last_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+BeginFrameObserverState::BeginFrameObserverState() = default;
+BeginFrameObserverState::~BeginFrameObserverState() = default;
+BeginFrameObserverState::BeginFrameObserverState(const BeginFrameObserverState&) = default;
+BeginFrameObserverState& BeginFrameObserverState::operator=(const BeginFrameObserverState&) = default;
+BeginFrameObserverState::BeginFrameObserverState(BeginFrameObserverState&&) noexcept = default;
+BeginFrameObserverState& BeginFrameObserverState::operator=(BeginFrameObserverState&&) = default;
+
+bool BeginFrameObserverState::operator==(const BeginFrameObserverState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(dropped_begin_frame_args_, other.dropped_begin_frame_args_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_begin_frame_args_, other.last_begin_frame_args_);
+}
+
+bool BeginFrameObserverState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* dropped_begin_frame_args */:
+        field.get(&dropped_begin_frame_args_);
+        break;
+      case 2 /* last_begin_frame_args */:
+        (*last_begin_frame_args_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string BeginFrameObserverState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginFrameObserverState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginFrameObserverState::Serialize(::protozero::Message* msg) const {
+  // Field 1: dropped_begin_frame_args
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, dropped_begin_frame_args_, msg);
+  }
+
+  // Field 2: last_begin_frame_args
+  if (_has_field_[2]) {
+    (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+BeginImplFrameArgs::BeginImplFrameArgs() = default;
+BeginImplFrameArgs::~BeginImplFrameArgs() = default;
+BeginImplFrameArgs::BeginImplFrameArgs(const BeginImplFrameArgs&) = default;
+BeginImplFrameArgs& BeginImplFrameArgs::operator=(const BeginImplFrameArgs&) = default;
+BeginImplFrameArgs::BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept = default;
+BeginImplFrameArgs& BeginImplFrameArgs::operator=(BeginImplFrameArgs&&) = default;
+
+bool BeginImplFrameArgs::operator==(const BeginImplFrameArgs& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(updated_at_us_, other.updated_at_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(finished_at_us_, other.finished_at_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_)
+   && ::protozero::internal::gen_helpers::EqualsField(current_args_, other.current_args_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_args_, other.last_args_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamps_in_us_, other.timestamps_in_us_);
+}
+
+bool BeginImplFrameArgs::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* updated_at_us */:
+        field.get(&updated_at_us_);
+        break;
+      case 2 /* finished_at_us */:
+        field.get(&finished_at_us_);
+        break;
+      case 3 /* state */:
+        field.get(&state_);
+        break;
+      case 4 /* current_args */:
+        (*current_args_).ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* last_args */:
+        (*last_args_).ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* timestamps_in_us */:
+        (*timestamps_in_us_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string BeginImplFrameArgs::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginImplFrameArgs::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginImplFrameArgs::Serialize(::protozero::Message* msg) const {
+  // Field 1: updated_at_us
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, updated_at_us_, msg);
+  }
+
+  // Field 2: finished_at_us
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, finished_at_us_, msg);
+  }
+
+  // Field 3: state
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, state_, msg);
+  }
+
+  // Field 4: current_args
+  if (_has_field_[4]) {
+    (*current_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: last_args
+  if (_has_field_[5]) {
+    (*last_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 6: timestamps_in_us
+  if (_has_field_[6]) {
+    (*timestamps_in_us_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs() = default;
+BeginImplFrameArgs_TimestampsInUs::~BeginImplFrameArgs_TimestampsInUs() = default;
+BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&) = default;
+BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(const BeginImplFrameArgs_TimestampsInUs&) = default;
+BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept = default;
+BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(BeginImplFrameArgs_TimestampsInUs&&) = default;
+
+bool BeginImplFrameArgs_TimestampsInUs::operator==(const BeginImplFrameArgs_TimestampsInUs& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(interval_delta_, other.interval_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(now_to_deadline_delta_, other.now_to_deadline_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_time_to_now_delta_, other.frame_time_to_now_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_time_to_deadline_delta_, other.frame_time_to_deadline_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(now_, other.now_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_time_, other.frame_time_)
+   && ::protozero::internal::gen_helpers::EqualsField(deadline_, other.deadline_);
+}
+
+bool BeginImplFrameArgs_TimestampsInUs::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* interval_delta */:
+        field.get(&interval_delta_);
+        break;
+      case 2 /* now_to_deadline_delta */:
+        field.get(&now_to_deadline_delta_);
+        break;
+      case 3 /* frame_time_to_now_delta */:
+        field.get(&frame_time_to_now_delta_);
+        break;
+      case 4 /* frame_time_to_deadline_delta */:
+        field.get(&frame_time_to_deadline_delta_);
+        break;
+      case 5 /* now */:
+        field.get(&now_);
+        break;
+      case 6 /* frame_time */:
+        field.get(&frame_time_);
+        break;
+      case 7 /* deadline */:
+        field.get(&deadline_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string BeginImplFrameArgs_TimestampsInUs::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> BeginImplFrameArgs_TimestampsInUs::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void BeginImplFrameArgs_TimestampsInUs::Serialize(::protozero::Message* msg) const {
+  // Field 1: interval_delta
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, interval_delta_, msg);
+  }
+
+  // Field 2: now_to_deadline_delta
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, now_to_deadline_delta_, msg);
+  }
+
+  // Field 3: frame_time_to_now_delta
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, frame_time_to_now_delta_, msg);
+  }
+
+  // Field 4: frame_time_to_deadline_delta
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, frame_time_to_deadline_delta_, msg);
+  }
+
+  // Field 5: now
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, now_, msg);
+  }
+
+  // Field 6: frame_time
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, frame_time_, msg);
+  }
+
+  // Field 7: deadline
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, deadline_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeCompositorStateMachine::ChromeCompositorStateMachine() = default;
+ChromeCompositorStateMachine::~ChromeCompositorStateMachine() = default;
+ChromeCompositorStateMachine::ChromeCompositorStateMachine(const ChromeCompositorStateMachine&) = default;
+ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(const ChromeCompositorStateMachine&) = default;
+ChromeCompositorStateMachine::ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept = default;
+ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(ChromeCompositorStateMachine&&) = default;
+
+bool ChromeCompositorStateMachine::operator==(const ChromeCompositorStateMachine& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(major_state_, other.major_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(minor_state_, other.minor_state_);
+}
+
+bool ChromeCompositorStateMachine::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* major_state */:
+        (*major_state_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* minor_state */:
+        (*minor_state_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeCompositorStateMachine::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorStateMachine::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeCompositorStateMachine::Serialize(::protozero::Message* msg) const {
+  // Field 1: major_state
+  if (_has_field_[1]) {
+    (*major_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: minor_state
+  if (_has_field_[2]) {
+    (*minor_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState() = default;
+ChromeCompositorStateMachine_MinorState::~ChromeCompositorStateMachine_MinorState() = default;
+ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&) = default;
+ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(const ChromeCompositorStateMachine_MinorState&) = default;
+ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept = default;
+ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(ChromeCompositorStateMachine_MinorState&&) = default;
+
+bool ChromeCompositorStateMachine_MinorState::operator==(const ChromeCompositorStateMachine_MinorState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(commit_count_, other.commit_count_)
+   && ::protozero::internal::gen_helpers::EqualsField(current_frame_number_, other.current_frame_number_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_frame_number_submit_performed_, other.last_frame_number_submit_performed_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_frame_number_draw_performed_, other.last_frame_number_draw_performed_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_frame_number_begin_main_frame_sent_, other.last_frame_number_begin_main_frame_sent_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_draw_, other.did_draw_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_send_begin_main_frame_for_current_frame_, other.did_send_begin_main_frame_for_current_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_notify_begin_main_frame_not_expected_until_, other.did_notify_begin_main_frame_not_expected_until_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_notify_begin_main_frame_not_expected_soon_, other.did_notify_begin_main_frame_not_expected_soon_)
+   && ::protozero::internal::gen_helpers::EqualsField(wants_begin_main_frame_not_expected_, other.wants_begin_main_frame_not_expected_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_commit_during_frame_, other.did_commit_during_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_invalidate_layer_tree_frame_sink_, other.did_invalidate_layer_tree_frame_sink_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_perform_impl_side_invalidaion_, other.did_perform_impl_side_invalidaion_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_prepare_tiles_, other.did_prepare_tiles_)
+   && ::protozero::internal::gen_helpers::EqualsField(consecutive_checkerboard_animations_, other.consecutive_checkerboard_animations_)
+   && ::protozero::internal::gen_helpers::EqualsField(pending_submit_frames_, other.pending_submit_frames_)
+   && ::protozero::internal::gen_helpers::EqualsField(submit_frames_with_current_layer_tree_frame_sink_, other.submit_frames_with_current_layer_tree_frame_sink_)
+   && ::protozero::internal::gen_helpers::EqualsField(needs_redraw_, other.needs_redraw_)
+   && ::protozero::internal::gen_helpers::EqualsField(needs_prepare_tiles_, other.needs_prepare_tiles_)
+   && ::protozero::internal::gen_helpers::EqualsField(needs_begin_main_frame_, other.needs_begin_main_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(needs_one_begin_impl_frame_, other.needs_one_begin_impl_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(visible_, other.visible_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_frame_source_paused_, other.begin_frame_source_paused_)
+   && ::protozero::internal::gen_helpers::EqualsField(can_draw_, other.can_draw_)
+   && ::protozero::internal::gen_helpers::EqualsField(resourceless_draw_, other.resourceless_draw_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_pending_tree_, other.has_pending_tree_)
+   && ::protozero::internal::gen_helpers::EqualsField(pending_tree_is_ready_for_activation_, other.pending_tree_is_ready_for_activation_)
+   && ::protozero::internal::gen_helpers::EqualsField(active_tree_needs_first_draw_, other.active_tree_needs_first_draw_)
+   && ::protozero::internal::gen_helpers::EqualsField(active_tree_is_ready_to_draw_, other.active_tree_is_ready_to_draw_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_create_and_initialize_first_layer_tree_frame_sink_, other.did_create_and_initialize_first_layer_tree_frame_sink_)
+   && ::protozero::internal::gen_helpers::EqualsField(tree_priority_, other.tree_priority_)
+   && ::protozero::internal::gen_helpers::EqualsField(scroll_handler_state_, other.scroll_handler_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(critical_begin_main_frame_to_activate_is_fast_, other.critical_begin_main_frame_to_activate_is_fast_)
+   && ::protozero::internal::gen_helpers::EqualsField(main_thread_missed_last_deadline_, other.main_thread_missed_last_deadline_)
+   && ::protozero::internal::gen_helpers::EqualsField(video_needs_begin_frames_, other.video_needs_begin_frames_)
+   && ::protozero::internal::gen_helpers::EqualsField(defer_begin_main_frame_, other.defer_begin_main_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_commit_had_no_updates_, other.last_commit_had_no_updates_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_draw_in_last_frame_, other.did_draw_in_last_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(did_submit_in_last_frame_, other.did_submit_in_last_frame_)
+   && ::protozero::internal::gen_helpers::EqualsField(needs_impl_side_invalidation_, other.needs_impl_side_invalidation_)
+   && ::protozero::internal::gen_helpers::EqualsField(current_pending_tree_is_impl_side_, other.current_pending_tree_is_impl_side_)
+   && ::protozero::internal::gen_helpers::EqualsField(previous_pending_tree_was_impl_side_, other.previous_pending_tree_was_impl_side_)
+   && ::protozero::internal::gen_helpers::EqualsField(processing_animation_worklets_for_active_tree_, other.processing_animation_worklets_for_active_tree_)
+   && ::protozero::internal::gen_helpers::EqualsField(processing_animation_worklets_for_pending_tree_, other.processing_animation_worklets_for_pending_tree_)
+   && ::protozero::internal::gen_helpers::EqualsField(processing_paint_worklets_for_pending_tree_, other.processing_paint_worklets_for_pending_tree_);
+}
+
+bool ChromeCompositorStateMachine_MinorState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* commit_count */:
+        field.get(&commit_count_);
+        break;
+      case 2 /* current_frame_number */:
+        field.get(&current_frame_number_);
+        break;
+      case 3 /* last_frame_number_submit_performed */:
+        field.get(&last_frame_number_submit_performed_);
+        break;
+      case 4 /* last_frame_number_draw_performed */:
+        field.get(&last_frame_number_draw_performed_);
+        break;
+      case 5 /* last_frame_number_begin_main_frame_sent */:
+        field.get(&last_frame_number_begin_main_frame_sent_);
+        break;
+      case 6 /* did_draw */:
+        field.get(&did_draw_);
+        break;
+      case 7 /* did_send_begin_main_frame_for_current_frame */:
+        field.get(&did_send_begin_main_frame_for_current_frame_);
+        break;
+      case 8 /* did_notify_begin_main_frame_not_expected_until */:
+        field.get(&did_notify_begin_main_frame_not_expected_until_);
+        break;
+      case 9 /* did_notify_begin_main_frame_not_expected_soon */:
+        field.get(&did_notify_begin_main_frame_not_expected_soon_);
+        break;
+      case 10 /* wants_begin_main_frame_not_expected */:
+        field.get(&wants_begin_main_frame_not_expected_);
+        break;
+      case 11 /* did_commit_during_frame */:
+        field.get(&did_commit_during_frame_);
+        break;
+      case 12 /* did_invalidate_layer_tree_frame_sink */:
+        field.get(&did_invalidate_layer_tree_frame_sink_);
+        break;
+      case 13 /* did_perform_impl_side_invalidaion */:
+        field.get(&did_perform_impl_side_invalidaion_);
+        break;
+      case 14 /* did_prepare_tiles */:
+        field.get(&did_prepare_tiles_);
+        break;
+      case 15 /* consecutive_checkerboard_animations */:
+        field.get(&consecutive_checkerboard_animations_);
+        break;
+      case 16 /* pending_submit_frames */:
+        field.get(&pending_submit_frames_);
+        break;
+      case 17 /* submit_frames_with_current_layer_tree_frame_sink */:
+        field.get(&submit_frames_with_current_layer_tree_frame_sink_);
+        break;
+      case 18 /* needs_redraw */:
+        field.get(&needs_redraw_);
+        break;
+      case 19 /* needs_prepare_tiles */:
+        field.get(&needs_prepare_tiles_);
+        break;
+      case 20 /* needs_begin_main_frame */:
+        field.get(&needs_begin_main_frame_);
+        break;
+      case 21 /* needs_one_begin_impl_frame */:
+        field.get(&needs_one_begin_impl_frame_);
+        break;
+      case 22 /* visible */:
+        field.get(&visible_);
+        break;
+      case 23 /* begin_frame_source_paused */:
+        field.get(&begin_frame_source_paused_);
+        break;
+      case 24 /* can_draw */:
+        field.get(&can_draw_);
+        break;
+      case 25 /* resourceless_draw */:
+        field.get(&resourceless_draw_);
+        break;
+      case 26 /* has_pending_tree */:
+        field.get(&has_pending_tree_);
+        break;
+      case 27 /* pending_tree_is_ready_for_activation */:
+        field.get(&pending_tree_is_ready_for_activation_);
+        break;
+      case 28 /* active_tree_needs_first_draw */:
+        field.get(&active_tree_needs_first_draw_);
+        break;
+      case 29 /* active_tree_is_ready_to_draw */:
+        field.get(&active_tree_is_ready_to_draw_);
+        break;
+      case 30 /* did_create_and_initialize_first_layer_tree_frame_sink */:
+        field.get(&did_create_and_initialize_first_layer_tree_frame_sink_);
+        break;
+      case 31 /* tree_priority */:
+        field.get(&tree_priority_);
+        break;
+      case 32 /* scroll_handler_state */:
+        field.get(&scroll_handler_state_);
+        break;
+      case 33 /* critical_begin_main_frame_to_activate_is_fast */:
+        field.get(&critical_begin_main_frame_to_activate_is_fast_);
+        break;
+      case 34 /* main_thread_missed_last_deadline */:
+        field.get(&main_thread_missed_last_deadline_);
+        break;
+      case 36 /* video_needs_begin_frames */:
+        field.get(&video_needs_begin_frames_);
+        break;
+      case 37 /* defer_begin_main_frame */:
+        field.get(&defer_begin_main_frame_);
+        break;
+      case 38 /* last_commit_had_no_updates */:
+        field.get(&last_commit_had_no_updates_);
+        break;
+      case 39 /* did_draw_in_last_frame */:
+        field.get(&did_draw_in_last_frame_);
+        break;
+      case 40 /* did_submit_in_last_frame */:
+        field.get(&did_submit_in_last_frame_);
+        break;
+      case 41 /* needs_impl_side_invalidation */:
+        field.get(&needs_impl_side_invalidation_);
+        break;
+      case 42 /* current_pending_tree_is_impl_side */:
+        field.get(&current_pending_tree_is_impl_side_);
+        break;
+      case 43 /* previous_pending_tree_was_impl_side */:
+        field.get(&previous_pending_tree_was_impl_side_);
+        break;
+      case 44 /* processing_animation_worklets_for_active_tree */:
+        field.get(&processing_animation_worklets_for_active_tree_);
+        break;
+      case 45 /* processing_animation_worklets_for_pending_tree */:
+        field.get(&processing_animation_worklets_for_pending_tree_);
+        break;
+      case 46 /* processing_paint_worklets_for_pending_tree */:
+        field.get(&processing_paint_worklets_for_pending_tree_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeCompositorStateMachine_MinorState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorStateMachine_MinorState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeCompositorStateMachine_MinorState::Serialize(::protozero::Message* msg) const {
+  // Field 1: commit_count
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, commit_count_, msg);
+  }
+
+  // Field 2: current_frame_number
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, current_frame_number_, msg);
+  }
+
+  // Field 3: last_frame_number_submit_performed
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, last_frame_number_submit_performed_, msg);
+  }
+
+  // Field 4: last_frame_number_draw_performed
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, last_frame_number_draw_performed_, msg);
+  }
+
+  // Field 5: last_frame_number_begin_main_frame_sent
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, last_frame_number_begin_main_frame_sent_, msg);
+  }
+
+  // Field 6: did_draw
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, did_draw_, msg);
+  }
+
+  // Field 7: did_send_begin_main_frame_for_current_frame
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, did_send_begin_main_frame_for_current_frame_, msg);
+  }
+
+  // Field 8: did_notify_begin_main_frame_not_expected_until
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, did_notify_begin_main_frame_not_expected_until_, msg);
+  }
+
+  // Field 9: did_notify_begin_main_frame_not_expected_soon
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, did_notify_begin_main_frame_not_expected_soon_, msg);
+  }
+
+  // Field 10: wants_begin_main_frame_not_expected
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, wants_begin_main_frame_not_expected_, msg);
+  }
+
+  // Field 11: did_commit_during_frame
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(11, did_commit_during_frame_, msg);
+  }
+
+  // Field 12: did_invalidate_layer_tree_frame_sink
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, did_invalidate_layer_tree_frame_sink_, msg);
+  }
+
+  // Field 13: did_perform_impl_side_invalidaion
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(13, did_perform_impl_side_invalidaion_, msg);
+  }
+
+  // Field 14: did_prepare_tiles
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(14, did_prepare_tiles_, msg);
+  }
+
+  // Field 15: consecutive_checkerboard_animations
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(15, consecutive_checkerboard_animations_, msg);
+  }
+
+  // Field 16: pending_submit_frames
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(16, pending_submit_frames_, msg);
+  }
+
+  // Field 17: submit_frames_with_current_layer_tree_frame_sink
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, submit_frames_with_current_layer_tree_frame_sink_, msg);
+  }
+
+  // Field 18: needs_redraw
+  if (_has_field_[18]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(18, needs_redraw_, msg);
+  }
+
+  // Field 19: needs_prepare_tiles
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, needs_prepare_tiles_, msg);
+  }
+
+  // Field 20: needs_begin_main_frame
+  if (_has_field_[20]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(20, needs_begin_main_frame_, msg);
+  }
+
+  // Field 21: needs_one_begin_impl_frame
+  if (_has_field_[21]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(21, needs_one_begin_impl_frame_, msg);
+  }
+
+  // Field 22: visible
+  if (_has_field_[22]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(22, visible_, msg);
+  }
+
+  // Field 23: begin_frame_source_paused
+  if (_has_field_[23]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(23, begin_frame_source_paused_, msg);
+  }
+
+  // Field 24: can_draw
+  if (_has_field_[24]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(24, can_draw_, msg);
+  }
+
+  // Field 25: resourceless_draw
+  if (_has_field_[25]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(25, resourceless_draw_, msg);
+  }
+
+  // Field 26: has_pending_tree
+  if (_has_field_[26]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(26, has_pending_tree_, msg);
+  }
+
+  // Field 27: pending_tree_is_ready_for_activation
+  if (_has_field_[27]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(27, pending_tree_is_ready_for_activation_, msg);
+  }
+
+  // Field 28: active_tree_needs_first_draw
+  if (_has_field_[28]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(28, active_tree_needs_first_draw_, msg);
+  }
+
+  // Field 29: active_tree_is_ready_to_draw
+  if (_has_field_[29]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(29, active_tree_is_ready_to_draw_, msg);
+  }
+
+  // Field 30: did_create_and_initialize_first_layer_tree_frame_sink
+  if (_has_field_[30]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(30, did_create_and_initialize_first_layer_tree_frame_sink_, msg);
+  }
+
+  // Field 31: tree_priority
+  if (_has_field_[31]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(31, tree_priority_, msg);
+  }
+
+  // Field 32: scroll_handler_state
+  if (_has_field_[32]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(32, scroll_handler_state_, msg);
+  }
+
+  // Field 33: critical_begin_main_frame_to_activate_is_fast
+  if (_has_field_[33]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(33, critical_begin_main_frame_to_activate_is_fast_, msg);
+  }
+
+  // Field 34: main_thread_missed_last_deadline
+  if (_has_field_[34]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(34, main_thread_missed_last_deadline_, msg);
+  }
+
+  // Field 36: video_needs_begin_frames
+  if (_has_field_[36]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(36, video_needs_begin_frames_, msg);
+  }
+
+  // Field 37: defer_begin_main_frame
+  if (_has_field_[37]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(37, defer_begin_main_frame_, msg);
+  }
+
+  // Field 38: last_commit_had_no_updates
+  if (_has_field_[38]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(38, last_commit_had_no_updates_, msg);
+  }
+
+  // Field 39: did_draw_in_last_frame
+  if (_has_field_[39]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(39, did_draw_in_last_frame_, msg);
+  }
+
+  // Field 40: did_submit_in_last_frame
+  if (_has_field_[40]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(40, did_submit_in_last_frame_, msg);
+  }
+
+  // Field 41: needs_impl_side_invalidation
+  if (_has_field_[41]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(41, needs_impl_side_invalidation_, msg);
+  }
+
+  // Field 42: current_pending_tree_is_impl_side
+  if (_has_field_[42]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(42, current_pending_tree_is_impl_side_, msg);
+  }
+
+  // Field 43: previous_pending_tree_was_impl_side
+  if (_has_field_[43]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(43, previous_pending_tree_was_impl_side_, msg);
+  }
+
+  // Field 44: processing_animation_worklets_for_active_tree
+  if (_has_field_[44]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(44, processing_animation_worklets_for_active_tree_, msg);
+  }
+
+  // Field 45: processing_animation_worklets_for_pending_tree
+  if (_has_field_[45]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(45, processing_animation_worklets_for_pending_tree_, msg);
+  }
+
+  // Field 46: processing_paint_worklets_for_pending_tree
+  if (_has_field_[46]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(46, processing_paint_worklets_for_pending_tree_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState() = default;
+ChromeCompositorStateMachine_MajorState::~ChromeCompositorStateMachine_MajorState() = default;
+ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&) = default;
+ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(const ChromeCompositorStateMachine_MajorState&) = default;
+ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept = default;
+ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(ChromeCompositorStateMachine_MajorState&&) = default;
+
+bool ChromeCompositorStateMachine_MajorState::operator==(const ChromeCompositorStateMachine_MajorState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(next_action_, other.next_action_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_impl_frame_state_, other.begin_impl_frame_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_state_, other.begin_main_frame_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(layer_tree_frame_sink_state_, other.layer_tree_frame_sink_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(forced_redraw_state_, other.forced_redraw_state_);
+}
+
+bool ChromeCompositorStateMachine_MajorState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* next_action */:
+        field.get(&next_action_);
+        break;
+      case 2 /* begin_impl_frame_state */:
+        field.get(&begin_impl_frame_state_);
+        break;
+      case 3 /* begin_main_frame_state */:
+        field.get(&begin_main_frame_state_);
+        break;
+      case 4 /* layer_tree_frame_sink_state */:
+        field.get(&layer_tree_frame_sink_state_);
+        break;
+      case 5 /* forced_redraw_state */:
+        field.get(&forced_redraw_state_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeCompositorStateMachine_MajorState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorStateMachine_MajorState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeCompositorStateMachine_MajorState::Serialize(::protozero::Message* msg) const {
+  // Field 1: next_action
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, next_action_, msg);
+  }
+
+  // Field 2: begin_impl_frame_state
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, begin_impl_frame_state_, msg);
+  }
+
+  // Field 3: begin_main_frame_state
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, begin_main_frame_state_, msg);
+  }
+
+  // Field 4: layer_tree_frame_sink_state
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, layer_tree_frame_sink_state_, msg);
+  }
+
+  // Field 5: forced_redraw_state
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, forced_redraw_state_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeCompositorSchedulerState::ChromeCompositorSchedulerState() = default;
+ChromeCompositorSchedulerState::~ChromeCompositorSchedulerState() = default;
+ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&) = default;
+ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(const ChromeCompositorSchedulerState&) = default;
+ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept = default;
+ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(ChromeCompositorSchedulerState&&) = default;
+
+bool ChromeCompositorSchedulerState::operator==(const ChromeCompositorSchedulerState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(state_machine_, other.state_machine_)
+   && ::protozero::internal::gen_helpers::EqualsField(observing_begin_frame_source_, other.observing_begin_frame_source_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_impl_frame_deadline_task_, other.begin_impl_frame_deadline_task_)
+   && ::protozero::internal::gen_helpers::EqualsField(pending_begin_frame_task_, other.pending_begin_frame_task_)
+   && ::protozero::internal::gen_helpers::EqualsField(skipped_last_frame_missed_exceeded_deadline_, other.skipped_last_frame_missed_exceeded_deadline_)
+   && ::protozero::internal::gen_helpers::EqualsField(inside_action_, other.inside_action_)
+   && ::protozero::internal::gen_helpers::EqualsField(deadline_mode_, other.deadline_mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(deadline_us_, other.deadline_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(deadline_scheduled_at_us_, other.deadline_scheduled_at_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(now_us_, other.now_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(now_to_deadline_delta_us_, other.now_to_deadline_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(now_to_deadline_scheduled_at_delta_us_, other.now_to_deadline_scheduled_at_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_impl_frame_args_, other.begin_impl_frame_args_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_frame_observer_state_, other.begin_frame_observer_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(begin_frame_source_state_, other.begin_frame_source_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(compositor_timing_history_, other.compositor_timing_history_);
+}
+
+bool ChromeCompositorSchedulerState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* state_machine */:
+        (*state_machine_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* observing_begin_frame_source */:
+        field.get(&observing_begin_frame_source_);
+        break;
+      case 3 /* begin_impl_frame_deadline_task */:
+        field.get(&begin_impl_frame_deadline_task_);
+        break;
+      case 4 /* pending_begin_frame_task */:
+        field.get(&pending_begin_frame_task_);
+        break;
+      case 5 /* skipped_last_frame_missed_exceeded_deadline */:
+        field.get(&skipped_last_frame_missed_exceeded_deadline_);
+        break;
+      case 7 /* inside_action */:
+        field.get(&inside_action_);
+        break;
+      case 8 /* deadline_mode */:
+        field.get(&deadline_mode_);
+        break;
+      case 9 /* deadline_us */:
+        field.get(&deadline_us_);
+        break;
+      case 10 /* deadline_scheduled_at_us */:
+        field.get(&deadline_scheduled_at_us_);
+        break;
+      case 11 /* now_us */:
+        field.get(&now_us_);
+        break;
+      case 12 /* now_to_deadline_delta_us */:
+        field.get(&now_to_deadline_delta_us_);
+        break;
+      case 13 /* now_to_deadline_scheduled_at_delta_us */:
+        field.get(&now_to_deadline_scheduled_at_delta_us_);
+        break;
+      case 14 /* begin_impl_frame_args */:
+        (*begin_impl_frame_args_).ParseFromArray(field.data(), field.size());
+        break;
+      case 15 /* begin_frame_observer_state */:
+        (*begin_frame_observer_state_).ParseFromArray(field.data(), field.size());
+        break;
+      case 16 /* begin_frame_source_state */:
+        (*begin_frame_source_state_).ParseFromArray(field.data(), field.size());
+        break;
+      case 17 /* compositor_timing_history */:
+        (*compositor_timing_history_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeCompositorSchedulerState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeCompositorSchedulerState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeCompositorSchedulerState::Serialize(::protozero::Message* msg) const {
+  // Field 1: state_machine
+  if (_has_field_[1]) {
+    (*state_machine_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: observing_begin_frame_source
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, observing_begin_frame_source_, msg);
+  }
+
+  // Field 3: begin_impl_frame_deadline_task
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, begin_impl_frame_deadline_task_, msg);
+  }
+
+  // Field 4: pending_begin_frame_task
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, pending_begin_frame_task_, msg);
+  }
+
+  // Field 5: skipped_last_frame_missed_exceeded_deadline
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, skipped_last_frame_missed_exceeded_deadline_, msg);
+  }
+
+  // Field 7: inside_action
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, inside_action_, msg);
+  }
+
+  // Field 8: deadline_mode
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, deadline_mode_, msg);
+  }
+
+  // Field 9: deadline_us
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, deadline_us_, msg);
+  }
+
+  // Field 10: deadline_scheduled_at_us
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, deadline_scheduled_at_us_, msg);
+  }
+
+  // Field 11: now_us
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, now_us_, msg);
+  }
+
+  // Field 12: now_to_deadline_delta_us
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(12, now_to_deadline_delta_us_, msg);
+  }
+
+  // Field 13: now_to_deadline_scheduled_at_delta_us
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, now_to_deadline_scheduled_at_delta_us_, msg);
+  }
+
+  // Field 14: begin_impl_frame_args
+  if (_has_field_[14]) {
+    (*begin_impl_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(14));
+  }
+
+  // Field 15: begin_frame_observer_state
+  if (_has_field_[15]) {
+    (*begin_frame_observer_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
+  }
+
+  // Field 16: begin_frame_source_state
+  if (_has_field_[16]) {
+    (*begin_frame_source_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
+  }
+
+  // Field 17: compositor_timing_history
+  if (_has_field_[17]) {
+    (*compositor_timing_history_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo() = default;
+ChromeContentSettingsEventInfo::~ChromeContentSettingsEventInfo() = default;
+ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo(const ChromeContentSettingsEventInfo&) = default;
+ChromeContentSettingsEventInfo& ChromeContentSettingsEventInfo::operator=(const ChromeContentSettingsEventInfo&) = default;
+ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo(ChromeContentSettingsEventInfo&&) noexcept = default;
+ChromeContentSettingsEventInfo& ChromeContentSettingsEventInfo::operator=(ChromeContentSettingsEventInfo&&) = default;
+
+bool ChromeContentSettingsEventInfo::operator==(const ChromeContentSettingsEventInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(number_of_exceptions_, other.number_of_exceptions_);
+}
+
+bool ChromeContentSettingsEventInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* number_of_exceptions */:
+        field.get(&number_of_exceptions_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeContentSettingsEventInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeContentSettingsEventInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeContentSettingsEventInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: number_of_exceptions
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, number_of_exceptions_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeFrameReporter::ChromeFrameReporter() = default;
+ChromeFrameReporter::~ChromeFrameReporter() = default;
+ChromeFrameReporter::ChromeFrameReporter(const ChromeFrameReporter&) = default;
+ChromeFrameReporter& ChromeFrameReporter::operator=(const ChromeFrameReporter&) = default;
+ChromeFrameReporter::ChromeFrameReporter(ChromeFrameReporter&&) noexcept = default;
+ChromeFrameReporter& ChromeFrameReporter::operator=(ChromeFrameReporter&&) = default;
+
+bool ChromeFrameReporter::operator==(const ChromeFrameReporter& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_)
+   && ::protozero::internal::gen_helpers::EqualsField(reason_, other.reason_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_source_, other.frame_source_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_sequence_, other.frame_sequence_)
+   && ::protozero::internal::gen_helpers::EqualsField(affects_smoothness_, other.affects_smoothness_)
+   && ::protozero::internal::gen_helpers::EqualsField(scroll_state_, other.scroll_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_main_animation_, other.has_main_animation_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_compositor_animation_, other.has_compositor_animation_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_smooth_input_main_, other.has_smooth_input_main_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_missing_content_, other.has_missing_content_)
+   && ::protozero::internal::gen_helpers::EqualsField(layer_tree_host_id_, other.layer_tree_host_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_high_latency_, other.has_high_latency_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_type_, other.frame_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(high_latency_contribution_stage_, other.high_latency_contribution_stage_);
+}
+
+bool ChromeFrameReporter::ParseFromArray(const void* raw, size_t size) {
+  high_latency_contribution_stage_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* state */:
+        field.get(&state_);
+        break;
+      case 2 /* reason */:
+        field.get(&reason_);
+        break;
+      case 3 /* frame_source */:
+        field.get(&frame_source_);
+        break;
+      case 4 /* frame_sequence */:
+        field.get(&frame_sequence_);
+        break;
+      case 5 /* affects_smoothness */:
+        field.get(&affects_smoothness_);
+        break;
+      case 6 /* scroll_state */:
+        field.get(&scroll_state_);
+        break;
+      case 7 /* has_main_animation */:
+        field.get(&has_main_animation_);
+        break;
+      case 8 /* has_compositor_animation */:
+        field.get(&has_compositor_animation_);
+        break;
+      case 9 /* has_smooth_input_main */:
+        field.get(&has_smooth_input_main_);
+        break;
+      case 10 /* has_missing_content */:
+        field.get(&has_missing_content_);
+        break;
+      case 11 /* layer_tree_host_id */:
+        field.get(&layer_tree_host_id_);
+        break;
+      case 12 /* has_high_latency */:
+        field.get(&has_high_latency_);
+        break;
+      case 13 /* frame_type */:
+        field.get(&frame_type_);
+        break;
+      case 14 /* high_latency_contribution_stage */:
+        high_latency_contribution_stage_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &high_latency_contribution_stage_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeFrameReporter::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeFrameReporter::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeFrameReporter::Serialize(::protozero::Message* msg) const {
+  // Field 1: state
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, state_, msg);
+  }
+
+  // Field 2: reason
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, reason_, msg);
+  }
+
+  // Field 3: frame_source
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, frame_source_, msg);
+  }
+
+  // Field 4: frame_sequence
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, frame_sequence_, msg);
+  }
+
+  // Field 5: affects_smoothness
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, affects_smoothness_, msg);
+  }
+
+  // Field 6: scroll_state
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, scroll_state_, msg);
+  }
+
+  // Field 7: has_main_animation
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, has_main_animation_, msg);
+  }
+
+  // Field 8: has_compositor_animation
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, has_compositor_animation_, msg);
+  }
+
+  // Field 9: has_smooth_input_main
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, has_smooth_input_main_, msg);
+  }
+
+  // Field 10: has_missing_content
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, has_missing_content_, msg);
+  }
+
+  // Field 11: layer_tree_host_id
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, layer_tree_host_id_, msg);
+  }
+
+  // Field 12: has_high_latency
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, has_high_latency_, msg);
+  }
+
+  // Field 13: frame_type
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, frame_type_, msg);
+  }
+
+  // Field 14: high_latency_contribution_stage
+  for (auto& it : high_latency_contribution_stage_) {
+    ::protozero::internal::gen_helpers::SerializeString(14, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeHistogramSample::ChromeHistogramSample() = default;
+ChromeHistogramSample::~ChromeHistogramSample() = default;
+ChromeHistogramSample::ChromeHistogramSample(const ChromeHistogramSample&) = default;
+ChromeHistogramSample& ChromeHistogramSample::operator=(const ChromeHistogramSample&) = default;
+ChromeHistogramSample::ChromeHistogramSample(ChromeHistogramSample&&) noexcept = default;
+ChromeHistogramSample& ChromeHistogramSample::operator=(ChromeHistogramSample&&) = default;
+
+bool ChromeHistogramSample::operator==(const ChromeHistogramSample& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_hash_, other.name_hash_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(sample_, other.sample_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_);
+}
+
+bool ChromeHistogramSample::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name_hash */:
+        field.get(&name_hash_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 3 /* sample */:
+        field.get(&sample_);
+        break;
+      case 4 /* name_iid */:
+        field.get(&name_iid_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeHistogramSample::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeHistogramSample::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeHistogramSample::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_hash
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, name_hash_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  // Field 3: sample
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, sample_, msg);
+  }
+
+  // Field 4: name_iid
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, name_iid_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+HistogramName::HistogramName() = default;
+HistogramName::~HistogramName() = default;
+HistogramName::HistogramName(const HistogramName&) = default;
+HistogramName& HistogramName::operator=(const HistogramName&) = default;
+HistogramName::HistogramName(HistogramName&&) noexcept = default;
+HistogramName& HistogramName::operator=(HistogramName&&) = default;
+
+bool HistogramName::operator==(const HistogramName& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool HistogramName::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string HistogramName::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> HistogramName::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void HistogramName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeKeyedService::ChromeKeyedService() = default;
+ChromeKeyedService::~ChromeKeyedService() = default;
+ChromeKeyedService::ChromeKeyedService(const ChromeKeyedService&) = default;
+ChromeKeyedService& ChromeKeyedService::operator=(const ChromeKeyedService&) = default;
+ChromeKeyedService::ChromeKeyedService(ChromeKeyedService&&) noexcept = default;
+ChromeKeyedService& ChromeKeyedService::operator=(ChromeKeyedService&&) = default;
+
+bool ChromeKeyedService::operator==(const ChromeKeyedService& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool ChromeKeyedService::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeKeyedService::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeKeyedService::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeKeyedService::Serialize(::protozero::Message* msg) const {
+  // Field 1: name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeLatencyInfo::ChromeLatencyInfo() = default;
+ChromeLatencyInfo::~ChromeLatencyInfo() = default;
+ChromeLatencyInfo::ChromeLatencyInfo(const ChromeLatencyInfo&) = default;
+ChromeLatencyInfo& ChromeLatencyInfo::operator=(const ChromeLatencyInfo&) = default;
+ChromeLatencyInfo::ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept = default;
+ChromeLatencyInfo& ChromeLatencyInfo::operator=(ChromeLatencyInfo&&) = default;
+
+bool ChromeLatencyInfo::operator==(const ChromeLatencyInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_id_, other.trace_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(step_, other.step_)
+   && ::protozero::internal::gen_helpers::EqualsField(frame_tree_node_id_, other.frame_tree_node_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(component_info_, other.component_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_coalesced_, other.is_coalesced_)
+   && ::protozero::internal::gen_helpers::EqualsField(gesture_scroll_id_, other.gesture_scroll_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(touch_id_, other.touch_id_);
+}
+
+int ChromeLatencyInfo::component_info_size() const { return static_cast<int>(component_info_.size()); }
+void ChromeLatencyInfo::clear_component_info() { component_info_.clear(); }
+ChromeLatencyInfo_ComponentInfo* ChromeLatencyInfo::add_component_info() { component_info_.emplace_back(); return &component_info_.back(); }
+bool ChromeLatencyInfo::ParseFromArray(const void* raw, size_t size) {
+  component_info_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_id */:
+        field.get(&trace_id_);
+        break;
+      case 2 /* step */:
+        field.get(&step_);
+        break;
+      case 3 /* frame_tree_node_id */:
+        field.get(&frame_tree_node_id_);
+        break;
+      case 4 /* component_info */:
+        component_info_.emplace_back();
+        component_info_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* is_coalesced */:
+        field.get(&is_coalesced_);
+        break;
+      case 6 /* gesture_scroll_id */:
+        field.get(&gesture_scroll_id_);
+        break;
+      case 7 /* touch_id */:
+        field.get(&touch_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeLatencyInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeLatencyInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeLatencyInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_id_, msg);
+  }
+
+  // Field 2: step
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, step_, msg);
+  }
+
+  // Field 3: frame_tree_node_id
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, frame_tree_node_id_, msg);
+  }
+
+  // Field 4: component_info
+  for (auto& it : component_info_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: is_coalesced
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, is_coalesced_, msg);
+  }
+
+  // Field 6: gesture_scroll_id
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, gesture_scroll_id_, msg);
+  }
+
+  // Field 7: touch_id
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, touch_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo() = default;
+ChromeLatencyInfo_ComponentInfo::~ChromeLatencyInfo_ComponentInfo() = default;
+ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&) = default;
+ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(const ChromeLatencyInfo_ComponentInfo&) = default;
+ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept = default;
+ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(ChromeLatencyInfo_ComponentInfo&&) = default;
+
+bool ChromeLatencyInfo_ComponentInfo::operator==(const ChromeLatencyInfo_ComponentInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(component_type_, other.component_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(time_us_, other.time_us_);
+}
+
+bool ChromeLatencyInfo_ComponentInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* component_type */:
+        field.get(&component_type_);
+        break;
+      case 2 /* time_us */:
+        field.get(&time_us_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeLatencyInfo_ComponentInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeLatencyInfo_ComponentInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeLatencyInfo_ComponentInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: component_type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, component_type_, msg);
+  }
+
+  // Field 2: time_us
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, time_us_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeLegacyIpc::ChromeLegacyIpc() = default;
+ChromeLegacyIpc::~ChromeLegacyIpc() = default;
+ChromeLegacyIpc::ChromeLegacyIpc(const ChromeLegacyIpc&) = default;
+ChromeLegacyIpc& ChromeLegacyIpc::operator=(const ChromeLegacyIpc&) = default;
+ChromeLegacyIpc::ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept = default;
+ChromeLegacyIpc& ChromeLegacyIpc::operator=(ChromeLegacyIpc&&) = default;
+
+bool ChromeLegacyIpc::operator==(const ChromeLegacyIpc& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_class_, other.message_class_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_line_, other.message_line_);
+}
+
+bool ChromeLegacyIpc::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* message_class */:
+        field.get(&message_class_);
+        break;
+      case 2 /* message_line */:
+        field.get(&message_line_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeLegacyIpc::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeLegacyIpc::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeLegacyIpc::Serialize(::protozero::Message* msg) const {
+  // Field 1: message_class
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, message_class_, msg);
+  }
+
+  // Field 2: message_line
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, message_line_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_message_pump.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_message_pump.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeMessagePump::ChromeMessagePump() = default;
+ChromeMessagePump::~ChromeMessagePump() = default;
+ChromeMessagePump::ChromeMessagePump(const ChromeMessagePump&) = default;
+ChromeMessagePump& ChromeMessagePump::operator=(const ChromeMessagePump&) = default;
+ChromeMessagePump::ChromeMessagePump(ChromeMessagePump&&) noexcept = default;
+ChromeMessagePump& ChromeMessagePump::operator=(ChromeMessagePump&&) = default;
+
+bool ChromeMessagePump::operator==(const ChromeMessagePump& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(sent_messages_in_queue_, other.sent_messages_in_queue_)
+   && ::protozero::internal::gen_helpers::EqualsField(io_handler_location_iid_, other.io_handler_location_iid_);
+}
+
+bool ChromeMessagePump::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* sent_messages_in_queue */:
+        field.get(&sent_messages_in_queue_);
+        break;
+      case 2 /* io_handler_location_iid */:
+        field.get(&io_handler_location_iid_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeMessagePump::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeMessagePump::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeMessagePump::Serialize(::protozero::Message* msg) const {
+  // Field 1: sent_messages_in_queue
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, sent_messages_in_queue_, msg);
+  }
+
+  // Field 2: io_handler_location_iid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, io_handler_location_iid_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeMojoEventInfo::ChromeMojoEventInfo() = default;
+ChromeMojoEventInfo::~ChromeMojoEventInfo() = default;
+ChromeMojoEventInfo::ChromeMojoEventInfo(const ChromeMojoEventInfo&) = default;
+ChromeMojoEventInfo& ChromeMojoEventInfo::operator=(const ChromeMojoEventInfo&) = default;
+ChromeMojoEventInfo::ChromeMojoEventInfo(ChromeMojoEventInfo&&) noexcept = default;
+ChromeMojoEventInfo& ChromeMojoEventInfo::operator=(ChromeMojoEventInfo&&) = default;
+
+bool ChromeMojoEventInfo::operator==(const ChromeMojoEventInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(watcher_notify_interface_tag_, other.watcher_notify_interface_tag_)
+   && ::protozero::internal::gen_helpers::EqualsField(ipc_hash_, other.ipc_hash_)
+   && ::protozero::internal::gen_helpers::EqualsField(mojo_interface_tag_, other.mojo_interface_tag_)
+   && ::protozero::internal::gen_helpers::EqualsField(mojo_interface_method_iid_, other.mojo_interface_method_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_reply_, other.is_reply_)
+   && ::protozero::internal::gen_helpers::EqualsField(payload_size_, other.payload_size_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_num_bytes_, other.data_num_bytes_);
+}
+
+bool ChromeMojoEventInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* watcher_notify_interface_tag */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &watcher_notify_interface_tag_);
+        break;
+      case 2 /* ipc_hash */:
+        field.get(&ipc_hash_);
+        break;
+      case 3 /* mojo_interface_tag */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &mojo_interface_tag_);
+        break;
+      case 4 /* mojo_interface_method_iid */:
+        field.get(&mojo_interface_method_iid_);
+        break;
+      case 5 /* is_reply */:
+        field.get(&is_reply_);
+        break;
+      case 6 /* payload_size */:
+        field.get(&payload_size_);
+        break;
+      case 7 /* data_num_bytes */:
+        field.get(&data_num_bytes_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeMojoEventInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeMojoEventInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeMojoEventInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: watcher_notify_interface_tag
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, watcher_notify_interface_tag_, msg);
+  }
+
+  // Field 2: ipc_hash
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, ipc_hash_, msg);
+  }
+
+  // Field 3: mojo_interface_tag
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, mojo_interface_tag_, msg);
+  }
+
+  // Field 4: mojo_interface_method_iid
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, mojo_interface_method_iid_, msg);
+  }
+
+  // Field 5: is_reply
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, is_reply_, msg);
+  }
+
+  // Field 6: payload_size
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, payload_size_, msg);
+  }
+
+  // Field 7: data_num_bytes
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, data_num_bytes_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeProcessDescriptor::ChromeProcessDescriptor() = default;
+ChromeProcessDescriptor::~ChromeProcessDescriptor() = default;
+ChromeProcessDescriptor::ChromeProcessDescriptor(const ChromeProcessDescriptor&) = default;
+ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(const ChromeProcessDescriptor&) = default;
+ChromeProcessDescriptor::ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept = default;
+ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(ChromeProcessDescriptor&&) = default;
+
+bool ChromeProcessDescriptor::operator==(const ChromeProcessDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_type_, other.process_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_priority_, other.process_priority_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_)
+   && ::protozero::internal::gen_helpers::EqualsField(host_app_package_name_, other.host_app_package_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(crash_trace_id_, other.crash_trace_id_);
+}
+
+bool ChromeProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* process_type */:
+        field.get(&process_type_);
+        break;
+      case 2 /* process_priority */:
+        field.get(&process_priority_);
+        break;
+      case 3 /* legacy_sort_index */:
+        field.get(&legacy_sort_index_);
+        break;
+      case 4 /* host_app_package_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &host_app_package_name_);
+        break;
+      case 5 /* crash_trace_id */:
+        field.get(&crash_trace_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeProcessDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeProcessDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeProcessDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: process_type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, process_type_, msg);
+  }
+
+  // Field 2: process_priority
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, process_priority_, msg);
+  }
+
+  // Field 3: legacy_sort_index
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, legacy_sort_index_, msg);
+  }
+
+  // Field 4: host_app_package_name
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeString(4, host_app_package_name_, msg);
+  }
+
+  // Field 5: crash_trace_id
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, crash_trace_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeRendererSchedulerState::ChromeRendererSchedulerState() = default;
+ChromeRendererSchedulerState::~ChromeRendererSchedulerState() = default;
+ChromeRendererSchedulerState::ChromeRendererSchedulerState(const ChromeRendererSchedulerState&) = default;
+ChromeRendererSchedulerState& ChromeRendererSchedulerState::operator=(const ChromeRendererSchedulerState&) = default;
+ChromeRendererSchedulerState::ChromeRendererSchedulerState(ChromeRendererSchedulerState&&) noexcept = default;
+ChromeRendererSchedulerState& ChromeRendererSchedulerState::operator=(ChromeRendererSchedulerState&&) = default;
+
+bool ChromeRendererSchedulerState::operator==(const ChromeRendererSchedulerState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(rail_mode_, other.rail_mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_backgrounded_, other.is_backgrounded_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_hidden_, other.is_hidden_);
+}
+
+bool ChromeRendererSchedulerState::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* rail_mode */:
+        field.get(&rail_mode_);
+        break;
+      case 2 /* is_backgrounded */:
+        field.get(&is_backgrounded_);
+        break;
+      case 3 /* is_hidden */:
+        field.get(&is_hidden_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeRendererSchedulerState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeRendererSchedulerState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeRendererSchedulerState::Serialize(::protozero::Message* msg) const {
+  // Field 1: rail_mode
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, rail_mode_, msg);
+  }
+
+  // Field 2: is_backgrounded
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, is_backgrounded_, msg);
+  }
+
+  // Field 3: is_hidden
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, is_hidden_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeThreadDescriptor::ChromeThreadDescriptor() = default;
+ChromeThreadDescriptor::~ChromeThreadDescriptor() = default;
+ChromeThreadDescriptor::ChromeThreadDescriptor(const ChromeThreadDescriptor&) = default;
+ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(const ChromeThreadDescriptor&) = default;
+ChromeThreadDescriptor::ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept = default;
+ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(ChromeThreadDescriptor&&) = default;
+
+bool ChromeThreadDescriptor::operator==(const ChromeThreadDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_type_, other.thread_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_);
+}
+
+bool ChromeThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* thread_type */:
+        field.get(&thread_type_);
+        break;
+      case 2 /* legacy_sort_index */:
+        field.get(&legacy_sort_index_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeThreadDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeThreadDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeThreadDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: thread_type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, thread_type_, msg);
+  }
+
+  // Field 2: legacy_sort_index
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, legacy_sort_index_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeUserEvent::ChromeUserEvent() = default;
+ChromeUserEvent::~ChromeUserEvent() = default;
+ChromeUserEvent::ChromeUserEvent(const ChromeUserEvent&) = default;
+ChromeUserEvent& ChromeUserEvent::operator=(const ChromeUserEvent&) = default;
+ChromeUserEvent::ChromeUserEvent(ChromeUserEvent&&) noexcept = default;
+ChromeUserEvent& ChromeUserEvent::operator=(ChromeUserEvent&&) = default;
+
+bool ChromeUserEvent::operator==(const ChromeUserEvent& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(action_, other.action_)
+   && ::protozero::internal::gen_helpers::EqualsField(action_hash_, other.action_hash_);
+}
+
+bool ChromeUserEvent::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* action */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &action_);
+        break;
+      case 2 /* action_hash */:
+        field.get(&action_hash_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeUserEvent::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeUserEvent::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeUserEvent::Serialize(::protozero::Message* msg) const {
+  // Field 1: action
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, action_, msg);
+  }
+
+  // Field 2: action_hash
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, action_hash_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo() = default;
+ChromeWindowHandleEventInfo::~ChromeWindowHandleEventInfo() = default;
+ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo(const ChromeWindowHandleEventInfo&) = default;
+ChromeWindowHandleEventInfo& ChromeWindowHandleEventInfo::operator=(const ChromeWindowHandleEventInfo&) = default;
+ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo(ChromeWindowHandleEventInfo&&) noexcept = default;
+ChromeWindowHandleEventInfo& ChromeWindowHandleEventInfo::operator=(ChromeWindowHandleEventInfo&&) = default;
+
+bool ChromeWindowHandleEventInfo::operator==(const ChromeWindowHandleEventInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(dpi_, other.dpi_)
+   && ::protozero::internal::gen_helpers::EqualsField(message_id_, other.message_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(hwnd_ptr_, other.hwnd_ptr_);
+}
+
+bool ChromeWindowHandleEventInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* dpi */:
+        field.get(&dpi_);
+        break;
+      case 2 /* message_id */:
+        field.get(&message_id_);
+        break;
+      case 3 /* hwnd_ptr */:
+        field.get(&hwnd_ptr_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChromeWindowHandleEventInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChromeWindowHandleEventInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChromeWindowHandleEventInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: dpi
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, dpi_, msg);
+  }
+
+  // Field 2: message_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, message_id_, msg);
+  }
+
+  // Field 3: hwnd_ptr
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(3, hwnd_ptr_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+CounterDescriptor::CounterDescriptor() = default;
+CounterDescriptor::~CounterDescriptor() = default;
+CounterDescriptor::CounterDescriptor(const CounterDescriptor&) = default;
+CounterDescriptor& CounterDescriptor::operator=(const CounterDescriptor&) = default;
+CounterDescriptor::CounterDescriptor(CounterDescriptor&&) noexcept = default;
+CounterDescriptor& CounterDescriptor::operator=(CounterDescriptor&&) = default;
+
+bool CounterDescriptor::operator==(const CounterDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(categories_, other.categories_)
+   && ::protozero::internal::gen_helpers::EqualsField(unit_, other.unit_)
+   && ::protozero::internal::gen_helpers::EqualsField(unit_name_, other.unit_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(unit_multiplier_, other.unit_multiplier_)
+   && ::protozero::internal::gen_helpers::EqualsField(is_incremental_, other.is_incremental_);
+}
+
+bool CounterDescriptor::ParseFromArray(const void* raw, size_t size) {
+  categories_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* type */:
+        field.get(&type_);
+        break;
+      case 2 /* categories */:
+        categories_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &categories_.back());
+        break;
+      case 3 /* unit */:
+        field.get(&unit_);
+        break;
+      case 6 /* unit_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &unit_name_);
+        break;
+      case 4 /* unit_multiplier */:
+        field.get(&unit_multiplier_);
+        break;
+      case 5 /* is_incremental */:
+        field.get(&is_incremental_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CounterDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CounterDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CounterDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, type_, msg);
+  }
+
+  // Field 2: categories
+  for (auto& it : categories_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: unit
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, unit_, msg);
+  }
+
+  // Field 6: unit_name
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeString(6, unit_name_, msg);
+  }
+
+  // Field 4: unit_multiplier
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, unit_multiplier_, msg);
+  }
+
+  // Field 5: is_incremental
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, is_incremental_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+DebugAnnotationValueTypeName::DebugAnnotationValueTypeName() = default;
+DebugAnnotationValueTypeName::~DebugAnnotationValueTypeName() = default;
+DebugAnnotationValueTypeName::DebugAnnotationValueTypeName(const DebugAnnotationValueTypeName&) = default;
+DebugAnnotationValueTypeName& DebugAnnotationValueTypeName::operator=(const DebugAnnotationValueTypeName&) = default;
+DebugAnnotationValueTypeName::DebugAnnotationValueTypeName(DebugAnnotationValueTypeName&&) noexcept = default;
+DebugAnnotationValueTypeName& DebugAnnotationValueTypeName::operator=(DebugAnnotationValueTypeName&&) = default;
+
+bool DebugAnnotationValueTypeName::operator==(const DebugAnnotationValueTypeName& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool DebugAnnotationValueTypeName::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DebugAnnotationValueTypeName::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotationValueTypeName::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotationValueTypeName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DebugAnnotationName::DebugAnnotationName() = default;
+DebugAnnotationName::~DebugAnnotationName() = default;
+DebugAnnotationName::DebugAnnotationName(const DebugAnnotationName&) = default;
+DebugAnnotationName& DebugAnnotationName::operator=(const DebugAnnotationName&) = default;
+DebugAnnotationName::DebugAnnotationName(DebugAnnotationName&&) noexcept = default;
+DebugAnnotationName& DebugAnnotationName::operator=(DebugAnnotationName&&) = default;
+
+bool DebugAnnotationName::operator==(const DebugAnnotationName& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool DebugAnnotationName::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DebugAnnotationName::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotationName::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotationName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DebugAnnotation::DebugAnnotation() = default;
+DebugAnnotation::~DebugAnnotation() = default;
+DebugAnnotation::DebugAnnotation(const DebugAnnotation&) = default;
+DebugAnnotation& DebugAnnotation::operator=(const DebugAnnotation&) = default;
+DebugAnnotation::DebugAnnotation(DebugAnnotation&&) noexcept = default;
+DebugAnnotation& DebugAnnotation::operator=(DebugAnnotation&&) = default;
+
+bool DebugAnnotation::operator==(const DebugAnnotation& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(bool_value_, other.bool_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(uint_value_, other.uint_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(int_value_, other.int_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(double_value_, other.double_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(pointer_value_, other.pointer_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(nested_value_, other.nested_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_json_value_, other.legacy_json_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(string_value_, other.string_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(string_value_iid_, other.string_value_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(proto_type_name_, other.proto_type_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(proto_type_name_iid_, other.proto_type_name_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(proto_value_, other.proto_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(dict_entries_, other.dict_entries_)
+   && ::protozero::internal::gen_helpers::EqualsField(array_values_, other.array_values_);
+}
+
+int DebugAnnotation::dict_entries_size() const { return static_cast<int>(dict_entries_.size()); }
+void DebugAnnotation::clear_dict_entries() { dict_entries_.clear(); }
+DebugAnnotation* DebugAnnotation::add_dict_entries() { dict_entries_.emplace_back(); return &dict_entries_.back(); }
+int DebugAnnotation::array_values_size() const { return static_cast<int>(array_values_.size()); }
+void DebugAnnotation::clear_array_values() { array_values_.clear(); }
+DebugAnnotation* DebugAnnotation::add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
+bool DebugAnnotation::ParseFromArray(const void* raw, size_t size) {
+  dict_entries_.clear();
+  array_values_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name_iid */:
+        field.get(&name_iid_);
+        break;
+      case 10 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 2 /* bool_value */:
+        field.get(&bool_value_);
+        break;
+      case 3 /* uint_value */:
+        field.get(&uint_value_);
+        break;
+      case 4 /* int_value */:
+        field.get(&int_value_);
+        break;
+      case 5 /* double_value */:
+        field.get(&double_value_);
+        break;
+      case 7 /* pointer_value */:
+        field.get(&pointer_value_);
+        break;
+      case 8 /* nested_value */:
+        (*nested_value_).ParseFromArray(field.data(), field.size());
+        break;
+      case 9 /* legacy_json_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &legacy_json_value_);
+        break;
+      case 6 /* string_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &string_value_);
+        break;
+      case 17 /* string_value_iid */:
+        field.get(&string_value_iid_);
+        break;
+      case 16 /* proto_type_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &proto_type_name_);
+        break;
+      case 13 /* proto_type_name_iid */:
+        field.get(&proto_type_name_iid_);
+        break;
+      case 14 /* proto_value */:
+        field.get(&proto_value_);
+        break;
+      case 11 /* dict_entries */:
+        dict_entries_.emplace_back();
+        dict_entries_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 12 /* array_values */:
+        array_values_.emplace_back();
+        array_values_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DebugAnnotation::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotation::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotation::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, name_iid_, msg);
+  }
+
+  // Field 10: name
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeString(10, name_, msg);
+  }
+
+  // Field 2: bool_value
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, bool_value_, msg);
+  }
+
+  // Field 3: uint_value
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, uint_value_, msg);
+  }
+
+  // Field 4: int_value
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, int_value_, msg);
+  }
+
+  // Field 5: double_value
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(5, double_value_, msg);
+  }
+
+  // Field 7: pointer_value
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, pointer_value_, msg);
+  }
+
+  // Field 8: nested_value
+  if (_has_field_[8]) {
+    (*nested_value_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 9: legacy_json_value
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeString(9, legacy_json_value_, msg);
+  }
+
+  // Field 6: string_value
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeString(6, string_value_, msg);
+  }
+
+  // Field 17: string_value_iid
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, string_value_iid_, msg);
+  }
+
+  // Field 16: proto_type_name
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeString(16, proto_type_name_, msg);
+  }
+
+  // Field 13: proto_type_name_iid
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, proto_type_name_iid_, msg);
+  }
+
+  // Field 14: proto_value
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeString(14, proto_value_, msg);
+  }
+
+  // Field 11: dict_entries
+  for (auto& it : dict_entries_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
+  }
+
+  // Field 12: array_values
+  for (auto& it : array_values_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DebugAnnotation_NestedValue::DebugAnnotation_NestedValue() = default;
+DebugAnnotation_NestedValue::~DebugAnnotation_NestedValue() = default;
+DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&) = default;
+DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(const DebugAnnotation_NestedValue&) = default;
+DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept = default;
+DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(DebugAnnotation_NestedValue&&) = default;
+
+bool DebugAnnotation_NestedValue::operator==(const DebugAnnotation_NestedValue& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(nested_type_, other.nested_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(dict_keys_, other.dict_keys_)
+   && ::protozero::internal::gen_helpers::EqualsField(dict_values_, other.dict_values_)
+   && ::protozero::internal::gen_helpers::EqualsField(array_values_, other.array_values_)
+   && ::protozero::internal::gen_helpers::EqualsField(int_value_, other.int_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(double_value_, other.double_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(bool_value_, other.bool_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(string_value_, other.string_value_);
+}
+
+int DebugAnnotation_NestedValue::dict_values_size() const { return static_cast<int>(dict_values_.size()); }
+void DebugAnnotation_NestedValue::clear_dict_values() { dict_values_.clear(); }
+DebugAnnotation_NestedValue* DebugAnnotation_NestedValue::add_dict_values() { dict_values_.emplace_back(); return &dict_values_.back(); }
+int DebugAnnotation_NestedValue::array_values_size() const { return static_cast<int>(array_values_.size()); }
+void DebugAnnotation_NestedValue::clear_array_values() { array_values_.clear(); }
+DebugAnnotation_NestedValue* DebugAnnotation_NestedValue::add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
+bool DebugAnnotation_NestedValue::ParseFromArray(const void* raw, size_t size) {
+  dict_keys_.clear();
+  dict_values_.clear();
+  array_values_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* nested_type */:
+        field.get(&nested_type_);
+        break;
+      case 2 /* dict_keys */:
+        dict_keys_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &dict_keys_.back());
+        break;
+      case 3 /* dict_values */:
+        dict_values_.emplace_back();
+        dict_values_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* array_values */:
+        array_values_.emplace_back();
+        array_values_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* int_value */:
+        field.get(&int_value_);
+        break;
+      case 6 /* double_value */:
+        field.get(&double_value_);
+        break;
+      case 7 /* bool_value */:
+        field.get(&bool_value_);
+        break;
+      case 8 /* string_value */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &string_value_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DebugAnnotation_NestedValue::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DebugAnnotation_NestedValue::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DebugAnnotation_NestedValue::Serialize(::protozero::Message* msg) const {
+  // Field 1: nested_type
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, nested_type_, msg);
+  }
+
+  // Field 2: dict_keys
+  for (auto& it : dict_keys_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 3: dict_values
+  for (auto& it : dict_values_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: array_values
+  for (auto& it : array_values_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: int_value
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, int_value_, msg);
+  }
+
+  // Field 6: double_value
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(6, double_value_, msg);
+  }
+
+  // Field 7: bool_value
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, bool_value_, msg);
+  }
+
+  // Field 8: string_value
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeString(8, string_value_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+LogMessageBody::LogMessageBody() = default;
+LogMessageBody::~LogMessageBody() = default;
+LogMessageBody::LogMessageBody(const LogMessageBody&) = default;
+LogMessageBody& LogMessageBody::operator=(const LogMessageBody&) = default;
+LogMessageBody::LogMessageBody(LogMessageBody&&) noexcept = default;
+LogMessageBody& LogMessageBody::operator=(LogMessageBody&&) = default;
+
+bool LogMessageBody::operator==(const LogMessageBody& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(body_, other.body_);
+}
+
+bool LogMessageBody::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* body */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &body_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string LogMessageBody::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> LogMessageBody::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void LogMessageBody::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: body
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, body_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+LogMessage::LogMessage() = default;
+LogMessage::~LogMessage() = default;
+LogMessage::LogMessage(const LogMessage&) = default;
+LogMessage& LogMessage::operator=(const LogMessage&) = default;
+LogMessage::LogMessage(LogMessage&&) noexcept = default;
+LogMessage& LogMessage::operator=(LogMessage&&) = default;
+
+bool LogMessage::operator==(const LogMessage& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_location_iid_, other.source_location_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(body_iid_, other.body_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(prio_, other.prio_);
+}
+
+bool LogMessage::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* source_location_iid */:
+        field.get(&source_location_iid_);
+        break;
+      case 2 /* body_iid */:
+        field.get(&body_iid_);
+        break;
+      case 3 /* prio */:
+        field.get(&prio_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string LogMessage::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> LogMessage::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void LogMessage::Serialize(::protozero::Message* msg) const {
+  // Field 1: source_location_iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, source_location_iid_, msg);
+  }
+
+  // Field 2: body_iid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, body_iid_, msg);
+  }
+
+  // Field 3: prio
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, prio_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ProcessDescriptor::ProcessDescriptor() = default;
+ProcessDescriptor::~ProcessDescriptor() = default;
+ProcessDescriptor::ProcessDescriptor(const ProcessDescriptor&) = default;
+ProcessDescriptor& ProcessDescriptor::operator=(const ProcessDescriptor&) = default;
+ProcessDescriptor::ProcessDescriptor(ProcessDescriptor&&) noexcept = default;
+ProcessDescriptor& ProcessDescriptor::operator=(ProcessDescriptor&&) = default;
+
+bool ProcessDescriptor::operator==(const ProcessDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(cmdline_, other.cmdline_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_name_, other.process_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_priority_, other.process_priority_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_timestamp_ns_, other.start_timestamp_ns_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_process_type_, other.chrome_process_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_labels_, other.process_labels_);
+}
+
+bool ProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
+  cmdline_.clear();
+  process_labels_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* pid */:
+        field.get(&pid_);
+        break;
+      case 2 /* cmdline */:
+        cmdline_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &cmdline_.back());
+        break;
+      case 6 /* process_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &process_name_);
+        break;
+      case 5 /* process_priority */:
+        field.get(&process_priority_);
+        break;
+      case 7 /* start_timestamp_ns */:
+        field.get(&start_timestamp_ns_);
+        break;
+      case 4 /* chrome_process_type */:
+        field.get(&chrome_process_type_);
+        break;
+      case 3 /* legacy_sort_index */:
+        field.get(&legacy_sort_index_);
+        break;
+      case 8 /* process_labels */:
+        process_labels_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &process_labels_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ProcessDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ProcessDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ProcessDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: pid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, pid_, msg);
+  }
+
+  // Field 2: cmdline
+  for (auto& it : cmdline_) {
+    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
+  }
+
+  // Field 6: process_name
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeString(6, process_name_, msg);
+  }
+
+  // Field 5: process_priority
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, process_priority_, msg);
+  }
+
+  // Field 7: start_timestamp_ns
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, start_timestamp_ns_, msg);
+  }
+
+  // Field 4: chrome_process_type
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, chrome_process_type_, msg);
+  }
+
+  // Field 3: legacy_sort_index
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, legacy_sort_index_, msg);
+  }
+
+  // Field 8: process_labels
+  for (auto& it : process_labels_) {
+    ::protozero::internal::gen_helpers::SerializeString(8, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/range_of_interest.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/range_of_interest.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TrackEventRangeOfInterest::TrackEventRangeOfInterest() = default;
+TrackEventRangeOfInterest::~TrackEventRangeOfInterest() = default;
+TrackEventRangeOfInterest::TrackEventRangeOfInterest(const TrackEventRangeOfInterest&) = default;
+TrackEventRangeOfInterest& TrackEventRangeOfInterest::operator=(const TrackEventRangeOfInterest&) = default;
+TrackEventRangeOfInterest::TrackEventRangeOfInterest(TrackEventRangeOfInterest&&) noexcept = default;
+TrackEventRangeOfInterest& TrackEventRangeOfInterest::operator=(TrackEventRangeOfInterest&&) = default;
+
+bool TrackEventRangeOfInterest::operator==(const TrackEventRangeOfInterest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_us_, other.start_us_);
+}
+
+bool TrackEventRangeOfInterest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* start_us */:
+        field.get(&start_us_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventRangeOfInterest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventRangeOfInterest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventRangeOfInterest::Serialize(::protozero::Message* msg) const {
+  // Field 1: start_us
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, start_us_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/screenshot.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/screenshot.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+Screenshot::Screenshot() = default;
+Screenshot::~Screenshot() = default;
+Screenshot::Screenshot(const Screenshot&) = default;
+Screenshot& Screenshot::operator=(const Screenshot&) = default;
+Screenshot::Screenshot(Screenshot&&) noexcept = default;
+Screenshot& Screenshot::operator=(Screenshot&&) = default;
+
+bool Screenshot::operator==(const Screenshot& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(jpg_image_, other.jpg_image_);
+}
+
+bool Screenshot::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* jpg_image */:
+        field.get(&jpg_image_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string Screenshot::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> Screenshot::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void Screenshot::Serialize(::protozero::Message* msg) const {
+  // Field 1: jpg_image
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, jpg_image_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SourceLocation::SourceLocation() = default;
+SourceLocation::~SourceLocation() = default;
+SourceLocation::SourceLocation(const SourceLocation&) = default;
+SourceLocation& SourceLocation::operator=(const SourceLocation&) = default;
+SourceLocation::SourceLocation(SourceLocation&&) noexcept = default;
+SourceLocation& SourceLocation::operator=(SourceLocation&&) = default;
+
+bool SourceLocation::operator==(const SourceLocation& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(file_name_, other.file_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(function_name_, other.function_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(line_number_, other.line_number_);
+}
+
+bool SourceLocation::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* file_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &file_name_);
+        break;
+      case 3 /* function_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &function_name_);
+        break;
+      case 4 /* line_number */:
+        field.get(&line_number_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SourceLocation::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SourceLocation::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SourceLocation::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: file_name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, file_name_, msg);
+  }
+
+  // Field 3: function_name
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, function_name_, msg);
+  }
+
+  // Field 4: line_number
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, line_number_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UnsymbolizedSourceLocation::UnsymbolizedSourceLocation() = default;
+UnsymbolizedSourceLocation::~UnsymbolizedSourceLocation() = default;
+UnsymbolizedSourceLocation::UnsymbolizedSourceLocation(const UnsymbolizedSourceLocation&) = default;
+UnsymbolizedSourceLocation& UnsymbolizedSourceLocation::operator=(const UnsymbolizedSourceLocation&) = default;
+UnsymbolizedSourceLocation::UnsymbolizedSourceLocation(UnsymbolizedSourceLocation&&) noexcept = default;
+UnsymbolizedSourceLocation& UnsymbolizedSourceLocation::operator=(UnsymbolizedSourceLocation&&) = default;
+
+bool UnsymbolizedSourceLocation::operator==(const UnsymbolizedSourceLocation& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(mapping_id_, other.mapping_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(rel_pc_, other.rel_pc_);
+}
+
+bool UnsymbolizedSourceLocation::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* mapping_id */:
+        field.get(&mapping_id_);
+        break;
+      case 3 /* rel_pc */:
+        field.get(&rel_pc_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnsymbolizedSourceLocation::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnsymbolizedSourceLocation::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnsymbolizedSourceLocation::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: mapping_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, mapping_id_, msg);
+  }
+
+  // Field 3: rel_pc
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, rel_pc_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TaskExecution::TaskExecution() = default;
+TaskExecution::~TaskExecution() = default;
+TaskExecution::TaskExecution(const TaskExecution&) = default;
+TaskExecution& TaskExecution::operator=(const TaskExecution&) = default;
+TaskExecution::TaskExecution(TaskExecution&&) noexcept = default;
+TaskExecution& TaskExecution::operator=(TaskExecution&&) = default;
+
+bool TaskExecution::operator==(const TaskExecution& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(posted_from_iid_, other.posted_from_iid_);
+}
+
+bool TaskExecution::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* posted_from_iid */:
+        field.get(&posted_from_iid_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TaskExecution::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TaskExecution::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TaskExecution::Serialize(::protozero::Message* msg) const {
+  // Field 1: posted_from_iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, posted_from_iid_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+ThreadDescriptor::ThreadDescriptor() = default;
+ThreadDescriptor::~ThreadDescriptor() = default;
+ThreadDescriptor::ThreadDescriptor(const ThreadDescriptor&) = default;
+ThreadDescriptor& ThreadDescriptor::operator=(const ThreadDescriptor&) = default;
+ThreadDescriptor::ThreadDescriptor(ThreadDescriptor&&) noexcept = default;
+ThreadDescriptor& ThreadDescriptor::operator=(ThreadDescriptor&&) = default;
+
+bool ThreadDescriptor::operator==(const ThreadDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(tid_, other.tid_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_name_, other.thread_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_thread_type_, other.chrome_thread_type_)
+   && ::protozero::internal::gen_helpers::EqualsField(reference_timestamp_us_, other.reference_timestamp_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(reference_thread_time_us_, other.reference_thread_time_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(reference_thread_instruction_count_, other.reference_thread_instruction_count_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_);
+}
+
+bool ThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* pid */:
+        field.get(&pid_);
+        break;
+      case 2 /* tid */:
+        field.get(&tid_);
+        break;
+      case 5 /* thread_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &thread_name_);
+        break;
+      case 4 /* chrome_thread_type */:
+        field.get(&chrome_thread_type_);
+        break;
+      case 6 /* reference_timestamp_us */:
+        field.get(&reference_timestamp_us_);
+        break;
+      case 7 /* reference_thread_time_us */:
+        field.get(&reference_thread_time_us_);
+        break;
+      case 8 /* reference_thread_instruction_count */:
+        field.get(&reference_thread_instruction_count_);
+        break;
+      case 3 /* legacy_sort_index */:
+        field.get(&legacy_sort_index_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ThreadDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ThreadDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ThreadDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: pid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, pid_, msg);
+  }
+
+  // Field 2: tid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, tid_, msg);
+  }
+
+  // Field 5: thread_name
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeString(5, thread_name_, msg);
+  }
+
+  // Field 4: chrome_thread_type
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, chrome_thread_type_, msg);
+  }
+
+  // Field 6: reference_timestamp_us
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, reference_timestamp_us_, msg);
+  }
+
+  // Field 7: reference_thread_time_us
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(7, reference_thread_time_us_, msg);
+  }
+
+  // Field 8: reference_thread_instruction_count
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, reference_thread_instruction_count_, msg);
+  }
+
+  // Field 3: legacy_sort_index
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, legacy_sort_index_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+TrackDescriptor::TrackDescriptor() = default;
+TrackDescriptor::~TrackDescriptor() = default;
+TrackDescriptor::TrackDescriptor(const TrackDescriptor&) = default;
+TrackDescriptor& TrackDescriptor::operator=(const TrackDescriptor&) = default;
+TrackDescriptor::TrackDescriptor(TrackDescriptor&&) noexcept = default;
+TrackDescriptor& TrackDescriptor::operator=(TrackDescriptor&&) = default;
+
+bool TrackDescriptor::operator==(const TrackDescriptor& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(uuid_, other.uuid_)
+   && ::protozero::internal::gen_helpers::EqualsField(parent_uuid_, other.parent_uuid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(process_, other.process_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_process_, other.chrome_process_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_, other.thread_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_thread_, other.chrome_thread_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_, other.counter_)
+   && ::protozero::internal::gen_helpers::EqualsField(disallow_merging_with_system_tracks_, other.disallow_merging_with_system_tracks_);
+}
+
+bool TrackDescriptor::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* uuid */:
+        field.get(&uuid_);
+        break;
+      case 5 /* parent_uuid */:
+        field.get(&parent_uuid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 3 /* process */:
+        (*process_).ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* chrome_process */:
+        (*chrome_process_).ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* thread */:
+        (*thread_).ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* chrome_thread */:
+        (*chrome_thread_).ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* counter */:
+        (*counter_).ParseFromArray(field.data(), field.size());
+        break;
+      case 9 /* disallow_merging_with_system_tracks */:
+        field.get(&disallow_merging_with_system_tracks_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackDescriptor::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackDescriptor::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackDescriptor::Serialize(::protozero::Message* msg) const {
+  // Field 1: uuid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, uuid_, msg);
+  }
+
+  // Field 5: parent_uuid
+  if (_has_field_[5]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(5, parent_uuid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  // Field 3: process
+  if (_has_field_[3]) {
+    (*process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 6: chrome_process
+  if (_has_field_[6]) {
+    (*chrome_process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 4: thread
+  if (_has_field_[4]) {
+    (*thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 7: chrome_thread
+  if (_has_field_[7]) {
+    (*chrome_thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  // Field 8: counter
+  if (_has_field_[8]) {
+    (*counter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 9: disallow_merging_with_system_tracks
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, disallow_merging_with_system_tracks_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/screenshot.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_message_pump.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_application_state_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_active_processes.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+EventName::EventName() = default;
+EventName::~EventName() = default;
+EventName::EventName(const EventName&) = default;
+EventName& EventName::operator=(const EventName&) = default;
+EventName::EventName(EventName&&) noexcept = default;
+EventName& EventName::operator=(EventName&&) = default;
+
+bool EventName::operator==(const EventName& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool EventName::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EventName::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EventName::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EventName::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+EventCategory::EventCategory() = default;
+EventCategory::~EventCategory() = default;
+EventCategory::EventCategory(const EventCategory&) = default;
+EventCategory& EventCategory::operator=(const EventCategory&) = default;
+EventCategory::EventCategory(EventCategory&&) noexcept = default;
+EventCategory& EventCategory::operator=(EventCategory&&) = default;
+
+bool EventCategory::operator==(const EventCategory& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool EventCategory::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* iid */:
+        field.get(&iid_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EventCategory::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EventCategory::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EventCategory::Serialize(::protozero::Message* msg) const {
+  // Field 1: iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TrackEventDefaults::TrackEventDefaults() = default;
+TrackEventDefaults::~TrackEventDefaults() = default;
+TrackEventDefaults::TrackEventDefaults(const TrackEventDefaults&) = default;
+TrackEventDefaults& TrackEventDefaults::operator=(const TrackEventDefaults&) = default;
+TrackEventDefaults::TrackEventDefaults(TrackEventDefaults&&) noexcept = default;
+TrackEventDefaults& TrackEventDefaults::operator=(TrackEventDefaults&&) = default;
+
+bool TrackEventDefaults::operator==(const TrackEventDefaults& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_uuid_, other.track_uuid_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_counter_track_uuids_, other.extra_counter_track_uuids_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_double_counter_track_uuids_, other.extra_double_counter_track_uuids_);
+}
+
+bool TrackEventDefaults::ParseFromArray(const void* raw, size_t size) {
+  extra_counter_track_uuids_.clear();
+  extra_double_counter_track_uuids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 11 /* track_uuid */:
+        field.get(&track_uuid_);
+        break;
+      case 31 /* extra_counter_track_uuids */:
+        extra_counter_track_uuids_.emplace_back();
+        field.get(&extra_counter_track_uuids_.back());
+        break;
+      case 45 /* extra_double_counter_track_uuids */:
+        extra_double_counter_track_uuids_.emplace_back();
+        field.get(&extra_double_counter_track_uuids_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEventDefaults::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEventDefaults::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEventDefaults::Serialize(::protozero::Message* msg) const {
+  // Field 11: track_uuid
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, track_uuid_, msg);
+  }
+
+  // Field 31: extra_counter_track_uuids
+  for (auto& it : extra_counter_track_uuids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(31, it, msg);
+  }
+
+  // Field 45: extra_double_counter_track_uuids
+  for (auto& it : extra_double_counter_track_uuids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(45, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TrackEvent::TrackEvent() = default;
+TrackEvent::~TrackEvent() = default;
+TrackEvent::TrackEvent(const TrackEvent&) = default;
+TrackEvent& TrackEvent::operator=(const TrackEvent&) = default;
+TrackEvent::TrackEvent(TrackEvent&&) noexcept = default;
+TrackEvent& TrackEvent::operator=(TrackEvent&&) = default;
+
+bool TrackEvent::operator==(const TrackEvent& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(category_iids_, other.category_iids_)
+   && ::protozero::internal::gen_helpers::EqualsField(categories_, other.categories_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
+   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
+   && ::protozero::internal::gen_helpers::EqualsField(track_uuid_, other.track_uuid_)
+   && ::protozero::internal::gen_helpers::EqualsField(counter_value_, other.counter_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(double_counter_value_, other.double_counter_value_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_counter_track_uuids_, other.extra_counter_track_uuids_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_counter_values_, other.extra_counter_values_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_double_counter_track_uuids_, other.extra_double_counter_track_uuids_)
+   && ::protozero::internal::gen_helpers::EqualsField(extra_double_counter_values_, other.extra_double_counter_values_)
+   && ::protozero::internal::gen_helpers::EqualsField(flow_ids_old_, other.flow_ids_old_)
+   && ::protozero::internal::gen_helpers::EqualsField(flow_ids_, other.flow_ids_)
+   && ::protozero::internal::gen_helpers::EqualsField(terminating_flow_ids_old_, other.terminating_flow_ids_old_)
+   && ::protozero::internal::gen_helpers::EqualsField(terminating_flow_ids_, other.terminating_flow_ids_)
+   && ::protozero::internal::gen_helpers::EqualsField(debug_annotations_, other.debug_annotations_)
+   && ::protozero::internal::gen_helpers::EqualsField(task_execution_, other.task_execution_)
+   && ::protozero::internal::gen_helpers::EqualsField(log_message_, other.log_message_)
+   && ::protozero::internal::gen_helpers::EqualsField(cc_scheduler_state_, other.cc_scheduler_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_user_event_, other.chrome_user_event_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_keyed_service_, other.chrome_keyed_service_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_legacy_ipc_, other.chrome_legacy_ipc_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_histogram_sample_, other.chrome_histogram_sample_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_latency_info_, other.chrome_latency_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_frame_reporter_, other.chrome_frame_reporter_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_application_state_info_, other.chrome_application_state_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_renderer_scheduler_state_, other.chrome_renderer_scheduler_state_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_window_handle_event_info_, other.chrome_window_handle_event_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_content_settings_event_info_, other.chrome_content_settings_event_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_active_processes_, other.chrome_active_processes_)
+   && ::protozero::internal::gen_helpers::EqualsField(screenshot_, other.screenshot_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_location_, other.source_location_)
+   && ::protozero::internal::gen_helpers::EqualsField(source_location_iid_, other.source_location_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_message_pump_, other.chrome_message_pump_)
+   && ::protozero::internal::gen_helpers::EqualsField(chrome_mojo_event_info_, other.chrome_mojo_event_info_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamp_delta_us_, other.timestamp_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(timestamp_absolute_us_, other.timestamp_absolute_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_time_delta_us_, other.thread_time_delta_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_time_absolute_us_, other.thread_time_absolute_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_instruction_count_delta_, other.thread_instruction_count_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_instruction_count_absolute_, other.thread_instruction_count_absolute_)
+   && ::protozero::internal::gen_helpers::EqualsField(legacy_event_, other.legacy_event_);
+}
+
+int TrackEvent::debug_annotations_size() const { return static_cast<int>(debug_annotations_.size()); }
+void TrackEvent::clear_debug_annotations() { debug_annotations_.clear(); }
+DebugAnnotation* TrackEvent::add_debug_annotations() { debug_annotations_.emplace_back(); return &debug_annotations_.back(); }
+bool TrackEvent::ParseFromArray(const void* raw, size_t size) {
+  category_iids_.clear();
+  categories_.clear();
+  extra_counter_track_uuids_.clear();
+  extra_counter_values_.clear();
+  extra_double_counter_track_uuids_.clear();
+  extra_double_counter_values_.clear();
+  flow_ids_old_.clear();
+  flow_ids_.clear();
+  terminating_flow_ids_old_.clear();
+  terminating_flow_ids_.clear();
+  debug_annotations_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 3 /* category_iids */:
+        category_iids_.emplace_back();
+        field.get(&category_iids_.back());
+        break;
+      case 22 /* categories */:
+        categories_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &categories_.back());
+        break;
+      case 10 /* name_iid */:
+        field.get(&name_iid_);
+        break;
+      case 23 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      case 9 /* type */:
+        field.get(&type_);
+        break;
+      case 11 /* track_uuid */:
+        field.get(&track_uuid_);
+        break;
+      case 30 /* counter_value */:
+        field.get(&counter_value_);
+        break;
+      case 44 /* double_counter_value */:
+        field.get(&double_counter_value_);
+        break;
+      case 31 /* extra_counter_track_uuids */:
+        extra_counter_track_uuids_.emplace_back();
+        field.get(&extra_counter_track_uuids_.back());
+        break;
+      case 12 /* extra_counter_values */:
+        extra_counter_values_.emplace_back();
+        field.get(&extra_counter_values_.back());
+        break;
+      case 45 /* extra_double_counter_track_uuids */:
+        extra_double_counter_track_uuids_.emplace_back();
+        field.get(&extra_double_counter_track_uuids_.back());
+        break;
+      case 46 /* extra_double_counter_values */:
+        extra_double_counter_values_.emplace_back();
+        field.get(&extra_double_counter_values_.back());
+        break;
+      case 36 /* flow_ids_old */:
+        flow_ids_old_.emplace_back();
+        field.get(&flow_ids_old_.back());
+        break;
+      case 47 /* flow_ids */:
+        flow_ids_.emplace_back();
+        field.get(&flow_ids_.back());
+        break;
+      case 42 /* terminating_flow_ids_old */:
+        terminating_flow_ids_old_.emplace_back();
+        field.get(&terminating_flow_ids_old_.back());
+        break;
+      case 48 /* terminating_flow_ids */:
+        terminating_flow_ids_.emplace_back();
+        field.get(&terminating_flow_ids_.back());
+        break;
+      case 4 /* debug_annotations */:
+        debug_annotations_.emplace_back();
+        debug_annotations_.back().ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* task_execution */:
+        (*task_execution_).ParseFromArray(field.data(), field.size());
+        break;
+      case 21 /* log_message */:
+        (*log_message_).ParseFromArray(field.data(), field.size());
+        break;
+      case 24 /* cc_scheduler_state */:
+        (*cc_scheduler_state_).ParseFromArray(field.data(), field.size());
+        break;
+      case 25 /* chrome_user_event */:
+        (*chrome_user_event_).ParseFromArray(field.data(), field.size());
+        break;
+      case 26 /* chrome_keyed_service */:
+        (*chrome_keyed_service_).ParseFromArray(field.data(), field.size());
+        break;
+      case 27 /* chrome_legacy_ipc */:
+        (*chrome_legacy_ipc_).ParseFromArray(field.data(), field.size());
+        break;
+      case 28 /* chrome_histogram_sample */:
+        (*chrome_histogram_sample_).ParseFromArray(field.data(), field.size());
+        break;
+      case 29 /* chrome_latency_info */:
+        (*chrome_latency_info_).ParseFromArray(field.data(), field.size());
+        break;
+      case 32 /* chrome_frame_reporter */:
+        (*chrome_frame_reporter_).ParseFromArray(field.data(), field.size());
+        break;
+      case 39 /* chrome_application_state_info */:
+        (*chrome_application_state_info_).ParseFromArray(field.data(), field.size());
+        break;
+      case 40 /* chrome_renderer_scheduler_state */:
+        (*chrome_renderer_scheduler_state_).ParseFromArray(field.data(), field.size());
+        break;
+      case 41 /* chrome_window_handle_event_info */:
+        (*chrome_window_handle_event_info_).ParseFromArray(field.data(), field.size());
+        break;
+      case 43 /* chrome_content_settings_event_info */:
+        (*chrome_content_settings_event_info_).ParseFromArray(field.data(), field.size());
+        break;
+      case 49 /* chrome_active_processes */:
+        (*chrome_active_processes_).ParseFromArray(field.data(), field.size());
+        break;
+      case 50 /* screenshot */:
+        (*screenshot_).ParseFromArray(field.data(), field.size());
+        break;
+      case 33 /* source_location */:
+        (*source_location_).ParseFromArray(field.data(), field.size());
+        break;
+      case 34 /* source_location_iid */:
+        field.get(&source_location_iid_);
+        break;
+      case 35 /* chrome_message_pump */:
+        (*chrome_message_pump_).ParseFromArray(field.data(), field.size());
+        break;
+      case 38 /* chrome_mojo_event_info */:
+        (*chrome_mojo_event_info_).ParseFromArray(field.data(), field.size());
+        break;
+      case 1 /* timestamp_delta_us */:
+        field.get(&timestamp_delta_us_);
+        break;
+      case 16 /* timestamp_absolute_us */:
+        field.get(&timestamp_absolute_us_);
+        break;
+      case 2 /* thread_time_delta_us */:
+        field.get(&thread_time_delta_us_);
+        break;
+      case 17 /* thread_time_absolute_us */:
+        field.get(&thread_time_absolute_us_);
+        break;
+      case 8 /* thread_instruction_count_delta */:
+        field.get(&thread_instruction_count_delta_);
+        break;
+      case 20 /* thread_instruction_count_absolute */:
+        field.get(&thread_instruction_count_absolute_);
+        break;
+      case 6 /* legacy_event */:
+        (*legacy_event_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEvent::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEvent::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEvent::Serialize(::protozero::Message* msg) const {
+  // Field 3: category_iids
+  for (auto& it : category_iids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, it, msg);
+  }
+
+  // Field 22: categories
+  for (auto& it : categories_) {
+    ::protozero::internal::gen_helpers::SerializeString(22, it, msg);
+  }
+
+  // Field 10: name_iid
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, name_iid_, msg);
+  }
+
+  // Field 23: name
+  if (_has_field_[23]) {
+    ::protozero::internal::gen_helpers::SerializeString(23, name_, msg);
+  }
+
+  // Field 9: type
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(9, type_, msg);
+  }
+
+  // Field 11: track_uuid
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, track_uuid_, msg);
+  }
+
+  // Field 30: counter_value
+  if (_has_field_[30]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(30, counter_value_, msg);
+  }
+
+  // Field 44: double_counter_value
+  if (_has_field_[44]) {
+    ::protozero::internal::gen_helpers::SerializeFixed(44, double_counter_value_, msg);
+  }
+
+  // Field 31: extra_counter_track_uuids
+  for (auto& it : extra_counter_track_uuids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(31, it, msg);
+  }
+
+  // Field 12: extra_counter_values
+  for (auto& it : extra_counter_values_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(12, it, msg);
+  }
+
+  // Field 45: extra_double_counter_track_uuids
+  for (auto& it : extra_double_counter_track_uuids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(45, it, msg);
+  }
+
+  // Field 46: extra_double_counter_values
+  for (auto& it : extra_double_counter_values_) {
+    ::protozero::internal::gen_helpers::SerializeFixed(46, it, msg);
+  }
+
+  // Field 36: flow_ids_old
+  for (auto& it : flow_ids_old_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(36, it, msg);
+  }
+
+  // Field 47: flow_ids
+  for (auto& it : flow_ids_) {
+    ::protozero::internal::gen_helpers::SerializeFixed(47, it, msg);
+  }
+
+  // Field 42: terminating_flow_ids_old
+  for (auto& it : terminating_flow_ids_old_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(42, it, msg);
+  }
+
+  // Field 48: terminating_flow_ids
+  for (auto& it : terminating_flow_ids_) {
+    ::protozero::internal::gen_helpers::SerializeFixed(48, it, msg);
+  }
+
+  // Field 4: debug_annotations
+  for (auto& it : debug_annotations_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: task_execution
+  if (_has_field_[5]) {
+    (*task_execution_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 21: log_message
+  if (_has_field_[21]) {
+    (*log_message_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
+  }
+
+  // Field 24: cc_scheduler_state
+  if (_has_field_[24]) {
+    (*cc_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(24));
+  }
+
+  // Field 25: chrome_user_event
+  if (_has_field_[25]) {
+    (*chrome_user_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
+  }
+
+  // Field 26: chrome_keyed_service
+  if (_has_field_[26]) {
+    (*chrome_keyed_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(26));
+  }
+
+  // Field 27: chrome_legacy_ipc
+  if (_has_field_[27]) {
+    (*chrome_legacy_ipc_).Serialize(msg->BeginNestedMessage<::protozero::Message>(27));
+  }
+
+  // Field 28: chrome_histogram_sample
+  if (_has_field_[28]) {
+    (*chrome_histogram_sample_).Serialize(msg->BeginNestedMessage<::protozero::Message>(28));
+  }
+
+  // Field 29: chrome_latency_info
+  if (_has_field_[29]) {
+    (*chrome_latency_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(29));
+  }
+
+  // Field 32: chrome_frame_reporter
+  if (_has_field_[32]) {
+    (*chrome_frame_reporter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(32));
+  }
+
+  // Field 39: chrome_application_state_info
+  if (_has_field_[39]) {
+    (*chrome_application_state_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(39));
+  }
+
+  // Field 40: chrome_renderer_scheduler_state
+  if (_has_field_[40]) {
+    (*chrome_renderer_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(40));
+  }
+
+  // Field 41: chrome_window_handle_event_info
+  if (_has_field_[41]) {
+    (*chrome_window_handle_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(41));
+  }
+
+  // Field 43: chrome_content_settings_event_info
+  if (_has_field_[43]) {
+    (*chrome_content_settings_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(43));
+  }
+
+  // Field 49: chrome_active_processes
+  if (_has_field_[49]) {
+    (*chrome_active_processes_).Serialize(msg->BeginNestedMessage<::protozero::Message>(49));
+  }
+
+  // Field 50: screenshot
+  if (_has_field_[50]) {
+    (*screenshot_).Serialize(msg->BeginNestedMessage<::protozero::Message>(50));
+  }
+
+  // Field 33: source_location
+  if (_has_field_[33]) {
+    (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(33));
+  }
+
+  // Field 34: source_location_iid
+  if (_has_field_[34]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(34, source_location_iid_, msg);
+  }
+
+  // Field 35: chrome_message_pump
+  if (_has_field_[35]) {
+    (*chrome_message_pump_).Serialize(msg->BeginNestedMessage<::protozero::Message>(35));
+  }
+
+  // Field 38: chrome_mojo_event_info
+  if (_has_field_[38]) {
+    (*chrome_mojo_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(38));
+  }
+
+  // Field 1: timestamp_delta_us
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, timestamp_delta_us_, msg);
+  }
+
+  // Field 16: timestamp_absolute_us
+  if (_has_field_[16]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(16, timestamp_absolute_us_, msg);
+  }
+
+  // Field 2: thread_time_delta_us
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, thread_time_delta_us_, msg);
+  }
+
+  // Field 17: thread_time_absolute_us
+  if (_has_field_[17]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(17, thread_time_absolute_us_, msg);
+  }
+
+  // Field 8: thread_instruction_count_delta
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, thread_instruction_count_delta_, msg);
+  }
+
+  // Field 20: thread_instruction_count_absolute
+  if (_has_field_[20]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(20, thread_instruction_count_absolute_, msg);
+  }
+
+  // Field 6: legacy_event
+  if (_has_field_[6]) {
+    (*legacy_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+TrackEvent_LegacyEvent::TrackEvent_LegacyEvent() = default;
+TrackEvent_LegacyEvent::~TrackEvent_LegacyEvent() = default;
+TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&) = default;
+TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(const TrackEvent_LegacyEvent&) = default;
+TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept = default;
+TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(TrackEvent_LegacyEvent&&) = default;
+
+bool TrackEvent_LegacyEvent::operator==(const TrackEvent_LegacyEvent& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_)
+   && ::protozero::internal::gen_helpers::EqualsField(phase_, other.phase_)
+   && ::protozero::internal::gen_helpers::EqualsField(duration_us_, other.duration_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_duration_us_, other.thread_duration_us_)
+   && ::protozero::internal::gen_helpers::EqualsField(thread_instruction_delta_, other.thread_instruction_delta_)
+   && ::protozero::internal::gen_helpers::EqualsField(unscoped_id_, other.unscoped_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(local_id_, other.local_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(global_id_, other.global_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(id_scope_, other.id_scope_)
+   && ::protozero::internal::gen_helpers::EqualsField(use_async_tts_, other.use_async_tts_)
+   && ::protozero::internal::gen_helpers::EqualsField(bind_id_, other.bind_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(bind_to_enclosing_, other.bind_to_enclosing_)
+   && ::protozero::internal::gen_helpers::EqualsField(flow_direction_, other.flow_direction_)
+   && ::protozero::internal::gen_helpers::EqualsField(instant_event_scope_, other.instant_event_scope_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_override_, other.pid_override_)
+   && ::protozero::internal::gen_helpers::EqualsField(tid_override_, other.tid_override_);
+}
+
+bool TrackEvent_LegacyEvent::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* name_iid */:
+        field.get(&name_iid_);
+        break;
+      case 2 /* phase */:
+        field.get(&phase_);
+        break;
+      case 3 /* duration_us */:
+        field.get(&duration_us_);
+        break;
+      case 4 /* thread_duration_us */:
+        field.get(&thread_duration_us_);
+        break;
+      case 15 /* thread_instruction_delta */:
+        field.get(&thread_instruction_delta_);
+        break;
+      case 6 /* unscoped_id */:
+        field.get(&unscoped_id_);
+        break;
+      case 10 /* local_id */:
+        field.get(&local_id_);
+        break;
+      case 11 /* global_id */:
+        field.get(&global_id_);
+        break;
+      case 7 /* id_scope */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &id_scope_);
+        break;
+      case 9 /* use_async_tts */:
+        field.get(&use_async_tts_);
+        break;
+      case 8 /* bind_id */:
+        field.get(&bind_id_);
+        break;
+      case 12 /* bind_to_enclosing */:
+        field.get(&bind_to_enclosing_);
+        break;
+      case 13 /* flow_direction */:
+        field.get(&flow_direction_);
+        break;
+      case 14 /* instant_event_scope */:
+        field.get(&instant_event_scope_);
+        break;
+      case 18 /* pid_override */:
+        field.get(&pid_override_);
+        break;
+      case 19 /* tid_override */:
+        field.get(&tid_override_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string TrackEvent_LegacyEvent::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> TrackEvent_LegacyEvent::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void TrackEvent_LegacyEvent::Serialize(::protozero::Message* msg) const {
+  // Field 1: name_iid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, name_iid_, msg);
+  }
+
+  // Field 2: phase
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, phase_, msg);
+  }
+
+  // Field 3: duration_us
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, duration_us_, msg);
+  }
+
+  // Field 4: thread_duration_us
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, thread_duration_us_, msg);
+  }
+
+  // Field 15: thread_instruction_delta
+  if (_has_field_[15]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(15, thread_instruction_delta_, msg);
+  }
+
+  // Field 6: unscoped_id
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(6, unscoped_id_, msg);
+  }
+
+  // Field 10: local_id
+  if (_has_field_[10]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(10, local_id_, msg);
+  }
+
+  // Field 11: global_id
+  if (_has_field_[11]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(11, global_id_, msg);
+  }
+
+  // Field 7: id_scope
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeString(7, id_scope_, msg);
+  }
+
+  // Field 9: use_async_tts
+  if (_has_field_[9]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, use_async_tts_, msg);
+  }
+
+  // Field 8: bind_id
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(8, bind_id_, msg);
+  }
+
+  // Field 12: bind_to_enclosing
+  if (_has_field_[12]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, bind_to_enclosing_, msg);
+  }
+
+  // Field 13: flow_direction
+  if (_has_field_[13]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(13, flow_direction_, msg);
+  }
+
+  // Field 14: instant_event_scope
+  if (_has_field_[14]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(14, instant_event_scope_, msg);
+  }
+
+  // Field 18: pid_override
+  if (_has_field_[18]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(18, pid_override_, msg);
+  }
+
+  // Field 19: tid_override
+  if (_has_field_[19]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(19, tid_override_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_game_intervention_list_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_sdk_sysprop_guard_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_system_property_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/network_trace_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_layers_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_transactions_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/interceptors/console_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/atom_ids.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/statsd_tracing_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/system_info/system_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/scenario_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/etw/etw_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/interceptor_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/test_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/clock_snapshot.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/trace_uuid.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/trigger.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/system_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/etw/etw.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/etw/etw_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/etw/etw_event_bundle.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/filesystem/inode_file_map.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/generic.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/android_fs.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/binder.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/block.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cgroup.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/clk.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cma.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/compaction.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cpuhp.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cros_ec.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dma_fence.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dpu.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/drm.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ext4.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/f2fs.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fastrpc.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fence.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/filemap.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/g2d.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/gpu_mem.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/gpu_scheduler.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/hyp.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/i2c.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ion.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ipi.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/irq.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/kmem.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/kvm.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/lwis.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mali.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mdss.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mm_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/net.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/oom.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/panel.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/perf_trace_counters.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/power.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/printk.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/regulator.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/samsung.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sched.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/scm.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sde.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/signal.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/skb.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sock.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sync.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/synthetic.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/systrace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/task.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/tcp.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/thermal.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/trusty.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ufs.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/v4l2.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/virtio_gpu.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/virtio_video.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/vmscan.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/workqueue.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/power/android_entity_state_residency.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/power/battery_counters.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/power/power_rails.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_stats.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_tree.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/statsd/statsd_atom.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/sys_stats/sys_stats.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/system_info/cpu_info.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/translation/translation_table.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/test_event.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/test_extensions.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/trace.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/extension_descriptor.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/memory_graph.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: gen/protos/perfetto/trace/ui_state.pbzero.cc
+// Intentionally empty (crbug.com/998165)
+// gen_amalgamated begin source: src/tracing/trace_writer_base.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+namespace perfetto {
+
+// This destructor needs to be defined in a dedicated translation unit and
+// cannot be merged together with the other ones in virtual_destructors.cc.
+// This is because trace_writer_base.h/cc  is part of a separate target
+// (src/public:common) that is linked also by other part of the codebase.
+
+TraceWriterBase::~TraceWriterBase() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/id_allocator.cc
+// gen_amalgamated begin header: src/tracing/core/id_allocator.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_TRACING_CORE_ID_ALLOCATOR_H_
+#define SRC_TRACING_CORE_ID_ALLOCATOR_H_
+
+#include <stdint.h>
+
+#include <type_traits>
+#include <vector>
+
+namespace perfetto {
+
+// Handles assigment of IDs (int types) from a fixed-size pool.
+// Zero is not considered a valid ID.
+// The base class takes always a uint32_t and the derived class casts and checks
+// bounds at compile time. This is to avoid bloating code with different
+// instances of the main class for each size.
+class IdAllocatorGeneric {
+ public:
+  // |max_id| is inclusive.
+  explicit IdAllocatorGeneric(uint32_t max_id);
+  ~IdAllocatorGeneric();
+
+  // Returns an ID in the range [1, max_id] or 0 if no more ids are available.
+  uint32_t AllocateGeneric();
+  void FreeGeneric(uint32_t);
+
+  bool IsEmpty() const;
+
+ private:
+  IdAllocatorGeneric(const IdAllocatorGeneric&) = delete;
+  IdAllocatorGeneric& operator=(const IdAllocatorGeneric&) = delete;
+
+  const uint32_t max_id_;
+  uint32_t last_id_ = 0;
+  std::vector<bool> ids_;
+};
+
+template <typename T = uint32_t>
+class IdAllocator : public IdAllocatorGeneric {
+ public:
+  explicit IdAllocator(T end) : IdAllocatorGeneric(end) {
+    static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
+                  "T must be an unsigned integer");
+    static_assert(sizeof(T) <= sizeof(uint32_t), "T is too big");
+  }
+
+  T Allocate() { return static_cast<T>(AllocateGeneric()); }
+  void Free(T id) { FreeGeneric(id); }
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_ID_ALLOCATOR_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+
+IdAllocatorGeneric::IdAllocatorGeneric(uint32_t max_id) : max_id_(max_id) {
+  PERFETTO_DCHECK(max_id > 1);
+}
+
+IdAllocatorGeneric::~IdAllocatorGeneric() = default;
+
+uint32_t IdAllocatorGeneric::AllocateGeneric() {
+  for (uint32_t ignored = 1; ignored <= max_id_; ignored++) {
+    last_id_ = last_id_ < max_id_ ? last_id_ + 1 : 1;
+    const auto id = last_id_;
+
+    // 0 is never a valid ID. So if we are looking for |id| == N and there are
+    // N or less elements in the vector, they must necessarily be all < N.
+    // e.g. if |id| == 4 and size() == 4, the vector will contain IDs 0,1,2,3.
+    if (id >= ids_.size()) {
+      ids_.resize(id + 1);
+      ids_[id] = true;
+      return id;
+    }
+
+    if (!ids_[id]) {
+      ids_[id] = true;
+      return id;
+    }
+  }
+  return 0;
+}
+
+void IdAllocatorGeneric::FreeGeneric(uint32_t id) {
+  if (id == 0 || id >= ids_.size() || !ids_[id]) {
+    PERFETTO_DFATAL("Invalid id.");
+    return;
+  }
+  ids_[id] = false;
+}
+
+bool IdAllocatorGeneric::IsEmpty() const {
+  for (auto id : ids_) {
+    if (id)
+      return false;
+  }
+  return true;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/in_process_shared_memory.cc
+// gen_amalgamated begin header: src/tracing/core/in_process_shared_memory.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
+
+#include <stddef.h>
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+
+namespace perfetto {
+
+// An abstract interface that models the shared memory region shared between
+// Service and Producer. The concrete implementation of this is up to the
+// transport layer. This can be as simple as a malloc()-ed buffer, if both
+// Producer and Service are hosted in the same process, or some posix shared
+// memory for the out-of-process case (see src/unix_rpc).
+// Both this class and the Factory are subclassed by the transport layer, which
+// will attach platform specific fields to it (e.g., a unix file descriptor).
+class PERFETTO_EXPORT_COMPONENT SharedMemory {
+ public:
+  class PERFETTO_EXPORT_COMPONENT Factory {
+   public:
+    virtual ~Factory();
+    virtual std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) = 0;
+  };
+
+  // The transport layer is expected to tear down the resource associated to
+  // this object region when destroyed.
+  virtual ~SharedMemory();
+
+  virtual void* start() const = 0;
+  virtual size_t size() const = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef SRC_TRACING_CORE_IN_PROCESS_SHARED_MEMORY_H_
+#define SRC_TRACING_CORE_IN_PROCESS_SHARED_MEMORY_H_
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+
+namespace perfetto {
+
+// An implementation of the ShareMemory interface that allocates memory that can
+// only be shared intra-process.
+class InProcessSharedMemory : public SharedMemory {
+ public:
+  static constexpr size_t kDefaultSize = 128 * 1024;
+
+  // Default ctor used for intra-process shmem between a producer and the
+  // service.
+  explicit InProcessSharedMemory(size_t size)
+      : mem_(base::PagedMemory::Allocate(size)) {}
+  ~InProcessSharedMemory() override;
+
+  static std::unique_ptr<InProcessSharedMemory> Create(
+      size_t size = kDefaultSize) {
+    return std::make_unique<InProcessSharedMemory>(size);
+  }
+
+  // SharedMemory implementation.
+  void* start() const override;
+  size_t size() const override;
+
+  class Factory : public SharedMemory::Factory {
+   public:
+    ~Factory() override;
+    std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
+      return InProcessSharedMemory::Create(size);
+    }
+  };
+
+ private:
+  base::PagedMemory mem_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_IN_PROCESS_SHARED_MEMORY_H_
+/*
+ * Copyright (C) 2023 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/in_process_shared_memory.h"
+
+namespace perfetto {
+
+InProcessSharedMemory::~InProcessSharedMemory() = default;
+InProcessSharedMemory::Factory::~Factory() = default;
+
+void* InProcessSharedMemory::start() const {
+  return mem_.Get();
+}
+size_t InProcessSharedMemory::size() const {
+  return mem_.size();
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/null_trace_writer.cc
+// gen_amalgamated begin header: src/tracing/core/null_trace_writer.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_writer.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/basic_types.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+
+namespace perfetto {
+
+// Unique within the scope of the tracing service.
+using TracingSessionID = uint64_t;
+
+// Unique within the scope of the tracing service.
+using ProducerID = uint16_t;
+
+// Unique within the scope of the tracing service.
+using DataSourceInstanceID = uint64_t;
+
+// Unique within the scope of a Producer.
+using WriterID = uint16_t;
+
+// Unique within the scope of the tracing service.
+using FlushRequestID = uint64_t;
+
+// Combines Producer and Writer ID in one word which can be used as key for
+// hashtables and other data structures.
+using ProducerAndWriterID = uint32_t;
+
+inline ProducerAndWriterID MkProducerAndWriterID(ProducerID p, WriterID w) {
+  static_assert(
+      sizeof(ProducerID) + sizeof(WriterID) == sizeof(ProducerAndWriterID),
+      "MkProducerAndWriterID() and GetProducerAndWriterID() need updating");
+  return (static_cast<ProducerAndWriterID>(p) << (sizeof(WriterID) * 8)) | w;
+}
+
+inline void GetProducerAndWriterID(ProducerAndWriterID x,
+                                   ProducerID* p,
+                                   WriterID* w) {
+  static constexpr auto mask = (1ull << (sizeof(WriterID) * 8)) - 1;
+  *w = static_cast<WriterID>(x & mask);
+  *p = static_cast<ProducerID>(x >> (sizeof(WriterID) * 8));
+}
+
+// We need one FD per producer and we are not going to be able to keep > 64k FDs
+// open in the service.
+static constexpr ProducerID kMaxProducerID = static_cast<ProducerID>(-1);
+
+// 1024 Writers per producer seems a resonable bound. This reduces the ability
+// to memory-DoS the service by having to keep track of too many writer IDs.
+static constexpr WriterID kMaxWriterID = static_cast<WriterID>((1 << 10) - 1);
+
+// Unique within the scope of a {ProducerID, WriterID} tuple.
+using ChunkID = uint32_t;
+static constexpr ChunkID kMaxChunkID = static_cast<ChunkID>(-1);
+
+// Unique within the scope of the tracing service.
+using BufferID = uint16_t;
+
+// Target buffer ID for SharedMemoryArbiter. Values up to max uint16_t are
+// equivalent to a bound BufferID. Values above max uint16_t are reservation IDs
+// for the target buffer of a startup trace writer. Reservation IDs will be
+// translated to actual BufferIDs after they are bound by
+// SharedMemoryArbiter::BindStartupTargetBuffer().
+// TODO(mohitms): Delete this type and use `struct {uint16 ; uint16;}` instead.
+using MaybeUnboundBufferID = uint32_t;
+
+// Keep this in sync with SharedMemoryABI::PageHeader::target_buffer.
+static constexpr BufferID kMaxTraceBufferID = static_cast<BufferID>(-1);
+
+// Unique within the scope of a tracing session.
+using PacketSequenceID = uint32_t;
+// Used for extra packets emitted by the service, such as statistics.
+static constexpr PacketSequenceID kServicePacketSequenceID = 1;
+static constexpr PacketSequenceID kMaxPacketSequenceID =
+    static_cast<PacketSequenceID>(-1);
+
+constexpr uint32_t kDefaultFlushTimeoutMs = 5000;
+
+// The special id 0xffff..ffff represents the tracing session with the highest
+// bugreport score. This is used for CloneSession(kBugreportSessionId).
+constexpr TracingSessionID kBugreportSessionId =
+    static_cast<TracingSessionID>(-1);
+
+// The ID of a machine in a multi-machine tracing session.
+using MachineID = base::MachineID;
+constexpr MachineID kDefaultMachineID = base::kDefaultMachineID;
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+namespace perfetto {
+
+namespace protos {
+namespace pbzero {
+class TracePacket;
+}  // namespace pbzero
+}  // namespace protos
+
+// See comments in include/perfetto/tracing/trace_writer_base.h
+class PERFETTO_EXPORT_COMPONENT TraceWriter : public TraceWriterBase {
+ public:
+  using TracePacketHandle =
+      protozero::MessageHandle<protos::pbzero::TracePacket>;
+
+  TraceWriter();
+  ~TraceWriter() override;
+
+  virtual WriterID writer_id() const = 0;
+
+ private:
+  TraceWriter(const TraceWriter&) = delete;
+  TraceWriter& operator=(const TraceWriter&) = delete;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
+#define SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
+
+namespace perfetto {
+
+// A specialization of TraceWriter which no-ops all the writes routing them
+// into a fixed region of memory
+// See //include/perfetto/ext/tracing/core/trace_writer.h for docs.
+class NullTraceWriter : public TraceWriter {
+ public:
+  NullTraceWriter();
+  ~NullTraceWriter() override;
+
+  // TraceWriter implementation. See documentation in trace_writer.h.
+  // TracePacketHandle is defined in trace_writer.h
+  TracePacketHandle NewTracePacket() override;
+  void FinishTracePacket() override;
+  void Flush(std::function<void()> callback = {}) override;
+  WriterID writer_id() const override;
+  uint64_t written() const override;
+
+ private:
+  NullTraceWriter(const NullTraceWriter&) = delete;
+  NullTraceWriter& operator=(const NullTraceWriter&) = delete;
+
+  protozero::ScatteredStreamWriterNullDelegate delegate_;
+  protozero::ScatteredStreamWriter stream_;
+
+  // The packet returned via NewTracePacket(). It is owned by this class,
+  // TracePacketHandle has just a pointer to it.
+  std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
+      cur_packet_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+
+NullTraceWriter::NullTraceWriter() : delegate_(4096), stream_(&delegate_) {
+  cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
+  cur_packet_->Finalize();  // To avoid the DCHECK in NewTracePacket().
+}
+
+NullTraceWriter::~NullTraceWriter() {}
+
+void NullTraceWriter::Flush(std::function<void()> callback) {
+  // Flush() cannot be called in the middle of a TracePacket.
+  PERFETTO_CHECK(cur_packet_->is_finalized());
+
+  if (callback)
+    callback();
+}
+
+NullTraceWriter::TracePacketHandle NullTraceWriter::NewTracePacket() {
+  // If we hit this, the caller is calling NewTracePacket() without having
+  // finalized the previous packet.
+  PERFETTO_DCHECK(cur_packet_->is_finalized());
+  cur_packet_->Reset(&stream_);
+  return TraceWriter::TracePacketHandle(cur_packet_.get());
+}
+
+void NullTraceWriter::FinishTracePacket() {
+  cur_packet_->Finalize();
+}
+
+WriterID NullTraceWriter::writer_id() const {
+  return 0;
+}
+
+uint64_t NullTraceWriter::written() const {
+  return 0;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/shared_memory_abi.cc
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_abi.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <array>
+#include <atomic>
+#include <bitset>
+#include <thread>
+#include <type_traits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+
+// This file defines the binary interface of the memory buffers shared between
+// Producer and Service. This is a long-term stable ABI and has to be backwards
+// compatible to deal with mismatching Producer and Service versions.
+//
+// Overview
+// --------
+// SMB := "Shared Memory Buffer".
+// In the most typical case of a multi-process architecture (i.e. Producer and
+// Service are hosted by different processes), a Producer means almost always
+// a "client process producing data" (almost: in some cases a process might host
+// > 1 Producer, if it links two libraries, independent of each other, that both
+// use Perfetto tracing).
+// The Service has one SMB for each Producer.
+// A producer has one or (typically) more data sources. They all share the same
+// SMB.
+// The SMB is a staging area to decouple data sources living in the Producer
+// and allow them to do non-blocking async writes.
+// The SMB is *not* the ultimate logging buffer seen by the Consumer. That one
+// is larger (~MBs) and not shared with Producers.
+// Each SMB is small, typically few KB. Its size is configurable by the producer
+// within a max limit of ~MB (see kMaxShmSize in tracing_service_impl.cc).
+// The SMB is partitioned into fixed-size Page(s). The size of the Pages are
+// determined by each Producer at connection time and cannot be changed.
+// Hence, different producers can have SMB(s) that have a different Page size
+// from each other, but the page size will be constant throughout all the
+// lifetime of the SMB.
+// Page(s) are partitioned by the Producer into variable size Chunk(s):
+//
+// +------------+      +--------------------------+
+// | Producer 1 |  <-> |      SMB 1 [~32K - 1MB]  |
+// +------------+      +--------+--------+--------+
+//                     |  Page  |  Page  |  Page  |
+//                     +--------+--------+--------+
+//                     | Chunk  |        | Chunk  |
+//                     +--------+  Chunk +--------+ <----+
+//                     | Chunk  |        | Chunk  |      |
+//                     +--------+--------+--------+      +---------------------+
+//                                                       |       Service       |
+// +------------+      +--------------------------+      +---------------------+
+// | Producer 2 |  <-> |      SMB 2 [~32K - 1MB]  |     /| large ring buffers  |
+// +------------+      +--------+--------+--------+ <--+ | (100K - several MB) |
+//                     |  Page  |  Page  |  Page  |      +---------------------+
+//                     +--------+--------+--------+
+//                     | Chunk  |        | Chunk  |
+//                     +--------+  Chunk +--------+
+//                     | Chunk  |        | Chunk  |
+//                     +--------+--------+--------+
+//
+// * Sizes of both SMB and ring buffers are purely indicative and decided at
+// configuration time by the Producer (for SMB sizes) and the Consumer (for the
+// final ring buffer size).
+
+// Page
+// ----
+// A page is a portion of the shared memory buffer and defines the granularity
+// of the interaction between the Producer and tracing Service. When scanning
+// the shared memory buffer to determine if something should be moved to the
+// central logging buffers, the Service most of the times looks at and moves
+// whole pages. Similarly, the Producer sends an IPC to invite the Service to
+// drain the shared memory buffer only when a whole page is filled.
+// Having fixed the total SMB size (hence the total memory overhead), the page
+// size is a triangular tradeoff between:
+// 1) IPC traffic: smaller pages -> more IPCs.
+// 2) Producer lock freedom: larger pages -> larger chunks -> data sources can
+//    write more data without needing to swap chunks and synchronize.
+// 3) Risk of write-starving the SMB: larger pages -> higher chance that the
+//    Service won't manage to drain them and the SMB remains full.
+// The page size, on the other side, has no implications on wasted memory due to
+// fragmentations (see Chunk below).
+// The size of the page is chosen by the Service at connection time and stays
+// fixed throughout all the lifetime of the Producer. Different producers (i.e.
+// ~ different client processes) can use different page sizes.
+// The page size must be an integer multiple of 4k (this is to allow VM page
+// stealing optimizations) and obviously has to be an integer divisor of the
+// total SMB size.
+
+// Chunk
+// -----
+// A chunk is a portion of a Page which is written and handled by a Producer.
+// A chunk contains a linear sequence of TracePacket(s) (the root proto).
+// A chunk cannot be written concurrently by two data sources. Protobufs must be
+// encoded as contiguous byte streams and cannot be interleaved. Therefore, on
+// the Producer side, a chunk is almost always owned exclusively by one thread
+// (% extremely peculiar slow-path cases).
+// Chunks are essentially single-writer single-thread lock-free arenas. Locking
+// happens only when a Chunk is full and a new one needs to be acquired.
+// Locking happens only within the scope of a Producer process. There is no
+// inter-process locking. The Producer cannot lock the Service and viceversa.
+// In the worst case, any of the two can starve the SMB, by marking all chunks
+// as either being read or written. But that has the only side effect of
+// losing the trace data.
+// The Producer can decide to partition each page into a number of limited
+// configurations (e.g., 1 page == 1 chunk, 1 page == 2 chunks and so on).
+
+// TracePacket
+// -----------
+// Is the atom of tracing. Putting aside pages and chunks a trace is merely a
+// sequence of TracePacket(s). TracePacket is the root protobuf message.
+// A TracePacket can span across several chunks (hence even across several
+// pages). A TracePacket can therefore be >> chunk size, >> page size and even
+// >> SMB size. The Chunk header carries metadata to deal with the TracePacket
+// splitting case.
+
+// Use only explicitly-sized types below. DO NOT use size_t or any architecture
+// dependent size (e.g. size_t) in the struct fields. This buffer will be read
+// and written by processes that have a different bitness in the same OS.
+// Instead it's fine to assume little-endianess. Big-endian is a dream we are
+// not currently pursuing.
+
+class SharedMemoryABI {
+ public:
+  static constexpr size_t kMinPageSize = 4 * 1024;
+
+  // This is due to Chunk::size being 16 bits.
+  static constexpr size_t kMaxPageSize = 64 * 1024;
+
+  // "14" is the max number that can be encoded in a 32 bit atomic word using
+  // 2 state bits per Chunk and leaving 4 bits for the page layout.
+  // See PageLayout below.
+  static constexpr size_t kMaxChunksPerPage = 14;
+
+  // Each TracePacket fragment in the Chunk is prefixed by a VarInt stating its
+  // size that is up to 4 bytes long. Since the size is often known after the
+  // fragment has been filled, the VarInt is often redundantly encoded (see
+  // proto_utils.h) to be exactly 4 bytes.
+  static constexpr size_t kPacketHeaderSize = 4;
+
+  // TraceWriter specifies this invalid packet/fragment size to signal to the
+  // service that a packet should be discarded, because the TraceWriter couldn't
+  // write its remaining fragments (e.g. because the SMB was exhausted).
+  static constexpr size_t kPacketSizeDropPacket =
+      protozero::proto_utils::kMaxMessageLength;
+
+  // Chunk states and transitions:
+  //    kChunkFree  <----------------+
+  //         |  (Producer)           |
+  //         V                       |
+  //  kChunkBeingWritten             |
+  //         |  (Producer)           |
+  //         V                       |
+  //  kChunkComplete                 |
+  //         |  (Service)            |
+  //         V                       |
+  //  kChunkBeingRead                |
+  //        |   (Service)            |
+  //        +------------------------+
+  //
+  // The ABI has an "emulation mode" for transports where shared memory isn't
+  // supported. In this mode, kChunkBeingRead is skipped. A chunk in the
+  // kChunkComplete state is released as free after the producer serializes
+  // chunk content to the protobuf message.
+  enum ChunkState : uint32_t {
+    // The Chunk is free. The Service shall never touch it, the Producer can
+    // acquire it and transition it into kChunkBeingWritten.
+    kChunkFree = 0,
+
+    // The Chunk is being used by the Producer and is not complete yet.
+    // The Service shall never touch kChunkBeingWritten pages.
+    kChunkBeingWritten = 1,
+
+    // The Service is moving the page into its non-shared ring buffer. The
+    // Producer shall never touch kChunkBeingRead pages.
+    kChunkBeingRead = 2,
+
+    // The Producer is done writing the page and won't touch it again. The
+    // Service can now move it to its non-shared ring buffer.
+    // kAllChunksComplete relies on this being == 3.
+    kChunkComplete = 3,
+  };
+  static constexpr const char* kChunkStateStr[] = {"Free", "BeingWritten",
+                                                   "BeingRead", "Complete"};
+
+  enum PageLayout : uint32_t {
+    // The page is fully free and has not been partitioned yet.
+    kPageNotPartitioned = 0,
+
+    // TODO(primiano): Aligning a chunk @ 16 bytes could allow to use faster
+    // intrinsics based on quad-word moves. Do the math and check what is the
+    // fragmentation loss.
+
+    // align4(X) := the largest integer N s.t. (N % 4) == 0 && N <= X.
+    // 8 == sizeof(PageHeader).
+    kPageDiv1 = 1,   // Only one chunk of size: PAGE_SIZE - 8.
+    kPageDiv2 = 2,   // Two chunks of size: align4((PAGE_SIZE - 8) / 2).
+    kPageDiv4 = 3,   // Four chunks of size: align4((PAGE_SIZE - 8) / 4).
+    kPageDiv7 = 4,   // Seven chunks of size: align4((PAGE_SIZE - 8) / 7).
+    kPageDiv14 = 5,  // Fourteen chunks of size: align4((PAGE_SIZE - 8) / 14).
+
+    // The rationale for 7 and 14 above is to maximize the page usage for the
+    // likely case of |page_size| == 4096:
+    // (((4096 - 8) / 14) % 4) == 0, while (((4096 - 8) / 16 % 4)) == 3. So
+    // Div16 would waste 3 * 16 = 48 bytes per page for chunk alignment gaps.
+
+    kPageDivReserved1 = 6,
+    kPageDivReserved2 = 7,
+    kNumPageLayouts = 8,
+  };
+
+  // Keep this consistent with the PageLayout enum above.
+  static constexpr uint32_t kNumChunksForLayout[] = {0, 1, 2, 4, 7, 14, 0, 0};
+
+  enum class ShmemMode {
+    // The default mode, where the shared buffer is visible to both the producer
+    // and the service.
+    kDefault,
+
+    // The emulation mode, used for producer ports without shared memory. The
+    // state transitions are all done in the producer process.
+    kShmemEmulation,
+  };
+
+  // Layout of a Page.
+  // +===================================================+
+  // | Page header [8 bytes]                             |
+  // | Tells how many chunks there are, how big they are |
+  // | and their state (free, read, write, complete).    |
+  // +===================================================+
+  // +***************************************************+
+  // | Chunk #0 header [8 bytes]                         |
+  // | Tells how many packets there are and whether the  |
+  // | whether the 1st and last ones are fragmented.     |
+  // | Also has a chunk id to reassemble fragments.    |
+  // +***************************************************+
+  // +---------------------------------------------------+
+  // | Packet #0 size [varint, up to 4 bytes]            |
+  // + - - - - - - - - - - - - - - - - - - - - - - - - - +
+  // | Packet #0 payload                                 |
+  // | A TracePacket protobuf message                    |
+  // +---------------------------------------------------+
+  //                         ...
+  // + . . . . . . . . . . . . . . . . . . . . . . . . . +
+  // |      Optional padding to maintain aligment        |
+  // + . . . . . . . . . . . . . . . . . . . . . . . . . +
+  // +---------------------------------------------------+
+  // | Packet #N size [varint, up to 4 bytes]            |
+  // + - - - - - - - - - - - - - - - - - - - - - - - - - +
+  // | Packet #N payload                                 |
+  // | A TracePacket protobuf message                    |
+  // +---------------------------------------------------+
+  //                         ...
+  // +***************************************************+
+  // | Chunk #M header [8 bytes]                         |
+  //                         ...
+
+  // Alignment applies to start offset only. The Chunk size is *not* aligned.
+  static constexpr uint32_t kChunkAlignment = 4;
+  static constexpr uint32_t kChunkShift = 2;
+  static constexpr uint32_t kChunkMask = 0x3;
+  static constexpr uint32_t kLayoutMask = 0x70000000;
+  static constexpr uint32_t kLayoutShift = 28;
+  static constexpr uint32_t kAllChunksMask = 0x0FFFFFFF;
+
+  // This assumes that kChunkComplete == 3.
+  static constexpr uint32_t kAllChunksComplete = 0x0FFFFFFF;
+  static constexpr uint32_t kAllChunksFree = 0;
+  static constexpr size_t kInvalidPageIdx = static_cast<size_t>(-1);
+
+  // There is one page header per page, at the beginning of the page.
+  struct PageHeader {
+    // |layout| bits:
+    // [31] [30:28] [27:26] ... [1:0]
+    //  |      |       |     |    |
+    //  |      |       |     |    +---------- ChunkState[0]
+    //  |      |       |     +--------------- ChunkState[12..1]
+    //  |      |       +--------------------- ChunkState[13]
+    //  |      +----------------------------- PageLayout (0 == page fully free)
+    //  +------------------------------------ Reserved for future use
+    std::atomic<uint32_t> layout;
+
+    // If we'll ever going to use this in the future it might come handy
+    // reviving the kPageBeingPartitioned logic (look in git log, it was there
+    // at some point in the past).
+    uint32_t reserved;
+  };
+
+  // There is one Chunk header per chunk (hence PageLayout per page) at the
+  // beginning of each chunk.
+  struct ChunkHeader {
+    enum Flags : uint8_t {
+      // If set, the first TracePacket in the chunk is partial and continues
+      // from |chunk_id| - 1 (within the same |writer_id|).
+      kFirstPacketContinuesFromPrevChunk = 1 << 0,
+
+      // If set, the last TracePacket in the chunk is partial and continues on
+      // |chunk_id| + 1 (within the same |writer_id|).
+      kLastPacketContinuesOnNextChunk = 1 << 1,
+
+      // If set, the last (fragmented) TracePacket in the chunk has holes (even
+      // if the chunk is marked as kChunkComplete) that need to be patched
+      // out-of-band before the chunk can be read.
+      kChunkNeedsPatching = 1 << 2,
+    };
+
+    struct Packets {
+      // Number of valid TracePacket protobuf messages contained in the chunk.
+      // Each TracePacket is prefixed by its own size. This field is
+      // monotonically updated by the Producer with release store semantic when
+      // the packet at position |count| is started. This last packet may not be
+      // considered complete until |count| is incremented for the subsequent
+      // packet or the chunk is completed.
+      uint16_t count : 10;
+      static constexpr size_t kMaxCount = (1 << 10) - 1;
+
+      // See Flags above.
+      uint16_t flags : 6;
+    };
+
+    // A monotonic counter of the chunk within the scoped of a |writer_id|.
+    // The tuple (ProducerID, WriterID, ChunkID) allows to figure out if two
+    // chunks are contiguous (and hence a trace packets spanning across them can
+    // be glued) or we had some holes due to the ring buffer wrapping.
+    // This is set only when transitioning from kChunkFree to kChunkBeingWritten
+    // and remains unchanged throughout the remaining lifetime of the chunk.
+    std::atomic<uint32_t> chunk_id;
+
+    // ID of the writer, unique within the producer.
+    // Like |chunk_id|, this is set only when transitioning from kChunkFree to
+    // kChunkBeingWritten.
+    std::atomic<uint16_t> writer_id;
+
+    // There is no ProducerID here. The service figures that out from the IPC
+    // channel, which is unspoofable.
+
+    // Updated with release-store semantics.
+    std::atomic<Packets> packets;
+  };
+
+  class Chunk {
+   public:
+    Chunk();  // Constructs an invalid chunk.
+
+    // Chunk is move-only, to document the scope of the Acquire/Release
+    // TryLock operations below.
+    Chunk(const Chunk&) = delete;
+    Chunk operator=(const Chunk&) = delete;
+    Chunk(Chunk&&) noexcept;
+    Chunk& operator=(Chunk&&);
+
+    uint8_t* begin() const { return begin_; }
+    uint8_t* end() const { return begin_ + size_; }
+
+    // Size, including Chunk header.
+    size_t size() const { return size_; }
+
+    // Begin of the first packet (or packet fragment).
+    uint8_t* payload_begin() const { return begin_ + sizeof(ChunkHeader); }
+    size_t payload_size() const {
+      PERFETTO_DCHECK(size_ >= sizeof(ChunkHeader));
+      return size_ - sizeof(ChunkHeader);
+    }
+
+    bool is_valid() const { return begin_ && size_; }
+
+    // Index of the chunk within the page [0..13] (13 comes from kPageDiv14).
+    uint8_t chunk_idx() const { return chunk_idx_; }
+
+    ChunkHeader* header() { return reinterpret_cast<ChunkHeader*>(begin_); }
+
+    uint16_t writer_id() {
+      return header()->writer_id.load(std::memory_order_relaxed);
+    }
+
+    // Returns the count of packets and the flags with acquire-load semantics.
+    std::pair<uint16_t, uint8_t> GetPacketCountAndFlags() {
+      auto packets = header()->packets.load(std::memory_order_acquire);
+      const uint16_t packets_count = packets.count;
+      const uint8_t packets_flags = packets.flags;
+      return std::make_pair(packets_count, packets_flags);
+    }
+
+    // Increases |packets.count| with release semantics (note, however, that the
+    // packet count is incremented *before* starting writing a packet). Returns
+    // the new packet count. The increment is atomic but NOT race-free (i.e. no
+    // CAS). Only the Producer is supposed to perform this increment, and it's
+    // supposed to do that in a thread-safe way (holding a lock). A Chunk cannot
+    // be shared by multiple Producer threads without locking. The packet count
+    // is cleared by TryAcquireChunk(), when passing the new header for the
+    // chunk.
+    uint16_t IncrementPacketCount() {
+      ChunkHeader* chunk_header = header();
+      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
+      packets.count++;
+      chunk_header->packets.store(packets, std::memory_order_release);
+      return packets.count;
+    }
+
+    // Flags are cleared by TryAcquireChunk(), by passing the new header for
+    // the chunk, or through ClearNeedsPatchingFlag.
+    void SetFlag(ChunkHeader::Flags flag) {
+      ChunkHeader* chunk_header = header();
+      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
+      packets.flags |= flag;
+      chunk_header->packets.store(packets, std::memory_order_release);
+    }
+
+    // This flag can only be cleared by the producer while it is still holding
+    // on to the chunk - i.e. while the chunk is still in state
+    // ChunkState::kChunkBeingWritten and hasn't been transitioned to
+    // ChunkState::kChunkComplete. This is ok, because the service is oblivious
+    // to the needs patching flag before the chunk is released as complete.
+    void ClearNeedsPatchingFlag() {
+      ChunkHeader* chunk_header = header();
+      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
+      packets.flags &= ~ChunkHeader::kChunkNeedsPatching;
+      chunk_header->packets.store(packets, std::memory_order_release);
+    }
+
+   private:
+    friend class SharedMemoryABI;
+    Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx);
+
+    // Don't add extra fields, keep the move operator fast.
+    uint8_t* begin_ = nullptr;
+    uint16_t size_ = 0;
+    uint8_t chunk_idx_ = 0;
+
+   public:
+    static constexpr size_t kMaxSize = 1ULL << sizeof(size_) * 8;
+  };
+
+  // Construct an instance from an existing shared memory buffer.
+  SharedMemoryABI(uint8_t* start,
+                  size_t size,
+                  size_t page_size,
+                  ShmemMode mode);
+  SharedMemoryABI();
+
+  void Initialize(uint8_t* start,
+                  size_t size,
+                  size_t page_size,
+                  ShmemMode mode);
+
+  uint8_t* start() const { return start_; }
+  uint8_t* end() const { return start_ + size_; }
+  size_t size() const { return size_; }
+  size_t page_size() const { return page_size_; }
+  size_t num_pages() const { return num_pages_; }
+  bool is_valid() { return num_pages() > 0; }
+
+  uint8_t* page_start(size_t page_idx) {
+    PERFETTO_DCHECK(page_idx < num_pages_);
+    return start_ + page_size_ * page_idx;
+  }
+
+  PageHeader* page_header(size_t page_idx) {
+    return reinterpret_cast<PageHeader*>(page_start(page_idx));
+  }
+
+  // Returns true if the page is fully clear and has not been partitioned yet.
+  // The state of the page can change at any point after this returns (or even
+  // before). The Producer should use this only as a hint to decide out whether
+  // it should TryPartitionPage() or acquire an individual chunk.
+  bool is_page_free(size_t page_idx) {
+    return page_header(page_idx)->layout.load(std::memory_order_relaxed) == 0;
+  }
+
+  // Returns true if all chunks in the page are kChunkComplete. As above, this
+  // is advisory only. The Service is supposed to use this only to decide
+  // whether to TryAcquireAllChunksForReading() or not.
+  bool is_page_complete(size_t page_idx) {
+    auto layout = page_header(page_idx)->layout.load(std::memory_order_relaxed);
+    const uint32_t num_chunks = GetNumChunksForLayout(layout);
+    if (num_chunks == 0)
+      return false;  // Non partitioned pages cannot be complete.
+    return (layout & kAllChunksMask) ==
+           (kAllChunksComplete & ((1 << (num_chunks * kChunkShift)) - 1));
+  }
+
+  // For testing / debugging only.
+  std::string page_header_dbg(size_t page_idx) {
+    uint32_t x = page_header(page_idx)->layout.load(std::memory_order_relaxed);
+    return std::bitset<32>(x).to_string();
+  }
+
+  // Returns the page layout, which is a bitmap that specifies the chunking
+  // layout of the page and each chunk's current state. Reads with an
+  // acquire-load semantic to ensure a producer's writes corresponding to an
+  // update of the layout (e.g. clearing a chunk's header) are observed
+  // consistently.
+  uint32_t GetPageLayout(size_t page_idx) {
+    return page_header(page_idx)->layout.load(std::memory_order_acquire);
+  }
+
+  // Returns a bitmap in which each bit is set if the corresponding Chunk exists
+  // in the page (according to the page layout) and is free. If the page is not
+  // partitioned it returns 0 (as if the page had no free chunks).
+  uint32_t GetFreeChunks(size_t page_idx);
+
+  // Tries to atomically partition a page with the given |layout|. Returns true
+  // if the page was free and has been partitioned with the given |layout|,
+  // false if the page wasn't free anymore by the time we got there.
+  // If succeeds all the chunks are atomically set in the kChunkFree state.
+  bool TryPartitionPage(size_t page_idx, PageLayout layout);
+
+  // Tries to atomically mark a single chunk within the page as
+  // kChunkBeingWritten. Returns an invalid chunk if the page is not partitioned
+  // or the chunk is not in the kChunkFree state. If succeeds sets the chunk
+  // header to |header|.
+  Chunk TryAcquireChunkForWriting(size_t page_idx,
+                                  size_t chunk_idx,
+                                  const ChunkHeader* header) {
+    return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingWritten, header);
+  }
+
+  // Similar to TryAcquireChunkForWriting. Fails if the chunk isn't in the
+  // kChunkComplete state.
+  Chunk TryAcquireChunkForReading(size_t page_idx, size_t chunk_idx) {
+    return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingRead, nullptr);
+  }
+
+  // The caller must have successfully TryAcquireAllChunksForReading() or it
+  // needs to guarantee that the chunk is already in the kChunkBeingWritten
+  // state.
+  Chunk GetChunkUnchecked(size_t page_idx,
+                          uint32_t page_layout,
+                          size_t chunk_idx);
+
+  // Creates a Chunk by adopting the given buffer (|data| and |size|) and chunk
+  // index. This is used for chunk data passed over the wire (e.g. tcp or
+  // vsock). The chunk should *not* be freed to the shared memory.
+  static Chunk MakeChunkFromSerializedData(uint8_t* data,
+                                           uint16_t size,
+                                           uint8_t chunk_idx) {
+    return Chunk(data, size, chunk_idx);
+  }
+
+  // Puts a chunk into the kChunkComplete state. Returns the page index.
+  size_t ReleaseChunkAsComplete(Chunk chunk) {
+    return ReleaseChunk(std::move(chunk), kChunkComplete);
+  }
+
+  // Puts a chunk into the kChunkFree state. Returns the page index.
+  size_t ReleaseChunkAsFree(Chunk chunk) {
+    return ReleaseChunk(std::move(chunk), kChunkFree);
+  }
+
+  ChunkState GetChunkState(size_t page_idx, size_t chunk_idx) {
+    PageHeader* phdr = page_header(page_idx);
+    uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
+    return GetChunkStateFromLayout(layout, chunk_idx);
+  }
+
+  std::pair<size_t, size_t> GetPageAndChunkIndex(const Chunk& chunk);
+
+  uint16_t GetChunkSizeForLayout(uint32_t page_layout) const {
+    return chunk_sizes_[(page_layout & kLayoutMask) >> kLayoutShift];
+  }
+
+  static ChunkState GetChunkStateFromLayout(uint32_t page_layout,
+                                            size_t chunk_idx) {
+    return static_cast<ChunkState>((page_layout >> (chunk_idx * kChunkShift)) &
+                                   kChunkMask);
+  }
+
+  static constexpr uint32_t GetNumChunksForLayout(uint32_t page_layout) {
+    return kNumChunksForLayout[(page_layout & kLayoutMask) >> kLayoutShift];
+  }
+
+  // Returns a bitmap in which each bit is set if the corresponding Chunk exists
+  // in the page (according to the page layout) and is not free. If the page is
+  // not partitioned it returns 0 (as if the page had no used chunks). Bit N
+  // corresponds to Chunk N.
+  static uint32_t GetUsedChunks(uint32_t page_layout) {
+    const uint32_t num_chunks = GetNumChunksForLayout(page_layout);
+    uint32_t res = 0;
+    for (uint32_t i = 0; i < num_chunks; i++) {
+      res |= ((page_layout & kChunkMask) != kChunkFree) ? (1 << i) : 0;
+      page_layout >>= kChunkShift;
+    }
+    return res;
+  }
+
+ private:
+  SharedMemoryABI(const SharedMemoryABI&) = delete;
+  SharedMemoryABI& operator=(const SharedMemoryABI&) = delete;
+
+  Chunk TryAcquireChunk(size_t page_idx,
+                        size_t chunk_idx,
+                        ChunkState,
+                        const ChunkHeader*);
+  size_t ReleaseChunk(Chunk chunk, ChunkState);
+
+  uint8_t* start_ = nullptr;
+  size_t size_ = 0;
+  size_t page_size_ = 0;
+  bool use_shmem_emulation_ = false;
+  size_t num_pages_ = 0;
+  std::array<uint16_t, kNumPageLayouts> chunk_sizes_;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <sys/mman.h>
+#endif
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+
+namespace perfetto {
+
+namespace {
+
+constexpr int kRetryAttempts = 64;
+
+inline void WaitBeforeNextAttempt(int attempt) {
+  if (attempt < kRetryAttempts / 2) {
+    std::this_thread::yield();
+  } else {
+    base::SleepMicroseconds((unsigned(attempt) / 10) * 1000);
+  }
+}
+
+// Returns the largest 4-bytes aligned chunk size <= |page_size| / |divider|
+// for each divider in PageLayout.
+constexpr size_t GetChunkSize(size_t page_size, size_t divider) {
+  return ((page_size - sizeof(SharedMemoryABI::PageHeader)) / divider) & ~3UL;
+}
+
+// Initializer for the const |chunk_sizes_| array.
+std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> InitChunkSizes(
+    size_t page_size) {
+  static_assert(SharedMemoryABI::kNumPageLayouts ==
+                    base::ArraySize(SharedMemoryABI::kNumChunksForLayout),
+                "kNumPageLayouts out of date");
+  std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> res = {};
+  for (size_t i = 0; i < SharedMemoryABI::kNumPageLayouts; i++) {
+    size_t num_chunks = SharedMemoryABI::kNumChunksForLayout[i];
+    size_t size = num_chunks == 0 ? 0 : GetChunkSize(page_size, num_chunks);
+    PERFETTO_CHECK(size <= std::numeric_limits<uint16_t>::max());
+    res[i] = static_cast<uint16_t>(size);
+  }
+  return res;
+}
+
+inline void ClearChunkHeader(SharedMemoryABI::ChunkHeader* header) {
+  header->writer_id.store(0u, std::memory_order_relaxed);
+  header->chunk_id.store(0u, std::memory_order_relaxed);
+  header->packets.store({}, std::memory_order_release);
+}
+
+}  // namespace
+
+SharedMemoryABI::SharedMemoryABI() = default;
+
+SharedMemoryABI::SharedMemoryABI(uint8_t* start,
+                                 size_t size,
+                                 size_t page_size,
+                                 ShmemMode mode) {
+  Initialize(start, size, page_size, mode);
+}
+
+void SharedMemoryABI::Initialize(uint8_t* start,
+                                 size_t size,
+                                 size_t page_size,
+                                 ShmemMode mode) {
+  start_ = start;
+  size_ = size;
+  page_size_ = page_size;
+  use_shmem_emulation_ = mode == ShmemMode::kShmemEmulation;
+  num_pages_ = size / page_size;
+  chunk_sizes_ = InitChunkSizes(page_size);
+  static_assert(sizeof(PageHeader) == 8, "PageHeader size");
+  static_assert(sizeof(ChunkHeader) == 8, "ChunkHeader size");
+  static_assert(sizeof(ChunkHeader::chunk_id) == sizeof(ChunkID),
+                "ChunkID size");
+
+  static_assert(sizeof(ChunkHeader::Packets) == 2, "ChunkHeader::Packets size");
+  static_assert(alignof(ChunkHeader) == kChunkAlignment,
+                "ChunkHeader alignment");
+
+  // In theory std::atomic does not guarantee that the underlying type
+  // consists only of the actual atomic word. Theoretically it could have
+  // locks or other state. In practice most implementations just implement
+  // them without extra state. The code below overlays the atomic into the
+  // SMB, hence relies on this implementation detail. This should be fine
+  // pragmatically (Chrome's base makes the same assumption), but let's have a
+  // check for this.
+  static_assert(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t) &&
+                    sizeof(std::atomic<uint16_t>) == sizeof(uint16_t),
+                "Incompatible STL <atomic> implementation");
+
+  // Chec that the kAllChunks(Complete,Free) are consistent with the
+  // ChunkState enum values.
+
+  // These must be zero because rely on zero-initialized memory being
+  // interpreted as "free".
+  static_assert(kChunkFree == 0 && kAllChunksFree == 0,
+                "kChunkFree/kAllChunksFree and must be 0");
+
+  static_assert((kAllChunksComplete & kChunkMask) == kChunkComplete,
+                "kAllChunksComplete out of sync with kChunkComplete");
+
+  // Check the consistency of the kMax... constants.
+  static_assert(sizeof(ChunkHeader::writer_id) == sizeof(WriterID),
+                "WriterID size");
+  ChunkHeader chunk_header{};
+  chunk_header.chunk_id.store(static_cast<uint32_t>(-1));
+  PERFETTO_CHECK(chunk_header.chunk_id.load() == kMaxChunkID);
+
+  chunk_header.writer_id.store(static_cast<uint16_t>(-1));
+  PERFETTO_CHECK(kMaxWriterID <= chunk_header.writer_id.load());
+
+  PERFETTO_CHECK(page_size >= kMinPageSize);
+  PERFETTO_CHECK(page_size <= kMaxPageSize);
+  PERFETTO_CHECK(page_size % kMinPageSize == 0);
+  PERFETTO_CHECK(reinterpret_cast<uintptr_t>(start) % kMinPageSize == 0);
+  PERFETTO_CHECK(size % page_size == 0);
+}
+
+SharedMemoryABI::Chunk SharedMemoryABI::GetChunkUnchecked(size_t page_idx,
+                                                          uint32_t page_layout,
+                                                          size_t chunk_idx) {
+  const size_t num_chunks = GetNumChunksForLayout(page_layout);
+  PERFETTO_DCHECK(chunk_idx < num_chunks);
+  // Compute the chunk virtual address and write it into |chunk|.
+  const uint16_t chunk_size = GetChunkSizeForLayout(page_layout);
+  size_t chunk_offset_in_page = sizeof(PageHeader) + chunk_idx * chunk_size;
+
+  Chunk chunk(page_start(page_idx) + chunk_offset_in_page, chunk_size,
+              static_cast<uint8_t>(chunk_idx));
+  PERFETTO_DCHECK(chunk.end() <= end());
+  return chunk;
+}
+
+SharedMemoryABI::Chunk SharedMemoryABI::TryAcquireChunk(
+    size_t page_idx,
+    size_t chunk_idx,
+    ChunkState desired_chunk_state,
+    const ChunkHeader* header) {
+  PERFETTO_DCHECK(desired_chunk_state == kChunkBeingRead ||
+                  desired_chunk_state == kChunkBeingWritten);
+  PageHeader* phdr = page_header(page_idx);
+  for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
+    uint32_t layout = phdr->layout.load(std::memory_order_acquire);
+    const size_t num_chunks = GetNumChunksForLayout(layout);
+
+    // The page layout has changed (or the page is free).
+    if (chunk_idx >= num_chunks)
+      return Chunk();
+
+    // Verify that the chunk is still in a state that allows the transition to
+    // |desired_chunk_state|. The only allowed transitions are:
+    // 1. kChunkFree -> kChunkBeingWritten (Producer).
+    // 2. kChunkComplete -> kChunkBeingRead (Service).
+    ChunkState expected_chunk_state =
+        desired_chunk_state == kChunkBeingWritten ? kChunkFree : kChunkComplete;
+    auto cur_chunk_state = (layout >> (chunk_idx * kChunkShift)) & kChunkMask;
+    if (cur_chunk_state != expected_chunk_state)
+      return Chunk();
+
+    uint32_t next_layout = layout;
+    next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
+    next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
+    if (phdr->layout.compare_exchange_strong(layout, next_layout,
+                                             std::memory_order_acq_rel)) {
+      // Compute the chunk virtual address and write it into |chunk|.
+      Chunk chunk = GetChunkUnchecked(page_idx, layout, chunk_idx);
+      if (desired_chunk_state == kChunkBeingWritten) {
+        PERFETTO_DCHECK(header);
+        ChunkHeader* new_header = chunk.header();
+        new_header->writer_id.store(header->writer_id,
+                                    std::memory_order_relaxed);
+        new_header->chunk_id.store(header->chunk_id, std::memory_order_relaxed);
+        new_header->packets.store(header->packets, std::memory_order_release);
+      }
+      return chunk;
+    }
+    WaitBeforeNextAttempt(attempt);
+  }
+  return Chunk();  // All our attempts failed.
+}
+
+bool SharedMemoryABI::TryPartitionPage(size_t page_idx, PageLayout layout) {
+  PERFETTO_DCHECK(layout >= kPageDiv1 && layout <= kPageDiv14);
+  uint32_t expected_layout = 0;  // Free page.
+  uint32_t next_layout = (layout << kLayoutShift) & kLayoutMask;
+  PageHeader* phdr = page_header(page_idx);
+  if (!phdr->layout.compare_exchange_strong(expected_layout, next_layout,
+                                            std::memory_order_acq_rel)) {
+    return false;
+  }
+  return true;
+}
+
+uint32_t SharedMemoryABI::GetFreeChunks(size_t page_idx) {
+  uint32_t layout =
+      page_header(page_idx)->layout.load(std::memory_order_relaxed);
+  const uint32_t num_chunks = GetNumChunksForLayout(layout);
+  uint32_t res = 0;
+  for (uint32_t i = 0; i < num_chunks; i++) {
+    res |= ((layout & kChunkMask) == kChunkFree) ? (1 << i) : 0;
+    layout >>= kChunkShift;
+  }
+  return res;
+}
+
+size_t SharedMemoryABI::ReleaseChunk(Chunk chunk,
+                                     ChunkState desired_chunk_state) {
+  PERFETTO_DCHECK(desired_chunk_state == kChunkComplete ||
+                  desired_chunk_state == kChunkFree);
+
+  size_t page_idx;
+  size_t chunk_idx;
+  std::tie(page_idx, chunk_idx) = GetPageAndChunkIndex(chunk);
+
+  // Reset header fields, so that the service can identify when the chunk's
+  // header has been initialized by the producer.
+  if (desired_chunk_state == kChunkFree)
+    ClearChunkHeader(chunk.header());
+
+  for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
+    PageHeader* phdr = page_header(page_idx);
+    uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
+    const size_t page_chunk_size = GetChunkSizeForLayout(layout);
+
+    // TODO(primiano): this should not be a CHECK, because a malicious producer
+    // could crash us by putting the chunk in an invalid state. This should
+    // gracefully fail. Keep a CHECK until then.
+    PERFETTO_CHECK(chunk.size() == page_chunk_size);
+    const uint32_t chunk_state = GetChunkStateFromLayout(layout, chunk_idx);
+
+    // Verify that the chunk is still in a state that allows the transition to
+    // |desired_chunk_state|. The only allowed transitions are:
+    // 1. kChunkBeingWritten -> kChunkComplete (Producer).
+    // 2. kChunkBeingRead -> kChunkFree (Service).
+    // Or in the emulation mode, the allowed transitions are:
+    // 1. kChunkBeingWritten -> kChunkComplete (Producer).
+    // 2. kChunkComplete -> kChunkFree (Producer).
+    ChunkState expected_chunk_state;
+    if (desired_chunk_state == kChunkComplete) {
+      expected_chunk_state = kChunkBeingWritten;
+    } else {
+      expected_chunk_state =
+          use_shmem_emulation_ ? kChunkComplete : kChunkBeingRead;
+    }
+
+    // TODO(primiano): should not be a CHECK (same rationale of comment above).
+    PERFETTO_CHECK(chunk_state == expected_chunk_state);
+    uint32_t next_layout = layout;
+    next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
+    next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
+
+    // If we are freeing a chunk and all the other chunks in the page are free
+    // we should de-partition the page and mark it as clear.
+    if ((next_layout & kAllChunksMask) == kAllChunksFree)
+      next_layout = 0;
+
+    if (phdr->layout.compare_exchange_strong(layout, next_layout,
+                                             std::memory_order_acq_rel)) {
+      return page_idx;
+    }
+    WaitBeforeNextAttempt(attempt);
+  }
+  // Too much contention on this page. Give up. This page will be left pending
+  // forever but there isn't much more we can do at this point.
+  PERFETTO_DFATAL("Too much contention on page.");
+  return kInvalidPageIdx;
+}
+
+SharedMemoryABI::Chunk::Chunk() = default;
+
+SharedMemoryABI::Chunk::Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx)
+    : begin_(begin), size_(size), chunk_idx_(chunk_idx) {
+  PERFETTO_CHECK(reinterpret_cast<uintptr_t>(begin) % kChunkAlignment == 0);
+  PERFETTO_CHECK(size > 0);
+}
+
+SharedMemoryABI::Chunk::Chunk(Chunk&& o) noexcept {
+  *this = std::move(o);
+}
+
+SharedMemoryABI::Chunk& SharedMemoryABI::Chunk::operator=(Chunk&& o) {
+  begin_ = o.begin_;
+  size_ = o.size_;
+  chunk_idx_ = o.chunk_idx_;
+  o.begin_ = nullptr;
+  o.size_ = 0;
+  o.chunk_idx_ = 0;
+  return *this;
+}
+
+std::pair<size_t, size_t> SharedMemoryABI::GetPageAndChunkIndex(
+    const Chunk& chunk) {
+  PERFETTO_DCHECK(chunk.is_valid());
+  PERFETTO_DCHECK(chunk.begin() >= start_);
+  PERFETTO_DCHECK(chunk.end() <= start_ + size_);
+
+  // TODO(primiano): The divisions below could be avoided if we cached
+  // |page_shift_|.
+  const uintptr_t rel_addr = static_cast<uintptr_t>(chunk.begin() - start_);
+  const size_t page_idx = rel_addr / page_size_;
+  const size_t offset = rel_addr % page_size_;
+  PERFETTO_DCHECK(offset >= sizeof(PageHeader));
+  PERFETTO_DCHECK(offset % kChunkAlignment == 0);
+  PERFETTO_DCHECK((offset - sizeof(PageHeader)) % chunk.size() == 0);
+  const size_t chunk_idx = (offset - sizeof(PageHeader)) / chunk.size();
+  PERFETTO_DCHECK(chunk_idx < kMaxChunksPerPage);
+  PERFETTO_DCHECK(chunk_idx < GetNumChunksForLayout(GetPageLayout(page_idx)));
+  return std::make_pair(page_idx, chunk_idx);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/shared_memory_arbiter_impl.cc
+// gen_amalgamated begin header: src/tracing/core/shared_memory_arbiter_impl.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_arbiter.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/tracing_service.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_packet.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/slice.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
+
+#include <stddef.h>
+#include <string.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+
+// A simple wrapper around a virtually contiguous memory range that contains a
+// TracePacket, or just a portion of it.
+struct Slice {
+  Slice() : start(nullptr), size(0) {}
+  Slice(const void* st, size_t sz) : start(st), size(sz) {}
+  Slice(Slice&& other) noexcept = default;
+
+  // Create a Slice which owns |size| bytes of memory.
+  static Slice Allocate(size_t size) {
+    Slice slice;
+    slice.own_data_.reset(new uint8_t[size]);
+    slice.start = &slice.own_data_[0];
+    slice.size = size;
+    return slice;
+  }
+
+  static Slice TakeOwnership(std::unique_ptr<uint8_t[]> buf, size_t size) {
+    Slice slice;
+    slice.own_data_ = std::move(buf);
+    slice.start = &slice.own_data_[0];
+    slice.size = size;
+    return slice;
+  }
+
+  uint8_t* own_data() {
+    PERFETTO_DCHECK(own_data_);
+    return own_data_.get();
+  }
+
+  const void* start;
+  size_t size;
+
+ private:
+  Slice(const Slice&) = delete;
+  void operator=(const Slice&) = delete;
+
+  std::unique_ptr<uint8_t[]> own_data_;
+};
+
+// TODO(primiano): most TracePacket(s) fit in a slice or two. We need something
+// a bit more clever here that has inline capacity for 2 slices and then uses a
+// std::forward_list or a std::vector for the less likely cases.
+using Slices = std::vector<Slice>;
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
+
+#include <stddef.h>
+#include <memory>
+#include <optional>
+#include <tuple>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
+
+namespace perfetto {
+
+// A wrapper around a byte buffer that contains a protobuf-encoded TracePacket
+// (see trace_packet.proto). The TracePacket is decoded only if the Consumer
+// requests that. This is to allow Consumer(s) to just stream the packet over
+// the network or save it to a file without wasting time decoding it and without
+// needing to depend on libprotobuf or the trace_packet.pb.h header.
+// If the packets are saved / streamed and not just consumed locally, consumers
+// should ensure to preserve the unknown fields in the proto. A consumer, in
+// fact, might have an older version .proto which is newer on the producer.
+class PERFETTO_EXPORT_COMPONENT TracePacket {
+ public:
+  using const_iterator = Slices::const_iterator;
+
+  // The field id of protos::Trace::packet, static_assert()-ed in the unittest.
+  static constexpr uint32_t kPacketFieldNumber = 1;
+
+  // Maximum size of the preamble returned by GetProtoPreamble().
+  static constexpr size_t kMaxPreambleBytes = 8;
+
+  TracePacket();
+  ~TracePacket();
+  TracePacket(TracePacket&&) noexcept;
+  TracePacket& operator=(TracePacket&&);
+
+  // Accesses all the raw slices in the packet, for saving them to file/network.
+  const Slices& slices() const { return slices_; }
+
+  // Mutator, used only by the service and tests.
+  void AddSlice(Slice);
+
+  // Does not copy / take ownership of the memory of the slice. The TracePacket
+  // will be valid only as long as the original buffer is valid.
+  void AddSlice(const void* start, size_t size);
+
+  // Total size of all slices.
+  size_t size() const { return size_; }
+
+  // Generates a protobuf preamble suitable to represent this packet as a
+  // repeated field within a root trace.proto message.
+  // Returns a pointer to a buffer, owned by this class, containing the preamble
+  // and its size.
+  std::tuple<char*, size_t> GetProtoPreamble();
+
+  // Returns the raw protobuf bytes of the slices, all stitched together into
+  // a string. Only for testing.
+  std::string GetRawBytesForTesting();
+
+  // Remembers the buffer index where this packet was taken from. This is
+  // usually populated for packets from a TraceBuffer, not synthetic ones.
+  std::optional<uint32_t> buffer_index_for_stats() const {
+    if (buffer_index_for_stats_ == 0)
+      return std::nullopt;
+    return buffer_index_for_stats_ - 1;
+  }
+  void set_buffer_index_for_stats(uint32_t v) {
+    buffer_index_for_stats_ = v + 1;
+  }
+
+ private:
+  TracePacket(const TracePacket&) = delete;
+  TracePacket& operator=(const TracePacket&) = delete;
+
+  Slices slices_;     // Not owned.
+  size_t size_ = 0;   // SUM(slice.size for slice in slices_).
+
+  // Internally we store index+1, and use 0 for the "not set" case.
+  uint32_t buffer_index_for_stats_ = 0;
+  char preamble_[kMaxPreambleBytes];  // Deliberately not initialized.
+
+  // Remember to update the move operators and their unittest if adding new
+  // fields. ConsumerIPCClientImpl::OnReadBuffersResponse() relies on
+  // std::move(TracePacket) to clear up the moved-from instance.
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
+
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/flush_flags.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+class Consumer;
+class Producer;
+class SharedMemoryArbiter;
+class TraceWriter;
+class ClientIdentity;
+
+// TODO: for the moment this assumes that all the calls happen on the same
+// thread/sequence. Not sure this will be the case long term in Chrome.
+
+// The API for the Producer port of the Service.
+// Subclassed by:
+// 1. The tracing_service_impl.cc business logic when returning it in response
+//    to the ConnectProducer() method.
+// 2. The transport layer (e.g., src/ipc) when the producer and
+//    the service don't talk locally but via some IPC mechanism.
+class PERFETTO_EXPORT_COMPONENT ProducerEndpoint {
+ public:
+  virtual ~ProducerEndpoint();
+
+  // Disconnects the endpoint from the service, while keeping the shared memory
+  // valid. After calling this, the endpoint will no longer call any methods
+  // on the Producer.
+  virtual void Disconnect() = 0;
+
+  // Called by the Producer to (un)register data sources. Data sources are
+  // identified by their name (i.e. DataSourceDescriptor.name)
+  virtual void RegisterDataSource(const DataSourceDescriptor&) = 0;
+  virtual void UpdateDataSource(const DataSourceDescriptor&) = 0;
+  virtual void UnregisterDataSource(const std::string& name) = 0;
+
+  // Associate the trace writer with the given |writer_id| with
+  // |target_buffer|. The service may use this information to retrieve and
+  // copy uncommitted chunks written by the trace writer into its associated
+  // buffer, e.g. when a producer process crashes or when a flush is
+  // necessary.
+  virtual void RegisterTraceWriter(uint32_t writer_id,
+                                   uint32_t target_buffer) = 0;
+
+  // Remove the association of the trace writer previously created via
+  // RegisterTraceWriter.
+  virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;
+
+  // Called by the Producer to signal that some pages in the shared memory
+  // buffer (shared between Service and Producer) have changed.
+  // When the Producer and the Service are hosted in the same process and
+  // hence potentially live on the same task runner, This method must call
+  // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
+  // if on the same thread. This is to avoid a deadlock where the Producer
+  // exhausts its SMB and stalls waiting for the service to catch up with
+  // reads, but the Service never gets to that because it lives on the same
+  // thread.
+  using CommitDataCallback = std::function<void()>;
+  virtual void CommitData(const CommitDataRequest&,
+                          CommitDataCallback callback = {}) = 0;
+
+  virtual SharedMemory* shared_memory() const = 0;
+
+  // Size of shared memory buffer pages. It's always a multiple of 4K.
+  // See shared_memory_abi.h
+  virtual size_t shared_buffer_page_size_kb() const = 0;
+
+  // Creates a trace writer, which allows to create events, handling the
+  // underying shared memory buffer and signalling to the Service. This method
+  // is thread-safe but the returned object is not. A TraceWriter should be
+  // used only from a single thread, or the caller has to handle sequencing
+  // via a mutex or equivalent. This method can only be called if
+  // TracingService::ConnectProducer was called with |in_process=true|.
+  // Args:
+  // |target_buffer| is the target buffer ID where the data produced by the
+  // writer should be stored by the tracing service. This value is passed
+  // upon creation of the data source (StartDataSource()) in the
+  // DataSourceConfig.target_buffer().
+  virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID target_buffer,
+      BufferExhaustedPolicy buffer_exhausted_policy =
+          BufferExhaustedPolicy::kDefault) = 0;
+
+  // TODO(eseckler): Also expose CreateStartupTraceWriter() ?
+
+  // In some cases you can access the producer's SharedMemoryArbiter (for
+  // example if TracingService::ConnectProducer is called with
+  // |in_process=true|). The SharedMemoryArbiter can be used to create
+  // TraceWriters which is able to directly commit chunks. For the
+  // |in_process=true| case this can be done without going through an IPC layer.
+  virtual SharedMemoryArbiter* MaybeSharedMemoryArbiter() = 0;
+
+  // Whether the service accepted a shared memory buffer provided by the
+  // producer.
+  virtual bool IsShmemProvidedByProducer() const = 0;
+
+  // Called in response to a Producer::Flush(request_id) call after all data
+  // for the flush request has been committed.
+  virtual void NotifyFlushComplete(FlushRequestID) = 0;
+
+  // Called in response to one or more Producer::StartDataSource(),
+  // if the data source registered setting the flag
+  // DataSourceDescriptor.will_notify_on_start.
+  virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;
+
+  // Called in response to one or more Producer::StopDataSource(),
+  // if the data source registered setting the flag
+  // DataSourceDescriptor.will_notify_on_stop.
+  virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;
+
+  // This informs the service to activate any of these triggers if any tracing
+  // session was waiting for them.
+  virtual void ActivateTriggers(const std::vector<std::string>&) = 0;
+
+  // Emits a synchronization barrier to linearize with the service. When
+  // |callback| is invoked, the caller has the guarantee that the service has
+  // seen and processed all the requests sent by this producer prior to the
+  // Sync() call. Used mainly in tests.
+  virtual void Sync(std::function<void()> callback) = 0;
+};  // class ProducerEndpoint.
+
+// The API for the Consumer port of the Service.
+// Subclassed by:
+// 1. The tracing_service_impl.cc business logic when returning it in response
+// to
+//    the ConnectConsumer() method.
+// 2. The transport layer (e.g., src/ipc) when the consumer and
+//    the service don't talk locally but via some IPC mechanism.
+class PERFETTO_EXPORT_COMPONENT ConsumerEndpoint {
+ public:
+  virtual ~ConsumerEndpoint();
+
+  // Enables tracing with the given TraceConfig. The ScopedFile argument is
+  // used only when TraceConfig.write_into_file == true.
+  // If TraceConfig.deferred_start == true data sources are configured via
+  // SetupDataSource() but are not started until StartTracing() is called.
+  // This is to support pre-initialization and fast triggering of traces.
+  // The ScopedFile argument is used only when TraceConfig.write_into_file
+  // == true.
+  virtual void EnableTracing(const TraceConfig&,
+                             base::ScopedFile = base::ScopedFile()) = 0;
+
+  // Update the trace config of an existing tracing session; only a subset
+  // of options can be changed mid-session. Currently the only
+  // supported functionality is expanding the list of producer_name_filters()
+  // (or removing the filter entirely) for existing data sources.
+  virtual void ChangeTraceConfig(const TraceConfig&) = 0;
+
+  // Starts all data sources configured in the trace config. This is used only
+  // after calling EnableTracing() with TraceConfig.deferred_start=true.
+  // It's a no-op if called after a regular EnableTracing(), without setting
+  // deferred_start.
+  virtual void StartTracing() = 0;
+
+  virtual void DisableTracing() = 0;
+
+  // Clones an existing tracing session and attaches to it. The session is
+  // cloned in read-only mode and can only be used to read a snapshot of an
+  // existing tracing session. Will invoke Consumer::OnSessionCloned().
+  // If TracingSessionID == kBugreportSessionId (0xff...ff) the session with the
+  // highest bugreport score is cloned (if any exists).
+  // TODO(primiano): make pure virtual after various 3way patches.
+  virtual void CloneSession(TracingSessionID);
+
+  // Requests all data sources to flush their data immediately and invokes the
+  // passed callback once all of them have acked the flush (in which case
+  // the callback argument |success| will be true) or |timeout_ms| are elapsed
+  // (in which case |success| will be false).
+  // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
+  // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
+  // used.
+  using FlushCallback = std::function<void(bool /*success*/)>;
+  virtual void Flush(uint32_t timeout_ms, FlushCallback callback, FlushFlags);
+
+  // The only caller of this method is arctraceservice's PerfettoClient.
+  // Everything else in the codebase uses the 3-arg Flush() above.
+  // TODO(primiano): remove the overload without FlushFlags once
+  // arctraceservice moves away from this interface. arctraceservice lives in
+  // the internal repo and changes to this interface require multi-side patches.
+  // Inernally this calls Flush(timeout, callback, FlushFlags(0)).
+  virtual void Flush(uint32_t timeout_ms, FlushCallback callback);
+
+  // Tracing data will be delivered invoking Consumer::OnTraceData().
+  virtual void ReadBuffers() = 0;
+
+  virtual void FreeBuffers() = 0;
+
+  // Will call OnDetach().
+  virtual void Detach(const std::string& key) = 0;
+
+  // Will call OnAttach().
+  virtual void Attach(const std::string& key) = 0;
+
+  // Will call OnTraceStats().
+  virtual void GetTraceStats() = 0;
+
+  // Start or stop observing events of selected types. |events_mask| specifies
+  // the types of events to observe in a bitmask of ObservableEvents::Type.
+  // To disable observing, pass 0.
+  // Will call OnObservableEvents() repeatedly whenever an event of an enabled
+  // ObservableEventType occurs.
+  // TODO(eseckler): Extend this to support producers & data sources.
+  virtual void ObserveEvents(uint32_t events_mask) = 0;
+
+  // Used to obtain the list of connected data sources and other info about
+  // the tracing service.
+  using QueryServiceStateCallback =
+      std::function<void(bool success, const TracingServiceState&)>;
+  virtual void QueryServiceState(QueryServiceStateCallback) = 0;
+
+  // Used for feature detection. Makes sense only when the consumer and the
+  // service talk over IPC and can be from different versions.
+  using QueryCapabilitiesCallback =
+      std::function<void(const TracingServiceCapabilities&)>;
+  virtual void QueryCapabilities(QueryCapabilitiesCallback) = 0;
+
+  // If any tracing session with TraceConfig.bugreport_score > 0 is running,
+  // this will pick the highest-score one, stop it and save it into a fixed
+  // path (See kBugreportTracePath).
+  // The callback is invoked when the file has been saved, in case of success,
+  // or whenever an error occurs.
+  // Args:
+  // - success: if true, an eligible trace was found and saved into file.
+  //            If false, either there was no eligible trace running or
+  //            something else failed (See |msg|).
+  // - msg: human readable diagnostic messages to debug failures.
+  using SaveTraceForBugreportCallback =
+      std::function<void(bool /*success*/, const std::string& /*msg*/)>;
+  virtual void SaveTraceForBugreport(SaveTraceForBugreportCallback) = 0;
+};  // class ConsumerEndpoint.
+
+struct PERFETTO_EXPORT_COMPONENT TracingServiceInitOpts {
+  // Function used by tracing service to compress packets. Takes a pointer to
+  // a vector of TracePackets and replaces the packets in the vector with
+  // compressed ones.
+  using CompressorFn = void (*)(std::vector<TracePacket>*);
+  CompressorFn compressor_fn = nullptr;
+};
+
+// The public API of the tracing Service business logic.
+//
+// Exposed to:
+// 1. The transport layer (e.g., src/unix_rpc/unix_service_host.cc),
+//    which forwards commands received from a remote producer or consumer to
+//    the actual service implementation.
+// 2. Tests.
+//
+// Subclassed by:
+//   The service business logic in src/core/tracing_service_impl.cc.
+class PERFETTO_EXPORT_COMPONENT TracingService {
+ public:
+  using ProducerEndpoint = perfetto::ProducerEndpoint;
+  using ConsumerEndpoint = perfetto::ConsumerEndpoint;
+  using InitOpts = TracingServiceInitOpts;
+
+  // Default sizes used by the service implementation and client library.
+  static constexpr size_t kDefaultShmPageSize = 4096ul;
+  static constexpr size_t kDefaultShmSize = 256 * 1024ul;
+
+  enum class ProducerSMBScrapingMode {
+    // Use service's default setting for SMB scraping. Currently, the default
+    // mode is to disable SMB scraping, but this may change in the future.
+    kDefault,
+
+    // Enable scraping of uncommitted chunks in producers' shared memory
+    // buffers.
+    kEnabled,
+
+    // Disable scraping of uncommitted chunks in producers' shared memory
+    // buffers.
+    kDisabled
+  };
+
+  // Implemented in src/core/tracing_service_impl.cc . CompressorFn can be
+  // nullptr, in which case TracingService will not support compression.
+  static std::unique_ptr<TracingService> CreateInstance(
+      std::unique_ptr<SharedMemory::Factory>,
+      base::TaskRunner*,
+      InitOpts init_opts = {});
+
+  virtual ~TracingService();
+
+  // Connects a Producer instance and obtains a ProducerEndpoint, which is
+  // essentially a 1:1 channel between one Producer and the Service.
+  //
+  // The caller has to guarantee that the passed Producer will be alive as long
+  // as the returned ProducerEndpoint is alive. Both the passed Producer and the
+  // returned ProducerEndpoint must live on the same task runner of the service,
+  // specifically:
+  // 1) The Service will call Producer::* methods on the Service's task runner.
+  // 2) The Producer should call ProducerEndpoint::* methods only on the
+  //    service's task runner, except for ProducerEndpoint::CreateTraceWriter(),
+  //    which can be called on any thread. To disconnect just destroy the
+  //    returned ProducerEndpoint object. It is safe to destroy the Producer
+  //    once the Producer::OnDisconnect() has been invoked.
+  //
+  // |uid| is the trusted user id of the producer process, used by the consumers
+  // for validating the origin of trace data. |shared_memory_size_hint_bytes|
+  // and |shared_memory_page_size_hint_bytes| are optional hints on the size of
+  // the shared memory buffer and its pages. The service can ignore the hints
+  // (e.g., if the hints are unreasonably large or other sizes were configured
+  // in a tracing session's config). |in_process| enables the ProducerEndpoint
+  // to manage its own shared memory and enables use of
+  // |ProducerEndpoint::CreateTraceWriter|.
+  //
+  // The producer can optionally provide a non-null |shm|, which the service
+  // will adopt for the connection to the producer, provided it is correctly
+  // sized. In this case, |shared_memory_page_size_hint_bytes| indicates the
+  // page size used in this SMB. The producer can use this mechanism to record
+  // tracing data to an SMB even before the tracing session is started by the
+  // service. This is used in Chrome to implement startup tracing. If the buffer
+  // is incorrectly sized, the service will discard the SMB and allocate a new
+  // one, provided to the producer via ProducerEndpoint::shared_memory() after
+  // OnTracingSetup(). To verify that the service accepted the SMB, the producer
+  // may check via ProducerEndpoint::IsShmemProvidedByProducer(). If the service
+  // accepted the SMB, the producer can then commit any data that is already in
+  // the SMB after the tracing session was started by the service via
+  // Producer::StartDataSource(). The |shm| will also be rejected when
+  // connecting to a service that is too old (pre Android-11).
+  //
+  // Can return null in the unlikely event that service has too many producers
+  // connected.
+  virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      Producer*,
+      const ClientIdentity& client_identity,
+      const std::string& name,
+      size_t shared_memory_size_hint_bytes = 0,
+      bool in_process = false,
+      ProducerSMBScrapingMode smb_scraping_mode =
+          ProducerSMBScrapingMode::kDefault,
+      size_t shared_memory_page_size_hint_bytes = 0,
+      std::unique_ptr<SharedMemory> shm = nullptr,
+      const std::string& sdk_version = {}) = 0;
+
+  // Connects a Consumer instance and obtains a ConsumerEndpoint, which is
+  // essentially a 1:1 channel between one Consumer and the Service.
+  // The caller has to guarantee that the passed Consumer will be alive as long
+  // as the returned ConsumerEndpoint is alive.
+  // To disconnect just destroy the returned ConsumerEndpoint object. It is safe
+  // to destroy the Consumer once the Consumer::OnDisconnect() has been invoked.
+  virtual std::unique_ptr<ConsumerEndpoint> ConnectConsumer(Consumer*,
+                                                            uid_t) = 0;
+
+  // Enable/disable scraping of chunks in the shared memory buffer. If enabled,
+  // the service will copy uncommitted but non-empty chunks from the SMB when
+  // flushing (e.g. to handle unresponsive producers or producers unable to
+  // flush their active chunks), on producer disconnect (e.g. to recover data
+  // from crashed producers), and after disabling a tracing session (e.g. to
+  // gather data from producers that didn't stop their data sources in time).
+  //
+  // This feature is currently used by Chrome.
+  virtual void SetSMBScrapingEnabled(bool enabled) = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
+
+#include <stddef.h>
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+class SharedMemory;
+class TraceWriter;
+
+// Used by the Producer-side of the transport layer to vend TraceWriters
+// from the SharedMemory it receives from the Service-side.
+class PERFETTO_EXPORT_COMPONENT SharedMemoryArbiter {
+ public:
+  using ShmemMode = SharedMemoryABI::ShmemMode;
+
+  virtual ~SharedMemoryArbiter();
+
+  // Creates a new TraceWriter and assigns it a new WriterID. The WriterID is
+  // written in each chunk header owned by a given TraceWriter and is used by
+  // the Service to reconstruct TracePackets written by the same TraceWriter.
+  // Returns null impl of TraceWriter if all WriterID slots are exhausted. The
+  // writer will commit to the provided |target_buffer|. If the arbiter was
+  // created via CreateUnbound() or CreateStartupTraceWriter() is later used,
+  // only BufferExhaustedPolicy::kDrop is supported.
+  virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID target_buffer,
+      BufferExhaustedPolicy buffer_exhausted_policy =
+          BufferExhaustedPolicy::kDefault) = 0;
+
+  // Creates a TraceWriter that will commit to the target buffer with the given
+  // reservation ID (creating a new reservation for this ID if none exists yet).
+  // The buffer reservation should be bound to an actual BufferID via
+  // BindStartupTargetBuffer() once the actual BufferID is known. Calling this
+  // method may transition the arbiter into unbound state (see state diagram in
+  // SharedMemoryArbiterImpl's class comment) and requires that all (past and
+  // future) TraceWriters are created with BufferExhaustedPolicy::kDrop.
+  //
+  // While any unbound buffer reservation exists, all commits will be buffered
+  // until all reservations were bound. Thus, until all reservations are bound,
+  // the data written to the SMB will not be consumed by the service - the SMB
+  // size should be chosen with this in mind. Startup writers always use
+  // BufferExhaustedPolicy::kDrop, as we cannot feasibly stall while not
+  // flushing to the service.
+  //
+  // The |target_buffer_reservation_id| should be greater than 0 but can
+  // otherwise be freely chosen by the producer and is only used to translate
+  // packets into the actual buffer id once
+  // BindStartupTargetBuffer(reservation_id) is called. For example, Chrome uses
+  // startup tracing not only for the first, but also subsequent tracing
+  // sessions (to enable tracing in the browser process before it instructs the
+  // tracing service to start tracing asynchronously, minimizing trace data loss
+  // in the meantime), and increments the reservation ID between sessions.
+  // Similarly, if more than a single target buffer per session is required
+  // (e.g. for two different data sources), different reservation IDs should be
+  // chosen for different target buffers.
+  virtual std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
+      uint16_t target_buffer_reservation_id) = 0;
+
+  // Should only be called on unbound SharedMemoryArbiters. Binds the arbiter to
+  // the provided ProducerEndpoint and TaskRunner. Should be called only once
+  // and on the provided |TaskRunner|. Usually called by the producer (i.e., no
+  // specific data source) once it connects to the service. Both the endpoint
+  // and task runner should remain valid for the remainder of the arbiter's
+  // lifetime.
+  virtual void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
+                                      base::TaskRunner*) = 0;
+
+  // Binds commits from TraceWriters created via CreateStartupTraceWriter() with
+  // the given |target_buffer_reservation_id| to |target_buffer_id|. May only be
+  // called once per |target_buffer_reservation_id|. Should be called on the
+  // arbiter's TaskRunner, and after BindToProducerEndpoint() was called.
+  // Usually, it is called by a specific data source, after it received its
+  // configuration (including the target buffer ID) from the service.
+  virtual void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
+                                       BufferID target_buffer_id) = 0;
+
+  // Treat the reservation as resolved to an invalid buffer. Commits for this
+  // reservation will be flushed to the service ASAP. The service will free
+  // committed chunks but otherwise ignore them. The producer can call this
+  // method, for example, if connection to the tracing service failed or the
+  // session was stopped concurrently before the connection was established.
+  virtual void AbortStartupTracingForReservation(
+      uint16_t target_buffer_reservation_id) = 0;
+
+  // Notifies the service that all data for the given FlushRequestID has been
+  // committed in the shared memory buffer. Should only be called while bound.
+  virtual void NotifyFlushComplete(FlushRequestID) = 0;
+
+  // Sets the duration during which commits are batched. Args:
+  // |batch_commits_duration_ms|: The length of the period, during which commits
+  // by all trace writers are accumulated, before being sent to the service.
+  // When the period ends, all accumulated commits are flushed. On the first
+  // commit after the last flush, another delayed flush is scheduled to run in
+  // |batch_commits_duration_ms|. If an immediate flush occurs (via
+  // FlushPendingCommitDataRequests()) during a batching period, any
+  // accumulated commits up to that point will be sent to the service
+  // immediately. And when the batching period ends, the commits that occurred
+  // after the immediate flush will also be sent to the service.
+  //
+  // If the duration has already been set to a non-zero value before this method
+  // is called, and there is already a scheduled flush with the previously-set
+  // duration, the new duration will take effect after the scheduled flush
+  // occurs.
+  //
+  // If |batch_commits_duration_ms| is non-zero, batched data that hasn't been
+  // sent could be lost at the end of a tracing session. To avoid this,
+  // producers should make sure that FlushPendingCommitDataRequests is called
+  // after the last TraceWriter write and before the service has stopped
+  // listening for commits from the tracing session's data sources (i.e.
+  // data sources should stop asynchronously, see
+  // DataSourceDescriptor.will_notify_on_stop=true).
+  virtual void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) = 0;
+
+  // Called to enable direct producer-side patching of chunks that have not yet
+  // been committed to the service. The return value indicates whether direct
+  // patching was successfully enabled. It will be true if
+  // SharedMemoryArbiter::SetDirectSMBPatchingSupportedByService has been called
+  // and false otherwise.
+  virtual bool EnableDirectSMBPatching() = 0;
+
+  // When the producer and service live in separate processes, this method
+  // should be called if the producer receives an
+  // InitializeConnectionResponse.direct_smb_patching_supported set to true by
+  // the service (see producer_port.proto) .
+  //
+  // In the in-process case, the service will always support direct SMB patching
+  // and this method should always be called.
+  virtual void SetDirectSMBPatchingSupportedByService() = 0;
+
+  // Forces an immediate commit of the completed packets, without waiting for
+  // the next task or for a batching period to end. Should only be called while
+  // bound.
+  virtual void FlushPendingCommitDataRequests(
+      std::function<void()> callback = {}) = 0;
+
+  // Attempts to shut down this arbiter. This function prevents new trace
+  // writers from being created for this this arbiter, but if there are any
+  // existing trace writers, the shutdown cannot proceed and this funtion
+  // returns false. The caller should not delete the arbiter before all of its
+  // associated trace writers have been destroyed and this function returns
+  // true.
+  virtual bool TryShutdown() = 0;
+
+  // Create a bound arbiter instance. Args:
+  // |SharedMemory|: the shared memory buffer to use.
+  // |page_size|: a multiple of 4KB that defines the granularity of tracing
+  // pages. See tradeoff considerations in shared_memory_abi.h.
+  // |ProducerEndpoint|: The service's producer endpoint used e.g. to commit
+  // chunks and register trace writers.
+  // |TaskRunner|: Task runner for perfetto's main thread, which executes the
+  // OnPagesCompleteCallback and IPC calls to the |ProducerEndpoint|.
+  //
+  // Implemented in src/core/shared_memory_arbiter_impl.cc.
+  static std::unique_ptr<SharedMemoryArbiter> CreateInstance(
+      SharedMemory*,
+      size_t page_size,
+      ShmemMode,
+      TracingService::ProducerEndpoint*,
+      base::TaskRunner*);
+
+  // Create an unbound arbiter instance, which should later be bound to a
+  // ProducerEndpoint and TaskRunner by calling BindToProducerEndpoint(). The
+  // returned arbiter will ONLY support trace writers with
+  // BufferExhaustedPolicy::kDrop.
+  //
+  // An unbound SharedMemoryArbiter can be used to write to a producer-created
+  // SharedMemory buffer before the producer connects to the tracing service.
+  // The producer can then pass this SMB to the service when it connects (see
+  // TracingService::ConnectProducer).
+  //
+  // To trace into the SMB before the service starts the tracing session, trace
+  // writers can be obtained via CreateStartupTraceWriter() and later associated
+  // with a target buffer via BindStartupTargetBuffer(), once the target buffer
+  // is known.
+  //
+  // Implemented in src/core/shared_memory_arbiter_impl.cc. See CreateInstance()
+  // for comments about the arguments.
+  static std::unique_ptr<SharedMemoryArbiter>
+  CreateUnboundInstance(SharedMemory*, size_t page_size, ShmemMode mode);
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
+#define SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
+
+#include <stdint.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
+
+namespace perfetto {
+
+class PatchList;
+class Patch;
+class TraceWriter;
+class TraceWriterImpl;
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+// This class handles the shared memory buffer on the producer side. It is used
+// to obtain thread-local chunks and to partition pages from several threads.
+// There is one arbiter instance per Producer.
+// This class is thread-safe and uses locks to do so. Data sources are supposed
+// to interact with this sporadically, only when they run out of space on their
+// current thread-local chunk.
+//
+// The arbiter can become "unbound" as a consequence of:
+//  (a) being created without an endpoint
+//  (b) CreateStartupTraceWriter calls after creation (whether created with or
+//      without endpoint).
+//
+// Entering the unbound state is only supported if all trace writers are created
+// in kDrop mode. In the unbound state, the arbiter buffers commit messages
+// until all trace writers are bound to a target buffer.
+//
+// The following state transitions are possible:
+//
+//   CreateInstance()
+//    |
+//    |  CreateUnboundInstance()
+//    |    |
+//    |    |
+//    |    V
+//    |  [ !fully_bound_, !endpoint_, 0 unbound buffer reservations ]
+//    |      |     |
+//    |      |     | CreateStartupTraceWriter(buf)
+//    |      |     |  buffer reservations += buf
+//    |      |     |
+//    |      |     |             ----
+//    |      |     |            |    | CreateStartupTraceWriter(buf)
+//    |      |     |            |    |  buffer reservations += buf
+//    |      |     V            |    V
+//    |      |   [ !fully_bound_, !endpoint_, >=1 unbound buffer reservations ]
+//    |      |                                                |
+//    |      |                       BindToProducerEndpoint() |
+//    |      |                                                |
+//    |      | BindToProducerEndpoint()                       |
+//    |      |                                                V
+//    |      |   [ !fully_bound_, endpoint_, >=1 unbound buffer reservations ]
+//    |      |   A    |    A                               |     A
+//    |      |   |    |    |                               |     |
+//    |      |   |     ----                                |     |
+//    |      |   |    CreateStartupTraceWriter(buf)        |     |
+//    |      |   |     buffer reservations += buf          |     |
+//    |      |   |                                         |     |
+//    |      |   | CreateStartupTraceWriter(buf)           |     |
+//    |      |   |  where buf is not yet bound             |     |
+//    |      |   |  buffer reservations += buf             |     | (yes)
+//    |      |   |                                         |     |
+//    |      |   |        BindStartupTargetBuffer(buf, id) |-----
+//    |      |   |           buffer reservations -= buf    | reservations > 0?
+//    |      |   |                                         |
+//    |      |   |                                         | (no)
+//    |      V   |                                         V
+//     --> [ fully_bound_, endpoint_, 0 unbound buffer reservations ]
+//              |    A
+//              |    | CreateStartupTraceWriter(buf)
+//              |    |  where buf is already bound
+//               ----
+class SharedMemoryArbiterImpl : public SharedMemoryArbiter {
+ public:
+  // See SharedMemoryArbiter::CreateInstance(). |start|, |size| define the
+  // boundaries of the shared memory buffer. ProducerEndpoint and TaskRunner may
+  // be |nullptr| if created unbound, see
+  // SharedMemoryArbiter::CreateUnboundInstance().
+
+  // SharedMemoryArbiterImpl(void* start,
+  //                         size_t size,
+  //                         size_t page_size,
+  //                         TracingService::ProducerEndpoint*
+  //                         producer_endpoint, base::TaskRunner* task_runner) :
+  //   SharedMemoryArbiterImpl(start, size, page_size, false, producer_endpoint,
+  //   task_runner) {
+  // }
+
+  SharedMemoryArbiterImpl(void* start,
+                          size_t size,
+                          ShmemMode mode,
+                          size_t page_size,
+                          TracingService::ProducerEndpoint*,
+                          base::TaskRunner*);
+
+  // Returns a new Chunk to write tracing data. Depending on the provided
+  // BufferExhaustedPolicy, this may return an invalid chunk if no valid free
+  // chunk could be found in the SMB.
+  SharedMemoryABI::Chunk GetNewChunk(const SharedMemoryABI::ChunkHeader&,
+                                     BufferExhaustedPolicy,
+                                     size_t size_hint = 0);
+
+  // Puts back a Chunk that has been completed and sends a request to the
+  // service to move it to the central tracing buffer. |target_buffer| is the
+  // absolute trace buffer ID where the service should move the chunk onto (the
+  // producer is just to copy back the same number received in the
+  // DataSourceConfig upon the StartDataSource() reques).
+  // PatchList is a pointer to the list of patches for previous chunks. The
+  // first patched entries will be removed from the patched list and sent over
+  // to the service in the same CommitData() IPC request.
+  void ReturnCompletedChunk(SharedMemoryABI::Chunk,
+                            MaybeUnboundBufferID target_buffer,
+                            PatchList*);
+
+  // Send a request to the service to apply completed patches from |patch_list|.
+  // |writer_id| is the ID of the TraceWriter that calls this method,
+  // |target_buffer| is the global trace buffer ID of its target buffer.
+  void SendPatches(WriterID writer_id,
+                   MaybeUnboundBufferID target_buffer,
+                   PatchList* patch_list);
+
+  SharedMemoryABI* shmem_abi_for_testing() { return &shmem_abi_; }
+
+  static void set_default_layout_for_testing(SharedMemoryABI::PageLayout l) {
+    default_page_layout = l;
+  }
+
+  static SharedMemoryABI::PageLayout default_page_layout_for_testing() {
+    return default_page_layout;
+  }
+
+  // SharedMemoryArbiter implementation.
+  // See include/perfetto/tracing/core/shared_memory_arbiter.h for comments.
+  std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID target_buffer,
+      BufferExhaustedPolicy = BufferExhaustedPolicy::kDefault) override;
+  std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
+      uint16_t target_buffer_reservation_id) override;
+  void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
+                              base::TaskRunner*) override;
+  void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
+                               BufferID target_buffer_id) override;
+  void AbortStartupTracingForReservation(
+      uint16_t target_buffer_reservation_id) override;
+  void NotifyFlushComplete(FlushRequestID) override;
+
+  void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) override;
+
+  bool EnableDirectSMBPatching() override;
+
+  void SetDirectSMBPatchingSupportedByService() override;
+
+  void FlushPendingCommitDataRequests(
+      std::function<void()> callback = {}) override;
+  bool TryShutdown() override;
+
+  base::TaskRunner* task_runner() const { return task_runner_; }
+  size_t page_size() const { return shmem_abi_.page_size(); }
+  size_t num_pages() const { return shmem_abi_.num_pages(); }
+
+  base::WeakPtr<SharedMemoryArbiterImpl> GetWeakPtr() const {
+    return weak_ptr_factory_.GetWeakPtr();
+  }
+
+ private:
+  friend class TraceWriterImpl;
+  friend class StartupTraceWriterTest;
+  friend class SharedMemoryArbiterImplTest;
+
+  struct TargetBufferReservation {
+    bool resolved = false;
+    BufferID target_buffer = kInvalidBufferId;
+  };
+
+  // Placeholder for the actual target buffer ID of a startup target buffer
+  // reservation ID in |target_buffer_reservations_|.
+  static constexpr BufferID kInvalidBufferId = 0;
+
+  static SharedMemoryABI::PageLayout default_page_layout;
+
+  SharedMemoryArbiterImpl(const SharedMemoryArbiterImpl&) = delete;
+  SharedMemoryArbiterImpl& operator=(const SharedMemoryArbiterImpl&) = delete;
+
+  void UpdateCommitDataRequest(SharedMemoryABI::Chunk chunk,
+                               WriterID writer_id,
+                               MaybeUnboundBufferID target_buffer,
+                               PatchList* patch_list);
+
+  // Search the chunks that are being batched in |commit_data_req_| for a chunk
+  // that needs patching and that matches the provided |writer_id| and
+  // |patch.chunk_id|. If found, apply |patch| to that chunk, and if
+  // |chunk_needs_more_patching| is true, clear the needs patching flag of the
+  // chunk and mark it as complete - to allow the service to read it (and other
+  // chunks after it) during scraping. Returns true if the patch was applied,
+  // false otherwise.
+  //
+  // Note: the caller must be holding |lock_| for the duration of the call.
+  bool TryDirectPatchLocked(WriterID writer_id,
+                            const Patch& patch,
+                            bool chunk_needs_more_patching);
+  std::unique_ptr<TraceWriter> CreateTraceWriterInternal(
+      MaybeUnboundBufferID target_buffer,
+      BufferExhaustedPolicy);
+
+  // Called by the TraceWriter destructor.
+  void ReleaseWriterID(WriterID);
+
+  void BindStartupTargetBufferImpl(std::unique_lock<std::mutex> scoped_lock,
+                                   uint16_t target_buffer_reservation_id,
+                                   BufferID target_buffer_id);
+
+  // If any flush callbacks were queued up while the arbiter or any target
+  // buffer reservation was unbound, this wraps the pending callbacks into a new
+  // std::function and returns it. Otherwise returns an invalid std::function.
+  std::function<void()> TakePendingFlushCallbacksLocked();
+
+  // Replace occurrences of target buffer reservation IDs in |commit_data_req_|
+  // with their respective actual BufferIDs if they were already bound. Returns
+  // true iff all occurrences were replaced.
+  bool ReplaceCommitPlaceholderBufferIdsLocked();
+
+  // Update and return |fully_bound_| based on the arbiter's |pending_writers_|
+  // state.
+  bool UpdateFullyBoundLocked();
+
+  // Only accessed on |task_runner_| after the producer endpoint was bound.
+  TracingService::ProducerEndpoint* producer_endpoint_ = nullptr;
+
+  // Set to true when this instance runs in a emulation mode for a producer
+  // endpoint that doesn't support shared memory (e.g. vsock).
+  const bool use_shmem_emulation_ = false;
+
+  // --- Begin lock-protected members ---
+
+  std::mutex lock_;
+
+  base::TaskRunner* task_runner_ = nullptr;
+  SharedMemoryABI shmem_abi_;
+  size_t page_idx_ = 0;
+  std::unique_ptr<CommitDataRequest> commit_data_req_;
+  size_t bytes_pending_commit_ = 0;  // SUM(chunk.size() : commit_data_req_).
+  IdAllocator<WriterID> active_writer_ids_;
+  bool did_shutdown_ = false;
+
+  // Whether the arbiter itself and all startup target buffer reservations are
+  // bound. Note that this can become false again later if a new target buffer
+  // reservation is created by calling CreateStartupTraceWriter() with a new
+  // reservation id.
+  bool fully_bound_;
+
+  // Whether the arbiter was always bound. If false, the arbiter was unbound at
+  // one point in time.
+  bool was_always_bound_;
+
+  // Whether all created trace writers were created with kDrop policy.
+  bool all_writers_have_drop_policy_ = true;
+
+  // IDs of writers and their assigned target buffers that should be registered
+  // with the service after the arbiter and/or their startup target buffer is
+  // bound.
+  std::map<WriterID, MaybeUnboundBufferID> pending_writers_;
+
+  // Callbacks for flush requests issued while the arbiter or a target buffer
+  // reservation was unbound.
+  std::vector<std::function<void()>> pending_flush_callbacks_;
+
+  // See SharedMemoryArbiter::SetBatchCommitsDuration.
+  uint32_t batch_commits_duration_ms_ = 0;
+
+  // See SharedMemoryArbiter::EnableDirectSMBPatching.
+  bool direct_patching_enabled_ = false;
+
+  // See SharedMemoryArbiter::SetDirectSMBPatchingSupportedByService.
+  bool direct_patching_supported_by_service_ = false;
+
+  // Indicates whether we have already scheduled a delayed flush for the
+  // purposes of batching. Set to true at the beginning of a batching period and
+  // cleared at the end of the period. Immediate flushes that happen during a
+  // batching period will empty the |commit_data_req| (triggering an immediate
+  // IPC to the service), but will not clear this flag and the
+  // previously-scheduled delayed flush will still occur at the end of the
+  // batching period.
+  bool delayed_flush_scheduled_ = false;
+
+  // Stores target buffer reservations for writers created via
+  // CreateStartupTraceWriter(). A bound reservation sets
+  // TargetBufferReservation::resolved to true and is associated with the actual
+  // BufferID supplied in BindStartupTargetBuffer().
+  //
+  // TODO(eseckler): Clean up entries from this map. This would probably require
+  // a method in SharedMemoryArbiter that allows a producer to invalidate a
+  // reservation ID.
+  std::map<MaybeUnboundBufferID, TargetBufferReservation>
+      target_buffer_reservations_;
+
+  // --- End lock-protected members ---
+
+  // Keep at the end.
+  base::WeakPtrFactory<SharedMemoryArbiterImpl> weak_ptr_factory_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/commit_data_request.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
+// gen_amalgamated begin header: src/tracing/core/trace_writer_impl.h
+// gen_amalgamated begin header: src/tracing/core/patch_list.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef SRC_TRACING_CORE_PATCH_LIST_H_
+#define SRC_TRACING_CORE_PATCH_LIST_H_
+
+#include <array>
+#include <forward_list>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+
+namespace perfetto {
+
+// Used to handle the backfilling of the headers (the |size_field|) of nested
+// messages when a proto is fragmented over several chunks. These patches are
+// sent out-of-band to the tracing service, after having returned the initial
+// chunks of the fragment.
+// TODO(crbug.com/904477): Re-disable the move constructors when all usses of
+// this class have been fixed.
+class Patch {
+ public:
+  using PatchContent = std::array<uint8_t, SharedMemoryABI::kPacketHeaderSize>;
+  Patch(ChunkID c, uint16_t o) : chunk_id(c), offset(o) {}
+  Patch(const Patch&) = default;  // For tests.
+
+  const ChunkID chunk_id;
+  const uint16_t offset;
+  PatchContent size_field{};
+
+  // |size_field| contains a varint. Any varint must start with != 0. Even in
+  // the case we want to encode a size == 0, protozero will write a redundant
+  // varint for that, that is [0x80, 0x80, 0x80, 0x00]. So the first byte is 0
+  // iff we never wrote any varint into that.
+  bool is_patched() const { return size_field[0] != 0; }
+
+  // For tests.
+  bool operator==(const Patch& o) const {
+    return chunk_id == o.chunk_id && offset == o.offset &&
+           size_field == o.size_field;
+  }
+
+ private:
+  Patch& operator=(const Patch&) = delete;
+};
+
+// Note: the protozero::Message(s) will take pointers to the |size_field| of
+// these entries. This container must guarantee that the Patch objects are never
+// moved around (i.e. cannot be a vector because of reallocations can change
+// addresses of pre-existing entries).
+class PatchList {
+ public:
+  using ListType = std::forward_list<Patch>;
+  using value_type = ListType::value_type;          // For gtest.
+  using const_iterator = ListType::const_iterator;  // For gtest.
+
+  PatchList() : last_(list_.before_begin()) {}
+
+  Patch* emplace_back(ChunkID chunk_id, uint16_t offset) {
+    last_ = list_.emplace_after(last_, chunk_id, offset);
+    return &*last_;
+  }
+
+  void pop_front() {
+    PERFETTO_DCHECK(!list_.empty());
+    list_.pop_front();
+    if (empty())
+      last_ = list_.before_begin();
+  }
+
+  const Patch& front() const {
+    PERFETTO_DCHECK(!list_.empty());
+    return list_.front();
+  }
+
+  const Patch& back() const {
+    PERFETTO_DCHECK(!list_.empty());
+    return *last_;
+  }
+
+  ListType::const_iterator begin() const { return list_.begin(); }
+  ListType::const_iterator end() const { return list_.end(); }
+  bool empty() const { return list_.empty(); }
+
+ private:
+  ListType list_;
+  ListType::iterator last_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_PATCH_LIST_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
+#define SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "src/tracing/core/patch_list.h"
+
+namespace perfetto {
+
+class SharedMemoryArbiterImpl;
+
+// See //include/perfetto/ext/tracing/core/trace_writer.h for docs.
+//
+// Locking will happen only when a chunk is exhausted and a new one is
+// acquired from the arbiter.
+//
+// TODO: TraceWriter needs to keep the shared memory buffer alive (refcount?).
+// Otherwise if the shared memory buffer goes away (e.g. the Service crashes)
+// the TraceWriter will keep writing into unmapped memory.
+//
+class TraceWriterImpl : public TraceWriter,
+                        public protozero::ScatteredStreamWriter::Delegate {
+ public:
+  // TracePacketHandle is defined in trace_writer.h
+  TraceWriterImpl(SharedMemoryArbiterImpl*,
+                  WriterID,
+                  MaybeUnboundBufferID buffer_id,
+                  BufferExhaustedPolicy);
+  ~TraceWriterImpl() override;
+
+  // TraceWriter implementation. See documentation in trace_writer.h.
+  TracePacketHandle NewTracePacket() override;
+  void FinishTracePacket() override;
+  // Commits the data pending for the current chunk into the shared memory
+  // buffer and sends a CommitDataRequest() to the service.
+  // TODO(primiano): right now the |callback| will be called on the IPC thread.
+  // This is fine in the current single-thread scenario, but long-term
+  // trace_writer_impl.cc should be smarter and post it on the right thread.
+  void Flush(std::function<void()> callback = {}) override;
+  WriterID writer_id() const override;
+  uint64_t written() const override {
+    return protobuf_stream_writer_.written();
+  }
+
+  void ResetChunkForTesting() {
+    cur_chunk_ = SharedMemoryABI::Chunk();
+    cur_chunk_packet_count_inflated_ = false;
+  }
+  bool drop_packets_for_testing() const { return drop_packets_; }
+
+ private:
+  TraceWriterImpl(const TraceWriterImpl&) = delete;
+  TraceWriterImpl& operator=(const TraceWriterImpl&) = delete;
+
+  // ScatteredStreamWriter::Delegate implementation.
+  protozero::ContiguousMemoryRange GetNewBuffer() override;
+  uint8_t* AnnotatePatch(uint8_t*) override;
+
+  // Writes the size of the current fragment into the chunk.
+  //
+  // The size of nested messages inside TracePacket is written by
+  // by the user, but the size of the TracePacket fragments is written by
+  // TraceWriterImpl.
+  void FinalizeFragmentIfRequired();
+
+  // Returns |cur_chunk_| (for which is_valid() must be true) to the
+  // |shmem_arbiter|.
+  void ReturnCompletedChunk();
+
+  // The per-producer arbiter that coordinates access to the shared memory
+  // buffer from several threads.
+  SharedMemoryArbiterImpl* const shmem_arbiter_;
+
+  // ID of the current writer.
+  const WriterID id_;
+
+  // This is copied into the commit request by SharedMemoryArbiter. See comments
+  // in data_source_config.proto for |target_buffer|. If this is a reservation
+  // for a buffer ID in case of a startup trace writer, SharedMemoryArbiterImpl
+  // will also translate the reservation ID to the actual buffer ID.
+  const MaybeUnboundBufferID target_buffer_;
+
+  // Whether GetNewChunk() should stall or return an invalid chunk if the SMB is
+  // exhausted.
+  const BufferExhaustedPolicy buffer_exhausted_policy_;
+
+  // Monotonic (% wrapping) sequence id of the chunk. Together with the WriterID
+  // this allows the Service to reconstruct the linear sequence of packets.
+  ChunkID next_chunk_id_ = 0;
+
+  // The chunk we are holding onto (if any).
+  SharedMemoryABI::Chunk cur_chunk_;
+
+  // Passed to protozero message to write directly into |cur_chunk_|. It
+  // keeps track of the write pointer. It calls us back (GetNewBuffer()) when
+  // |cur_chunk_| is filled.
+  protozero::ScatteredStreamWriter protobuf_stream_writer_;
+
+  // The packet returned via NewTracePacket(). Its owned by this class,
+  // TracePacketHandle has just a pointer to it.
+  //
+  // The caller of NewTracePacket can use TakeStreamWriter() and use the stream
+  // writer directly: in that case:
+  // * cur_packet_->size() is not up to date. Only the stream writer has the
+  //   correct information.
+  // * cur_packet_->nested_message() is always nullptr.
+  // * cur_packet_->size_field() is still used to track the start of the current
+  //   fragment.
+  std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
+      cur_packet_;
+
+  // The start address of |cur_packet_| within |cur_chunk_|. Used to figure out
+  // fragments sizes when a TracePacket write is interrupted by GetNewBuffer().
+  uint8_t* cur_fragment_start_ = nullptr;
+
+  // true if we received a call to GetNewBuffer() after NewTracePacket(),
+  // false if GetNewBuffer() happened during NewTracePacket() prologue, while
+  // starting the TracePacket header.
+  bool fragmenting_packet_ = false;
+
+  // Set to |true| when the current chunk contains the maximum number of packets
+  // a chunk can contain. When this is |true|, the next packet requires starting
+  // a new chunk.
+  bool reached_max_packets_per_chunk_ = false;
+
+  // If we fail to acquire a new chunk when the arbiter operates in
+  // SharedMemory::BufferExhaustedPolicy::kDrop mode, the trace writer enters a
+  // mode in which data is written to a local garbage chunk and dropped.
+  bool drop_packets_ = false;
+
+  // Whether the trace writer should try to acquire a new chunk from the SMB
+  // when the next TracePacket is started because it filled the garbage chunk at
+  // least once since the last attempt.
+  bool retry_new_chunk_after_packet_ = false;
+
+  // Set to true if `cur_chunk_` has a packet counter that's inflated by one.
+  // The count may be inflated to convince the tracing service scraping logic
+  // that the last packet has been completed. When this is true, cur_chunk_
+  // should have at least `kExtraRoomForInflatedPacket` bytes free.
+  bool cur_chunk_packet_count_inflated_ = false;
+
+  // Points to the size field of the still open fragment we're writing to the
+  // current chunk. If the chunk was already returned, this is reset to
+  // |nullptr|. If the fragment is finalized, this is reset to |nullptr|.
+  //
+  // Note: for nested messages the field is tracked somewhere else
+  // (protozero::Message::size_field_ or PerfettoPbMsg::size_field). For the
+  // root message, protozero::Message::size_field_ is nullptr and this is used
+  // instead. This is because at the root level we deal with fragments, not
+  // logical messages.
+  uint8_t* cur_fragment_size_field_ = nullptr;
+
+  // When a packet is fragmented across different chunks, the |size_field| of
+  // the outstanding nested protobuf messages is redirected onto Patch entries
+  // in this list at the time the Chunk is returned (because at that point we
+  // have to release the ownership of the current Chunk). This list will be
+  // later sent out-of-band to the tracing service, who will patch the required
+  // chunks, if they are still around.
+  PatchList patch_list_;
+
+  // PID of the process that created the trace writer. Used for a DCHECK that
+  // aims to detect unsupported process forks while tracing.
+  const base::PlatformProcessId process_id_;
+
+  // True for the first packet on sequence. See the comment for
+  // TracePacket.first_packet_on_sequence for more details.
+  bool first_packet_on_sequence_ = true;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
+
+#include <algorithm>
+#include <limits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
+// gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"
+
+namespace perfetto {
+
+using Chunk = SharedMemoryABI::Chunk;
+
+namespace {
+static_assert(sizeof(BufferID) == sizeof(uint16_t),
+              "The MaybeUnboundBufferID logic requires BufferID not to grow "
+              "above uint16_t.");
+
+MaybeUnboundBufferID MakeTargetBufferIdForReservation(uint16_t reservation_id) {
+  // Reservation IDs are stored in the upper bits.
+  PERFETTO_CHECK(reservation_id > 0);
+  return static_cast<MaybeUnboundBufferID>(reservation_id) << 16;
+}
+
+bool IsReservationTargetBufferId(MaybeUnboundBufferID buffer_id) {
+  return (buffer_id >> 16) > 0;
+}
+}  // namespace
+
+// static
+SharedMemoryABI::PageLayout SharedMemoryArbiterImpl::default_page_layout =
+    SharedMemoryABI::PageLayout::kPageDiv1;
+
+// static
+std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateInstance(
+    SharedMemory* shared_memory,
+    size_t page_size,
+    ShmemMode mode,
+    TracingService::ProducerEndpoint* producer_endpoint,
+    base::TaskRunner* task_runner) {
+  return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
+      shared_memory->start(), shared_memory->size(), mode, page_size,
+      producer_endpoint, task_runner));
+}
+
+// static
+std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateUnboundInstance(
+    SharedMemory* shared_memory,
+    size_t page_size,
+    ShmemMode mode) {
+  return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
+      shared_memory->start(), shared_memory->size(), mode, page_size,
+      /*producer_endpoint=*/nullptr, /*task_runner=*/nullptr));
+}
+
+SharedMemoryArbiterImpl::SharedMemoryArbiterImpl(
+    void* start,
+    size_t size,
+    ShmemMode mode,
+    size_t page_size,
+    TracingService::ProducerEndpoint* producer_endpoint,
+    base::TaskRunner* task_runner)
+    : producer_endpoint_(producer_endpoint),
+      use_shmem_emulation_(mode == ShmemMode::kShmemEmulation),
+      task_runner_(task_runner),
+      shmem_abi_(reinterpret_cast<uint8_t*>(start), size, page_size, mode),
+      active_writer_ids_(kMaxWriterID),
+      fully_bound_(task_runner && producer_endpoint),
+      was_always_bound_(fully_bound_),
+      weak_ptr_factory_(this) {}
+
+Chunk SharedMemoryArbiterImpl::GetNewChunk(
+    const SharedMemoryABI::ChunkHeader& header,
+    BufferExhaustedPolicy buffer_exhausted_policy,
+    size_t size_hint) {
+  PERFETTO_DCHECK(size_hint == 0);  // Not implemented yet.
+
+  int stall_count = 0;
+  unsigned stall_interval_us = 0;
+  bool task_runner_runs_on_current_thread = false;
+  static const unsigned kMaxStallIntervalUs = 100000;
+  static const int kLogAfterNStalls = 3;
+  static const int kFlushCommitsAfterEveryNStalls = 2;
+  static const int kAssertAtNStalls = 200;
+
+  for (;;) {
+    // TODO(primiano): Probably this lock is not really required and this code
+    // could be rewritten leveraging only the Try* atomic operations in
+    // SharedMemoryABI. But let's not be too adventurous for the moment.
+    {
+      std::unique_lock<std::mutex> scoped_lock(lock_);
+
+      // If ever unbound, we do not support stalling. In theory, we could
+      // support stalling for TraceWriters created after the arbiter and startup
+      // buffer reservations were bound, but to avoid raciness between the
+      // creation of startup writers and binding, we categorically forbid kStall
+      // mode.
+      PERFETTO_DCHECK(was_always_bound_ ||
+                      buffer_exhausted_policy == BufferExhaustedPolicy::kDrop);
+
+      task_runner_runs_on_current_thread =
+          task_runner_ && task_runner_->RunsTasksOnCurrentThread();
+
+      // If more than half of the SMB.size() is filled with completed chunks for
+      // which we haven't notified the service yet (i.e. they are still enqueued
+      // in |commit_data_req_|), force a synchronous CommitDataRequest() even if
+      // we acquire a chunk, to reduce the likeliness of stalling the writer.
+      //
+      // We can only do this if we're writing on the same thread that we access
+      // the producer endpoint on, since we cannot notify the producer endpoint
+      // to commit synchronously on a different thread. Attempting to flush
+      // synchronously on another thread will lead to subtle bugs caused by
+      // out-of-order commit requests (crbug.com/919187#c28).
+      bool should_commit_synchronously =
+          task_runner_runs_on_current_thread &&
+          buffer_exhausted_policy == BufferExhaustedPolicy::kStall &&
+          commit_data_req_ && bytes_pending_commit_ >= shmem_abi_.size() / 2;
+
+      const size_t initial_page_idx = page_idx_;
+      for (size_t i = 0; i < shmem_abi_.num_pages(); i++) {
+        page_idx_ = (initial_page_idx + i) % shmem_abi_.num_pages();
+        bool is_new_page = false;
+
+        // TODO(primiano): make the page layout dynamic.
+        auto layout = SharedMemoryArbiterImpl::default_page_layout;
+
+        if (shmem_abi_.is_page_free(page_idx_)) {
+          // TODO(primiano): Use the |size_hint| here to decide the layout.
+          is_new_page = shmem_abi_.TryPartitionPage(page_idx_, layout);
+        }
+        uint32_t free_chunks;
+        if (is_new_page) {
+          free_chunks = (1 << SharedMemoryABI::kNumChunksForLayout[layout]) - 1;
+        } else {
+          free_chunks = shmem_abi_.GetFreeChunks(page_idx_);
+        }
+
+        for (uint32_t chunk_idx = 0; free_chunks;
+             chunk_idx++, free_chunks >>= 1) {
+          if (!(free_chunks & 1))
+            continue;
+          // We found a free chunk.
+          Chunk chunk = shmem_abi_.TryAcquireChunkForWriting(
+              page_idx_, chunk_idx, &header);
+          if (!chunk.is_valid())
+            continue;
+          if (stall_count > kLogAfterNStalls) {
+            PERFETTO_LOG("Recovered from stall after %d iterations",
+                         stall_count);
+          }
+
+          if (should_commit_synchronously) {
+            // We can't flush while holding the lock.
+            scoped_lock.unlock();
+            FlushPendingCommitDataRequests();
+            return chunk;
+          } else {
+            return chunk;
+          }
+        }
+      }
+    }  // scoped_lock
+
+    if (buffer_exhausted_policy == BufferExhaustedPolicy::kDrop) {
+      PERFETTO_DLOG("Shared memory buffer exhausted, returning invalid Chunk!");
+      return Chunk();
+    }
+
+    // Stalling is not supported if we were ever unbound (see earlier comment).
+    PERFETTO_CHECK(was_always_bound_);
+
+    // All chunks are taken (either kBeingWritten by us or kBeingRead by the
+    // Service).
+    if (stall_count++ == kLogAfterNStalls) {
+      PERFETTO_LOG("Shared memory buffer overrun! Stalling");
+    }
+
+    if (stall_count == kAssertAtNStalls) {
+      PERFETTO_FATAL(
+          "Shared memory buffer max stall count exceeded; possible deadlock");
+    }
+
+    // If the IPC thread itself is stalled because the current process has
+    // filled up the SMB, we need to make sure that the service can process and
+    // purge the chunks written by our process, by flushing any pending commit
+    // requests. Because other threads in our process can continue to
+    // concurrently grab, fill and commit any chunks purged by the service, it
+    // is possible that the SMB remains full and the IPC thread remains stalled,
+    // needing to flush the concurrently queued up commits again. This is
+    // particularly likely with in-process perfetto service where the IPC thread
+    // is the service thread. To avoid remaining stalled forever in such a
+    // situation, we attempt to flush periodically after every N stalls.
+    if (stall_count % kFlushCommitsAfterEveryNStalls == 0 &&
+        task_runner_runs_on_current_thread) {
+      // TODO(primiano): sending the IPC synchronously is a temporary workaround
+      // until the backpressure logic in probes_producer is sorted out. Until
+      // then the risk is that we stall the message loop waiting for the tracing
+      // service to consume the shared memory buffer (SMB) and, for this reason,
+      // never run the task that tells the service to purge the SMB. This must
+      // happen iff we are on the IPC thread, not doing this will cause
+      // deadlocks, doing this on the wrong thread causes out-of-order data
+      // commits (crbug.com/919187#c28).
+      FlushPendingCommitDataRequests();
+    } else {
+      base::SleepMicroseconds(stall_interval_us);
+      stall_interval_us =
+          std::min(kMaxStallIntervalUs, (stall_interval_us + 1) * 8);
+    }
+  }
+}
+
+void SharedMemoryArbiterImpl::ReturnCompletedChunk(
+    Chunk chunk,
+    MaybeUnboundBufferID target_buffer,
+    PatchList* patch_list) {
+  PERFETTO_DCHECK(chunk.is_valid());
+  const WriterID writer_id = chunk.writer_id();
+  UpdateCommitDataRequest(std::move(chunk), writer_id, target_buffer,
+                          patch_list);
+}
+
+void SharedMemoryArbiterImpl::SendPatches(WriterID writer_id,
+                                          MaybeUnboundBufferID target_buffer,
+                                          PatchList* patch_list) {
+  PERFETTO_DCHECK(!patch_list->empty() && patch_list->front().is_patched());
+  UpdateCommitDataRequest(Chunk(), writer_id, target_buffer, patch_list);
+}
+
+void SharedMemoryArbiterImpl::UpdateCommitDataRequest(
+    Chunk chunk,
+    WriterID writer_id,
+    MaybeUnboundBufferID target_buffer,
+    PatchList* patch_list) {
+  // Note: chunk will be invalid if the call came from SendPatches().
+  base::TaskRunner* task_runner_to_post_delayed_callback_on = nullptr;
+  // The delay with which the flush will be posted.
+  uint32_t flush_delay_ms = 0;
+  base::WeakPtr<SharedMemoryArbiterImpl> weak_this;
+  {
+    std::lock_guard<std::mutex> scoped_lock(lock_);
+
+    if (!commit_data_req_) {
+      commit_data_req_.reset(new CommitDataRequest());
+
+      // Flushing the commit is only supported while we're |fully_bound_|. If we
+      // aren't, we'll flush when |fully_bound_| is updated.
+      if (fully_bound_ && !delayed_flush_scheduled_) {
+        weak_this = weak_ptr_factory_.GetWeakPtr();
+        task_runner_to_post_delayed_callback_on = task_runner_;
+        flush_delay_ms = batch_commits_duration_ms_;
+        delayed_flush_scheduled_ = true;
+      }
+    }
+
+    CommitDataRequest::ChunksToMove* ctm = nullptr;  // Set if chunk is valid.
+    // If a valid chunk is specified, return it and attach it to the request.
+    if (chunk.is_valid()) {
+      PERFETTO_DCHECK(chunk.writer_id() == writer_id);
+      uint8_t chunk_idx = chunk.chunk_idx();
+      bytes_pending_commit_ += chunk.size();
+      size_t page_idx;
+
+      ctm = commit_data_req_->add_chunks_to_move();
+      // If the chunk needs patching, it should not be marked as complete yet,
+      // because this would indicate to the service that the producer will not
+      // be writing to it anymore, while the producer might still apply patches
+      // to the chunk later on. In particular, when re-reading (e.g. because of
+      // periodic scraping) a completed chunk, the service expects the flags of
+      // that chunk not to be removed between reads. So, let's say the producer
+      // marked the chunk as complete here and the service then read it for the
+      // first time. If the producer then fully patched the chunk, thus removing
+      // the kChunkNeedsPatching flag, and the service re-read the chunk after
+      // the patching, the service would be thrown off by the removed flag.
+      if (direct_patching_enabled_ &&
+          (chunk.GetPacketCountAndFlags().second &
+           SharedMemoryABI::ChunkHeader::kChunkNeedsPatching)) {
+        page_idx = shmem_abi_.GetPageAndChunkIndex(std::move(chunk)).first;
+      } else {
+        // If the chunk doesn't need patching, we can mark it as complete
+        // immediately. This allows the service to read it in full while
+        // scraping, which would not be the case if the chunk was left in a
+        // kChunkBeingWritten state.
+        page_idx = shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
+      }
+
+      // DO NOT access |chunk| after this point, it has been std::move()-d
+      // above.
+      ctm->set_page(static_cast<uint32_t>(page_idx));
+      ctm->set_chunk(chunk_idx);
+      ctm->set_target_buffer(target_buffer);
+    }
+
+    // Process the completed patches for previous chunks from the |patch_list|.
+    CommitDataRequest::ChunkToPatch* last_patch_req = nullptr;
+    while (!patch_list->empty() && patch_list->front().is_patched()) {
+      Patch curr_patch = patch_list->front();
+      patch_list->pop_front();
+      // Patches for the same chunk are contiguous in the |patch_list|. So, to
+      // determine if there are any other patches that apply to the chunk that
+      // is being patched, check if the next patch in the |patch_list| applies
+      // to the same chunk.
+      bool chunk_needs_more_patching =
+          !patch_list->empty() &&
+          patch_list->front().chunk_id == curr_patch.chunk_id;
+
+      if (direct_patching_enabled_ &&
+          TryDirectPatchLocked(writer_id, curr_patch,
+                               chunk_needs_more_patching)) {
+        continue;
+      }
+
+      // The chunk that this patch applies to has already been released to the
+      // service, so it cannot be patches here. Add the patch to the commit data
+      // request, so that it can be sent to the service and applied there.
+      if (!last_patch_req ||
+          last_patch_req->chunk_id() != curr_patch.chunk_id) {
+        last_patch_req = commit_data_req_->add_chunks_to_patch();
+        last_patch_req->set_writer_id(writer_id);
+        last_patch_req->set_chunk_id(curr_patch.chunk_id);
+        last_patch_req->set_target_buffer(target_buffer);
+      }
+      auto* patch = last_patch_req->add_patches();
+      patch->set_offset(curr_patch.offset);
+      patch->set_data(&curr_patch.size_field[0], curr_patch.size_field.size());
+    }
+
+    // Patches are enqueued in the |patch_list| in order and are notified to
+    // the service when the chunk is returned. The only case when the current
+    // patch list is incomplete is if there is an unpatched entry at the head of
+    // the |patch_list| that belongs to the same ChunkID as the last one we are
+    // about to send to the service.
+    if (last_patch_req && !patch_list->empty() &&
+        patch_list->front().chunk_id == last_patch_req->chunk_id()) {
+      last_patch_req->set_has_more_patches(true);
+    }
+
+    // If the buffer is filling up or if we are given a patch for a chunk
+    // that was already sent to the service, we don't want to wait for the next
+    // delayed flush to happen and we flush immediately. Otherwise, if we
+    // accumulate the patch and a crash occurs before the patch is sent, the
+    // service will not know of the patch and won't be able to reconstruct the
+    // trace.
+    if (fully_bound_ &&
+        (last_patch_req || bytes_pending_commit_ >= shmem_abi_.size() / 2)) {
+      weak_this = weak_ptr_factory_.GetWeakPtr();
+      task_runner_to_post_delayed_callback_on = task_runner_;
+      flush_delay_ms = 0;
+    }
+  }  // scoped_lock(lock_)
+
+  // We shouldn't post tasks while locked.
+  // |task_runner_to_post_delayed_callback_on| remains valid after unlocking,
+  // because |task_runner_| is never reset.
+  if (task_runner_to_post_delayed_callback_on) {
+    task_runner_to_post_delayed_callback_on->PostDelayedTask(
+        [weak_this] {
+          if (!weak_this)
+            return;
+          {
+            std::lock_guard<std::mutex> scoped_lock(weak_this->lock_);
+            // Clear |delayed_flush_scheduled_|, allowing the next call to
+            // UpdateCommitDataRequest to start another batching period.
+            weak_this->delayed_flush_scheduled_ = false;
+          }
+          weak_this->FlushPendingCommitDataRequests();
+        },
+        flush_delay_ms);
+  }
+}
+
+bool SharedMemoryArbiterImpl::TryDirectPatchLocked(
+    WriterID writer_id,
+    const Patch& patch,
+    bool chunk_needs_more_patching) {
+  // Search the chunks that are being batched in |commit_data_req_| for a chunk
+  // that needs patching and that matches the provided |writer_id| and
+  // |patch.chunk_id|. Iterate |commit_data_req_| in reverse, since
+  // |commit_data_req_| is appended to at the end with newly-returned chunks,
+  // and patches are more likely to apply to chunks that have been returned
+  // recently.
+  SharedMemoryABI::Chunk chunk;
+  bool chunk_found = false;
+  auto& chunks_to_move = commit_data_req_->chunks_to_move();
+  for (auto ctm_it = chunks_to_move.rbegin(); ctm_it != chunks_to_move.rend();
+       ++ctm_it) {
+    uint32_t layout = shmem_abi_.GetPageLayout(ctm_it->page());
+    auto chunk_state =
+        shmem_abi_.GetChunkStateFromLayout(layout, ctm_it->chunk());
+    // Note: the subset of |commit_data_req_| chunks that still need patching is
+    // also the subset of chunks that are still being written to. The rest of
+    // the chunks in |commit_data_req_| do not need patching and have already
+    // been marked as complete.
+    if (chunk_state != SharedMemoryABI::kChunkBeingWritten)
+      continue;
+
+    chunk =
+        shmem_abi_.GetChunkUnchecked(ctm_it->page(), layout, ctm_it->chunk());
+    if (chunk.writer_id() == writer_id &&
+        chunk.header()->chunk_id.load(std::memory_order_relaxed) ==
+            patch.chunk_id) {
+      chunk_found = true;
+      break;
+    }
+  }
+
+  if (!chunk_found) {
+    // The chunk has already been committed to the service and the patch cannot
+    // be applied in the producer.
+    return false;
+  }
+
+  // Apply the patch.
+  size_t page_idx;
+  uint8_t chunk_idx;
+  std::tie(page_idx, chunk_idx) = shmem_abi_.GetPageAndChunkIndex(chunk);
+  PERFETTO_DCHECK(shmem_abi_.GetChunkState(page_idx, chunk_idx) ==
+                  SharedMemoryABI::ChunkState::kChunkBeingWritten);
+  auto chunk_begin = chunk.payload_begin();
+  uint8_t* ptr = chunk_begin + patch.offset;
+  PERFETTO_CHECK(ptr <= chunk.end() - SharedMemoryABI::kPacketHeaderSize);
+  // DCHECK that we are writing into a zero-filled size field and not into
+  // valid data. It relies on ScatteredStreamWriter::ReserveBytes() to
+  // zero-fill reservations in debug builds.
+  const char zero[SharedMemoryABI::kPacketHeaderSize]{};
+  PERFETTO_DCHECK(memcmp(ptr, &zero, SharedMemoryABI::kPacketHeaderSize) == 0);
+
+  memcpy(ptr, &patch.size_field[0], SharedMemoryABI::kPacketHeaderSize);
+
+  if (!chunk_needs_more_patching) {
+    // Mark that the chunk doesn't need more patching and mark it as complete,
+    // as the producer will not write to it anymore. This allows the service to
+    // read the chunk in full while scraping, which would not be the case if the
+    // chunk was left in a kChunkBeingWritten state.
+    chunk.ClearNeedsPatchingFlag();
+    shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
+  }
+
+  return true;
+}
+
+void SharedMemoryArbiterImpl::SetBatchCommitsDuration(
+    uint32_t batch_commits_duration_ms) {
+  std::lock_guard<std::mutex> scoped_lock(lock_);
+  batch_commits_duration_ms_ = batch_commits_duration_ms;
+}
+
+bool SharedMemoryArbiterImpl::EnableDirectSMBPatching() {
+  std::lock_guard<std::mutex> scoped_lock(lock_);
+  if (!direct_patching_supported_by_service_) {
+    return false;
+  }
+
+  return direct_patching_enabled_ = true;
+}
+
+void SharedMemoryArbiterImpl::SetDirectSMBPatchingSupportedByService() {
+  std::lock_guard<std::mutex> scoped_lock(lock_);
+  direct_patching_supported_by_service_ = true;
+}
+
+// This function is quite subtle. When making changes keep in mind these two
+// challenges:
+// 1) If the producer stalls and we happen to be on the |task_runner_| IPC
+//    thread (or, for in-process cases, on the same thread where
+//    TracingServiceImpl lives), the CommitData() call must be synchronous and
+//    not posted, to avoid deadlocks.
+// 2) When different threads hit this function, we must guarantee that we don't
+//    accidentally make commits out of order. See commit 4e4fe8f56ef and
+//    crbug.com/919187 for more context.
+void SharedMemoryArbiterImpl::FlushPendingCommitDataRequests(
+    std::function<void()> callback) {
+  std::unique_ptr<CommitDataRequest> req;
+  {
+    std::unique_lock<std::mutex> scoped_lock(lock_);
+
+    // Flushing is only supported while |fully_bound_|, and there may still be
+    // unbound startup trace writers. If so, skip the commit for now - it'll be
+    // done when |fully_bound_| is updated.
+    if (!fully_bound_) {
+      if (callback)
+        pending_flush_callbacks_.push_back(callback);
+      return;
+    }
+
+    // May be called by TraceWriterImpl on any thread.
+    base::TaskRunner* task_runner = task_runner_;
+    if (!task_runner->RunsTasksOnCurrentThread()) {
+      // We shouldn't post a task while holding a lock. |task_runner| remains
+      // valid after unlocking, because |task_runner_| is never reset.
+      scoped_lock.unlock();
+
+      auto weak_this = weak_ptr_factory_.GetWeakPtr();
+      task_runner->PostTask([weak_this, callback] {
+        if (weak_this)
+          weak_this->FlushPendingCommitDataRequests(std::move(callback));
+      });
+      return;
+    }
+
+    // |commit_data_req_| could have become a nullptr, for example when a forced
+    // sync flush happens in GetNewChunk().
+    if (commit_data_req_) {
+      // Make sure any placeholder buffer IDs from StartupWriters are replaced
+      // before sending the request.
+      bool all_placeholders_replaced =
+          ReplaceCommitPlaceholderBufferIdsLocked();
+      // We're |fully_bound_|, thus all writers are bound and all placeholders
+      // should have been replaced.
+      PERFETTO_DCHECK(all_placeholders_replaced);
+
+      // In order to allow patching in the producer we delay the kChunkComplete
+      // transition and keep batched chunks in the kChunkBeingWritten state.
+      // Since we are about to notify the service of all batched chunks, it will
+      // not be possible to apply any more patches to them and we need to move
+      // them to kChunkComplete - otherwise the service won't look at them.
+      for (auto& ctm : *commit_data_req_->mutable_chunks_to_move()) {
+        uint32_t layout = shmem_abi_.GetPageLayout(ctm.page());
+        auto chunk_state =
+            shmem_abi_.GetChunkStateFromLayout(layout, ctm.chunk());
+        // Note: the subset of |commit_data_req_| chunks that still need
+        // patching is also the subset of chunks that are still being written
+        // to. The rest of the chunks in |commit_data_req_| do not need patching
+        // and have already been marked as complete.
+        if (chunk_state == SharedMemoryABI::kChunkBeingWritten) {
+          auto chunk =
+              shmem_abi_.GetChunkUnchecked(ctm.page(), layout, ctm.chunk());
+          shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
+        }
+
+        if (use_shmem_emulation_) {
+          // When running in the emulation mode:
+          // 1. serialize the chunk data to |ctm| as we won't modify the chunk
+          // anymore.
+          // 2. free the chunk as the service won't be able to do this.
+          auto chunk =
+              shmem_abi_.GetChunkUnchecked(ctm.page(), layout, ctm.chunk());
+          PERFETTO_CHECK(chunk.is_valid());
+          ctm.set_data(chunk.begin(), chunk.size());
+          shmem_abi_.ReleaseChunkAsFree(std::move(chunk));
+        }
+      }
+
+      req = std::move(commit_data_req_);
+      bytes_pending_commit_ = 0;
+    }
+  }  // scoped_lock
+
+  if (req) {
+    producer_endpoint_->CommitData(*req, callback);
+  } else if (callback) {
+    // If |req| was nullptr, it means that an enqueued deferred commit was
+    // executed just before this. At this point send an empty commit request
+    // to the service, just to linearize with it and give the guarantee to the
+    // caller that the data has been flushed into the service.
+    producer_endpoint_->CommitData(CommitDataRequest(), std::move(callback));
+  }
+}
+
+bool SharedMemoryArbiterImpl::TryShutdown() {
+  std::lock_guard<std::mutex> scoped_lock(lock_);
+  did_shutdown_ = true;
+  // Shutdown is safe if there are no active trace writers for this arbiter.
+  return active_writer_ids_.IsEmpty();
+}
+
+std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriter(
+    BufferID target_buffer,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  PERFETTO_CHECK(target_buffer > 0);
+  return CreateTraceWriterInternal(target_buffer, buffer_exhausted_policy);
+}
+
+std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateStartupTraceWriter(
+    uint16_t target_buffer_reservation_id) {
+  return CreateTraceWriterInternal(
+      MakeTargetBufferIdForReservation(target_buffer_reservation_id),
+      BufferExhaustedPolicy::kDrop);
+}
+
+void SharedMemoryArbiterImpl::BindToProducerEndpoint(
+    TracingService::ProducerEndpoint* producer_endpoint,
+    base::TaskRunner* task_runner) {
+  PERFETTO_DCHECK(producer_endpoint && task_runner);
+  PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
+
+  bool should_flush = false;
+  std::function<void()> flush_callback;
+  {
+    std::lock_guard<std::mutex> scoped_lock(lock_);
+    PERFETTO_CHECK(!fully_bound_);
+    PERFETTO_CHECK(!producer_endpoint_ && !task_runner_);
+
+    producer_endpoint_ = producer_endpoint;
+    task_runner_ = task_runner;
+
+    // Now that we're bound to a task runner, also reset the WeakPtrFactory to
+    // it. Because this code runs on the task runner, the factory's weak
+    // pointers will be valid on it.
+    weak_ptr_factory_.Reset(this);
+
+    // All writers registered so far should be startup trace writers, since
+    // the producer cannot feasibly know the target buffer for any future
+    // session yet.
+    for (const auto& entry : pending_writers_) {
+      PERFETTO_CHECK(IsReservationTargetBufferId(entry.second));
+    }
+
+    // If all buffer reservations are bound, we can flush pending commits.
+    if (UpdateFullyBoundLocked()) {
+      should_flush = true;
+      flush_callback = TakePendingFlushCallbacksLocked();
+    }
+  }  // scoped_lock
+
+  // Attempt to flush any pending commits (and run pending flush callbacks). If
+  // there are none, this will have no effect. If we ended up in a race that
+  // changed |fully_bound_| back to false, the commit will happen once we become
+  // |fully_bound_| again.
+  if (should_flush)
+    FlushPendingCommitDataRequests(flush_callback);
+}
+
+void SharedMemoryArbiterImpl::BindStartupTargetBuffer(
+    uint16_t target_buffer_reservation_id,
+    BufferID target_buffer_id) {
+  PERFETTO_DCHECK(target_buffer_id > 0);
+
+  std::unique_lock<std::mutex> scoped_lock(lock_);
+
+  // We should already be bound to an endpoint.
+  PERFETTO_CHECK(producer_endpoint_);
+  PERFETTO_CHECK(task_runner_);
+  PERFETTO_CHECK(task_runner_->RunsTasksOnCurrentThread());
+
+  BindStartupTargetBufferImpl(std::move(scoped_lock),
+                              target_buffer_reservation_id, target_buffer_id);
+}
+
+void SharedMemoryArbiterImpl::AbortStartupTracingForReservation(
+    uint16_t target_buffer_reservation_id) {
+  std::unique_lock<std::mutex> scoped_lock(lock_);
+
+  // If we are already bound to an arbiter, we may need to flush after aborting
+  // the session, and thus should be running on the arbiter's task runner.
+  if (task_runner_ && !task_runner_->RunsTasksOnCurrentThread()) {
+    // We shouldn't post tasks while locked.
+    auto* task_runner = task_runner_;
+    scoped_lock.unlock();
+
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner->PostTask([weak_this, target_buffer_reservation_id]() {
+      if (!weak_this)
+        return;
+      weak_this->AbortStartupTracingForReservation(
+          target_buffer_reservation_id);
+    });
+    return;
+  }
+
+  // Bind the target buffer reservation to an invalid buffer (ID 0), so that
+  // existing commits, as well as future commits (of currently acquired chunks),
+  // will be released as free free by the service but otherwise ignored (i.e.
+  // not copied into any valid target buffer).
+  BindStartupTargetBufferImpl(std::move(scoped_lock),
+                              target_buffer_reservation_id,
+                              /*target_buffer_id=*/kInvalidBufferId);
+}
+
+void SharedMemoryArbiterImpl::BindStartupTargetBufferImpl(
+    std::unique_lock<std::mutex> scoped_lock,
+    uint16_t target_buffer_reservation_id,
+    BufferID target_buffer_id) {
+  // We should already be bound to an endpoint if the target buffer is valid.
+  PERFETTO_DCHECK((producer_endpoint_ && task_runner_) ||
+                  target_buffer_id == kInvalidBufferId);
+
+  PERFETTO_DLOG("Binding startup target buffer reservation %" PRIu16
+                " to buffer %" PRIu16,
+                target_buffer_reservation_id, target_buffer_id);
+
+  MaybeUnboundBufferID reserved_id =
+      MakeTargetBufferIdForReservation(target_buffer_reservation_id);
+
+  bool should_flush = false;
+  std::function<void()> flush_callback;
+  std::vector<std::pair<WriterID, BufferID>> writers_to_register;
+
+  TargetBufferReservation& reservation =
+      target_buffer_reservations_[reserved_id];
+  PERFETTO_CHECK(!reservation.resolved);
+  reservation.resolved = true;
+  reservation.target_buffer = target_buffer_id;
+
+  // Collect trace writers associated with the reservation.
+  for (auto it = pending_writers_.begin(); it != pending_writers_.end();) {
+    if (it->second == reserved_id) {
+      // No need to register writers that have an invalid target buffer.
+      if (target_buffer_id != kInvalidBufferId) {
+        writers_to_register.push_back(
+            std::make_pair(it->first, target_buffer_id));
+      }
+      it = pending_writers_.erase(it);
+    } else {
+      it++;
+    }
+  }
+
+  // If all buffer reservations are bound, we can flush pending commits.
+  if (UpdateFullyBoundLocked()) {
+    should_flush = true;
+    flush_callback = TakePendingFlushCallbacksLocked();
+  }
+
+  scoped_lock.unlock();
+
+  // Register any newly bound trace writers with the service.
+  for (const auto& writer_and_target_buffer : writers_to_register) {
+    producer_endpoint_->RegisterTraceWriter(writer_and_target_buffer.first,
+                                            writer_and_target_buffer.second);
+  }
+
+  // Attempt to flush any pending commits (and run pending flush callbacks). If
+  // there are none, this will have no effect. If we ended up in a race that
+  // changed |fully_bound_| back to false, the commit will happen once we become
+  // |fully_bound_| again.
+  if (should_flush)
+    FlushPendingCommitDataRequests(flush_callback);
+}
+
+std::function<void()>
+SharedMemoryArbiterImpl::TakePendingFlushCallbacksLocked() {
+  if (pending_flush_callbacks_.empty())
+    return std::function<void()>();
+
+  std::vector<std::function<void()>> pending_flush_callbacks;
+  pending_flush_callbacks.swap(pending_flush_callbacks_);
+  // Capture the callback list into the lambda by copy.
+  return [pending_flush_callbacks]() {
+    for (auto& callback : pending_flush_callbacks)
+      callback();
+  };
+}
+
+void SharedMemoryArbiterImpl::NotifyFlushComplete(FlushRequestID req_id) {
+  base::TaskRunner* task_runner_to_commit_on = nullptr;
+
+  {
+    std::lock_guard<std::mutex> scoped_lock(lock_);
+    // If a commit_data_req_ exists it means that somebody else already posted a
+    // FlushPendingCommitDataRequests() task.
+    if (!commit_data_req_) {
+      commit_data_req_.reset(new CommitDataRequest());
+
+      // Flushing the commit is only supported while we're |fully_bound_|. If we
+      // aren't, we'll flush when |fully_bound_| is updated.
+      if (fully_bound_)
+        task_runner_to_commit_on = task_runner_;
+    } else {
+      // If there is another request queued and that also contains is a reply
+      // to a flush request, reply with the highest id.
+      req_id = std::max(req_id, commit_data_req_->flush_request_id());
+    }
+    commit_data_req_->set_flush_request_id(req_id);
+  }  // scoped_lock
+
+  // We shouldn't post tasks while locked. |task_runner_to_commit_on|
+  // remains valid after unlocking, because |task_runner_| is never reset.
+  if (task_runner_to_commit_on) {
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_to_commit_on->PostTask([weak_this] {
+      if (weak_this)
+        weak_this->FlushPendingCommitDataRequests();
+    });
+  }
+}
+
+std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriterInternal(
+    MaybeUnboundBufferID target_buffer,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  WriterID id;
+  base::TaskRunner* task_runner_to_register_on = nullptr;
+
+  {
+    std::lock_guard<std::mutex> scoped_lock(lock_);
+    if (did_shutdown_)
+      return std::unique_ptr<TraceWriter>(new NullTraceWriter());
+
+    id = active_writer_ids_.Allocate();
+    if (!id)
+      return std::unique_ptr<TraceWriter>(new NullTraceWriter());
+
+    PERFETTO_DCHECK(!pending_writers_.count(id));
+
+    if (IsReservationTargetBufferId(target_buffer)) {
+      // If the reservation is new, mark it as unbound in
+      // |target_buffer_reservations_|. Otherwise, if the reservation was
+      // already bound, choose the bound buffer ID now.
+      auto it_and_inserted = target_buffer_reservations_.insert(
+          {target_buffer, TargetBufferReservation()});
+      if (it_and_inserted.first->second.resolved)
+        target_buffer = it_and_inserted.first->second.target_buffer;
+    }
+
+    if (IsReservationTargetBufferId(target_buffer)) {
+      // The arbiter and/or startup buffer reservations are not bound yet, so
+      // buffer the registration of the writer until after we're bound.
+      pending_writers_[id] = target_buffer;
+
+      // Mark the arbiter as not fully bound, since we now have at least one
+      // unbound trace writer / target buffer reservation.
+      fully_bound_ = false;
+      was_always_bound_ = false;
+    } else if (target_buffer != kInvalidBufferId) {
+      // Trace writer is bound, so arbiter should be bound to an endpoint, too.
+      PERFETTO_CHECK(producer_endpoint_ && task_runner_);
+      task_runner_to_register_on = task_runner_;
+    }
+
+    // All trace writers must use kDrop policy if the arbiter ever becomes
+    // unbound.
+    bool uses_drop_policy =
+        buffer_exhausted_policy == BufferExhaustedPolicy::kDrop;
+    all_writers_have_drop_policy_ &= uses_drop_policy;
+    PERFETTO_DCHECK(fully_bound_ || uses_drop_policy);
+    PERFETTO_CHECK(fully_bound_ || all_writers_have_drop_policy_);
+    PERFETTO_CHECK(was_always_bound_ || uses_drop_policy);
+  }  // scoped_lock
+
+  // We shouldn't post tasks while locked. |task_runner_to_register_on|
+  // remains valid after unlocking, because |task_runner_| is never reset.
+  if (task_runner_to_register_on) {
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_to_register_on->PostTask([weak_this, id, target_buffer] {
+      if (weak_this)
+        weak_this->producer_endpoint_->RegisterTraceWriter(id, target_buffer);
+    });
+  }
+
+  return std::unique_ptr<TraceWriter>(
+      new TraceWriterImpl(this, id, target_buffer, buffer_exhausted_policy));
+}
+
+void SharedMemoryArbiterImpl::ReleaseWriterID(WriterID id) {
+  base::TaskRunner* task_runner = nullptr;
+  {
+    std::lock_guard<std::mutex> scoped_lock(lock_);
+    active_writer_ids_.Free(id);
+
+    auto it = pending_writers_.find(id);
+    if (it != pending_writers_.end()) {
+      // Writer hasn't been bound yet and thus also not yet registered with the
+      // service.
+      pending_writers_.erase(it);
+      return;
+    }
+
+    // A trace writer from an aborted session may be destroyed before the
+    // arbiter is bound to a task runner. In that case, it was never registered
+    // with the service.
+    if (!task_runner_)
+      return;
+
+    task_runner = task_runner_;
+  }  // scoped_lock
+
+  // We shouldn't post tasks while locked. |task_runner| remains valid after
+  // unlocking, because |task_runner_| is never reset.
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner->PostTask([weak_this, id] {
+    if (weak_this)
+      weak_this->producer_endpoint_->UnregisterTraceWriter(id);
+  });
+}
+
+bool SharedMemoryArbiterImpl::ReplaceCommitPlaceholderBufferIdsLocked() {
+  if (!commit_data_req_)
+    return true;
+
+  bool all_placeholders_replaced = true;
+  for (auto& chunk : *commit_data_req_->mutable_chunks_to_move()) {
+    if (!IsReservationTargetBufferId(chunk.target_buffer()))
+      continue;
+    const auto it = target_buffer_reservations_.find(chunk.target_buffer());
+    PERFETTO_DCHECK(it != target_buffer_reservations_.end());
+    if (!it->second.resolved) {
+      all_placeholders_replaced = false;
+      continue;
+    }
+    chunk.set_target_buffer(it->second.target_buffer);
+  }
+  for (auto& chunk : *commit_data_req_->mutable_chunks_to_patch()) {
+    if (!IsReservationTargetBufferId(chunk.target_buffer()))
+      continue;
+    const auto it = target_buffer_reservations_.find(chunk.target_buffer());
+    PERFETTO_DCHECK(it != target_buffer_reservations_.end());
+    if (!it->second.resolved) {
+      all_placeholders_replaced = false;
+      continue;
+    }
+    chunk.set_target_buffer(it->second.target_buffer);
+  }
+  return all_placeholders_replaced;
+}
+
+bool SharedMemoryArbiterImpl::UpdateFullyBoundLocked() {
+  if (!producer_endpoint_) {
+    PERFETTO_DCHECK(!fully_bound_);
+    return false;
+  }
+  // We're fully bound if all target buffer reservations have a valid associated
+  // BufferID.
+  fully_bound_ = std::none_of(
+      target_buffer_reservations_.begin(), target_buffer_reservations_.end(),
+      [](std::pair<MaybeUnboundBufferID, TargetBufferReservation> entry) {
+        return !entry.second.resolved;
+      });
+  if (!fully_bound_)
+    was_always_bound_ = false;
+  return fully_bound_;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/trace_packet.cc
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+
+TracePacket::TracePacket() = default;
+TracePacket::~TracePacket() = default;
+
+TracePacket::TracePacket(TracePacket&& other) noexcept {
+  *this = std::move(other);
+}
+
+TracePacket& TracePacket::operator=(TracePacket&& other) {
+  slices_ = std::move(other.slices_);
+  other.slices_.clear();
+  size_ = other.size_;
+  other.size_ = 0;
+  buffer_index_for_stats_ = other.buffer_index_for_stats_;
+  other.buffer_index_for_stats_ = 0;
+  return *this;
+}
+
+void TracePacket::AddSlice(Slice slice) {
+  size_ += slice.size;
+  slices_.push_back(std::move(slice));
+}
+
+void TracePacket::AddSlice(const void* start, size_t size) {
+  size_ += size;
+  slices_.emplace_back(start, size);
+}
+
+std::tuple<char*, size_t> TracePacket::GetProtoPreamble() {
+  using protozero::proto_utils::MakeTagLengthDelimited;
+  using protozero::proto_utils::WriteVarInt;
+  uint8_t* ptr = reinterpret_cast<uint8_t*>(&preamble_[0]);
+
+  constexpr uint8_t tag = MakeTagLengthDelimited(kPacketFieldNumber);
+  static_assert(tag < 0x80, "TracePacket tag should fit in one byte");
+  *(ptr++) = tag;
+
+  ptr = WriteVarInt(size(), ptr);
+  size_t preamble_size = reinterpret_cast<uintptr_t>(ptr) -
+                         reinterpret_cast<uintptr_t>(&preamble_[0]);
+  PERFETTO_DCHECK(preamble_size <= sizeof(preamble_));
+  return std::make_tuple(&preamble_[0], preamble_size);
+}
+
+std::string TracePacket::GetRawBytesForTesting() {
+  std::string data;
+  data.resize(size());
+  size_t pos = 0;
+  for (const Slice& slice : slices()) {
+    PERFETTO_CHECK(pos + slice.size <= data.size());
+    memcpy(&data[pos], slice.start, slice.size);
+    pos += slice.size;
+  }
+  return data;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/trace_writer_impl.cc
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"
+
+#include <string.h>
+
+#include <algorithm>
+#include <type_traits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
+// gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+using protozero::proto_utils::kMessageLengthFieldSize;
+using protozero::proto_utils::WriteRedundantVarInt;
+using ChunkHeader = perfetto::SharedMemoryABI::ChunkHeader;
+
+namespace perfetto {
+
+namespace {
+constexpr size_t kPacketHeaderSize = SharedMemoryABI::kPacketHeaderSize;
+// The -1 is because we want to leave extra room to inflate the counter.
+constexpr size_t kMaxPacketsPerChunk = ChunkHeader::Packets::kMaxCount - 1;
+// When the packet count in a chunk is inflated, TraceWriter is always going to
+// leave this kExtraRoomForInflatedPacket bytes to write an empty trace packet
+// if it needs to.
+constexpr size_t kExtraRoomForInflatedPacket = 1;
+uint8_t g_garbage_chunk[1024];
+}  // namespace
+
+TraceWriterImpl::TraceWriterImpl(SharedMemoryArbiterImpl* shmem_arbiter,
+                                 WriterID id,
+                                 MaybeUnboundBufferID target_buffer,
+                                 BufferExhaustedPolicy buffer_exhausted_policy)
+    : shmem_arbiter_(shmem_arbiter),
+      id_(id),
+      target_buffer_(target_buffer),
+      buffer_exhausted_policy_(buffer_exhausted_policy),
+      protobuf_stream_writer_(this),
+      process_id_(base::GetProcessId()) {
+  // TODO(primiano): we could handle the case of running out of TraceWriterID(s)
+  // more gracefully and always return a no-op TracePacket in NewTracePacket().
+  PERFETTO_CHECK(id_ != 0);
+
+  cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
+  cur_packet_->Finalize();  // To avoid the CHECK in NewTracePacket().
+}
+
+TraceWriterImpl::~TraceWriterImpl() {
+  if (cur_chunk_.is_valid()) {
+    cur_packet_->Finalize();
+    Flush();
+  }
+  // This call may cause the shared memory arbiter (and the underlying memory)
+  // to get asynchronously deleted if this was the last trace writer targeting
+  // the arbiter and the arbiter was marked for shutdown.
+  shmem_arbiter_->ReleaseWriterID(id_);
+}
+
+void TraceWriterImpl::ReturnCompletedChunk() {
+  PERFETTO_DCHECK(cur_chunk_.is_valid());
+  if (cur_chunk_packet_count_inflated_) {
+    uint8_t zero_size = 0;
+    static_assert(sizeof zero_size == kExtraRoomForInflatedPacket);
+    PERFETTO_CHECK(protobuf_stream_writer_.bytes_available() != 0);
+    protobuf_stream_writer_.WriteBytesUnsafe(&zero_size, sizeof zero_size);
+    cur_chunk_packet_count_inflated_ = false;
+  }
+  shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
+                                       &patch_list_);
+}
+
+void TraceWriterImpl::Flush(std::function<void()> callback) {
+  // Flush() cannot be called in the middle of a TracePacket.
+  PERFETTO_CHECK(cur_packet_->is_finalized());
+  // cur_packet_ is finalized: that means that the size is correct for all the
+  // nested submessages. The root fragment size however is not handled by
+  // protozero::Message::Finalize() and must be filled here.
+  FinalizeFragmentIfRequired();
+
+  if (cur_chunk_.is_valid()) {
+    ReturnCompletedChunk();
+  } else {
+    // When in stall mode, all patches should have been returned with the last
+    // chunk, since the last packet was completed. In drop_packets_ mode, this
+    // may not be the case because the packet may have been fragmenting when
+    // SMB exhaustion occurred and |cur_chunk_| became invalid. In this case,
+    // drop_packets_ should be true.
+    PERFETTO_DCHECK(patch_list_.empty() || drop_packets_);
+  }
+
+  // Always issue the Flush request, even if there is nothing to flush, just
+  // for the sake of getting the callback posted back.
+  shmem_arbiter_->FlushPendingCommitDataRequests(callback);
+  protobuf_stream_writer_.Reset({nullptr, nullptr});
+}
+
+TraceWriterImpl::TracePacketHandle TraceWriterImpl::NewTracePacket() {
+  // If we hit this, the caller is calling NewTracePacket() without having
+  // finalized the previous packet.
+  PERFETTO_CHECK(cur_packet_->is_finalized());
+  // If we hit this, this trace writer was created in a different process. This
+  // likely means that the process forked while tracing was active, and the
+  // forked child process tried to emit a trace event. This is not supported, as
+  // it would lead to two processes writing to the same tracing SMB.
+  PERFETTO_DCHECK(process_id_ == base::GetProcessId());
+
+  // Before starting a new packet, make sure that the last fragment size has ben
+  // written correctly. The root fragment size is not written by
+  // protozero::Message::Finalize().
+  FinalizeFragmentIfRequired();
+
+  fragmenting_packet_ = false;
+
+  // Reserve space for the size of the message. Note: this call might re-enter
+  // into this class invoking GetNewBuffer() if there isn't enough space or if
+  // this is the very first call to NewTracePacket().
+  static_assert(kPacketHeaderSize == kMessageLengthFieldSize,
+                "The packet header must match the Message header size");
+
+  bool was_dropping_packets = drop_packets_;
+
+  // It doesn't make sense to begin a packet that is going to fragment
+  // immediately after (8 is just an arbitrary estimation on the minimum size of
+  // a realistic packet).
+  bool chunk_too_full =
+      protobuf_stream_writer_.bytes_available() < kPacketHeaderSize + 8;
+  if (chunk_too_full || reached_max_packets_per_chunk_ ||
+      retry_new_chunk_after_packet_) {
+    protobuf_stream_writer_.Reset(GetNewBuffer());
+  }
+
+  // Send any completed patches to the service to facilitate trace data
+  // recovery by the service. This should only happen when we're completing
+  // the first packet in a chunk which was a continuation from the previous
+  // chunk, i.e. at most once per chunk.
+  if (!patch_list_.empty() && patch_list_.front().is_patched()) {
+    shmem_arbiter_->SendPatches(id_, target_buffer_, &patch_list_);
+  }
+
+  cur_packet_->Reset(&protobuf_stream_writer_);
+  uint8_t* header = protobuf_stream_writer_.ReserveBytes(kPacketHeaderSize);
+  memset(header, 0, kPacketHeaderSize);
+  cur_fragment_size_field_ = header;
+
+  TracePacketHandle handle(cur_packet_.get());
+  cur_fragment_start_ = protobuf_stream_writer_.write_ptr();
+  fragmenting_packet_ = true;
+
+  if (PERFETTO_LIKELY(!drop_packets_)) {
+    uint16_t new_packet_count;
+    if (cur_chunk_packet_count_inflated_) {
+      new_packet_count =
+          cur_chunk_.header()->packets.load(std::memory_order_relaxed).count;
+      cur_chunk_packet_count_inflated_ = false;
+    } else {
+      new_packet_count = cur_chunk_.IncrementPacketCount();
+    }
+    reached_max_packets_per_chunk_ = new_packet_count == kMaxPacketsPerChunk;
+
+    if (PERFETTO_UNLIKELY(was_dropping_packets)) {
+      // We've succeeded to get a new chunk from the SMB after we entered
+      // drop_packets_ mode. Record a marker into the new packet to indicate the
+      // data loss.
+      cur_packet_->set_previous_packet_dropped(true);
+    }
+  }
+
+  if (PERFETTO_UNLIKELY(first_packet_on_sequence_)) {
+    cur_packet_->set_first_packet_on_sequence(true);
+    first_packet_on_sequence_ = false;
+  }
+
+  return handle;
+}
+
+// Called by the Message. We can get here in two cases:
+// 1. In the middle of writing a Message,
+// when |fragmenting_packet_| == true. In this case we want to update the
+// chunk header with a partial packet and start a new partial packet in the
+// new chunk.
+// 2. While calling ReserveBytes() for the packet header in NewTracePacket().
+// In this case |fragmenting_packet_| == false and we just want a new chunk
+// without creating any fragments.
+protozero::ContiguousMemoryRange TraceWriterImpl::GetNewBuffer() {
+  if (fragmenting_packet_ && drop_packets_) {
+    // We can't write the remaining data of the fragmenting packet to a new
+    // chunk, because we have already lost some of its data in the garbage
+    // chunk. Thus, we will wrap around in the garbage chunk, wait until the
+    // current packet was completed, and then attempt to get a new chunk from
+    // the SMB again. Instead, if |drop_packets_| is true and
+    // |fragmenting_packet_| is false, we try to acquire a valid chunk because
+    // the SMB exhaustion might be resolved.
+    retry_new_chunk_after_packet_ = true;
+    cur_fragment_size_field_ = nullptr;
+    cur_fragment_start_ = &g_garbage_chunk[0];
+    return protozero::ContiguousMemoryRange{
+        &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
+  }
+
+  // Attempt to grab the next chunk before finalizing the current one, so that
+  // we know whether we need to start dropping packets before writing the
+  // current packet fragment's header.
+  ChunkHeader::Packets packets = {};
+  if (fragmenting_packet_) {
+    packets.count = 1;
+    packets.flags = ChunkHeader::kFirstPacketContinuesFromPrevChunk;
+  }
+
+  // The memory order of the stores below doesn't really matter. This |header|
+  // is just a local temporary object. The GetNewChunk() call below will copy it
+  // into the shared buffer with the proper barriers.
+  ChunkHeader header = {};
+  header.writer_id.store(id_, std::memory_order_relaxed);
+  header.chunk_id.store(next_chunk_id_, std::memory_order_relaxed);
+  header.packets.store(packets, std::memory_order_relaxed);
+
+  SharedMemoryABI::Chunk new_chunk =
+      shmem_arbiter_->GetNewChunk(header, buffer_exhausted_policy_);
+  if (!new_chunk.is_valid()) {
+    // Shared memory buffer exhausted, switch into |drop_packets_| mode. We'll
+    // drop data until the garbage chunk has been filled once and then retry.
+
+    // If we started a packet in one of the previous (valid) chunks, we need to
+    // tell the service to discard it.
+    if (fragmenting_packet_) {
+      // We can only end up here if the previous chunk was a valid chunk,
+      // because we never try to acquire a new chunk in |drop_packets_| mode
+      // while fragmenting.
+      PERFETTO_DCHECK(!drop_packets_);
+
+      // Backfill the last fragment's header with an invalid size (too large),
+      // so that the service's TraceBuffer throws out the incomplete packet.
+      // It'll restart reading from the next chunk we submit.
+      WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
+                           cur_fragment_size_field_);
+
+      // Reset the size field, since we should not write the current packet's
+      // size anymore after this.
+      cur_fragment_size_field_ = nullptr;
+
+      // We don't set kLastPacketContinuesOnNextChunk or kChunkNeedsPatching on
+      // the last chunk, because its last fragment will be discarded anyway.
+      // However, the current packet fragment points to a valid |cur_chunk_| and
+      // may have non-finalized nested messages which will continue in the
+      // garbage chunk and currently still point into |cur_chunk_|. As we are
+      // about to return |cur_chunk_|, we need to invalidate the size fields of
+      // those nested messages. Normally we move them in the |patch_list_| (see
+      // below) but in this case, it doesn't make sense to send patches for a
+      // fragment that will be discarded for sure. Thus, we clean up any size
+      // field references into |cur_chunk_|.
+      for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
+           nested_msg = nested_msg->nested_message()) {
+        uint8_t* const cur_hdr = nested_msg->size_field();
+
+        // If this is false the protozero Message has already been instructed to
+        // write, upon Finalize(), its size into the patch list.
+        bool size_field_points_within_chunk =
+            cur_hdr >= cur_chunk_.payload_begin() &&
+            cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();
+
+        if (size_field_points_within_chunk)
+          nested_msg->set_size_field(nullptr);
+      }
+    } else if (!drop_packets_ && cur_fragment_size_field_) {
+      // If we weren't dropping packets before, we should indicate to the
+      // service that we're about to lose data. We do this by invalidating the
+      // size of the last packet in |cur_chunk_|. The service will record
+      // statistics about packets with kPacketSizeDropPacket size.
+      PERFETTO_DCHECK(cur_packet_->is_finalized());
+      PERFETTO_DCHECK(cur_chunk_.is_valid());
+
+      // |cur_fragment_size_field_| should point within |cur_chunk_|'s payload.
+      PERFETTO_DCHECK(cur_fragment_size_field_ >= cur_chunk_.payload_begin() &&
+                      cur_fragment_size_field_ + kMessageLengthFieldSize <=
+                          cur_chunk_.end());
+
+      WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
+                           cur_fragment_size_field_);
+    }
+
+    if (cur_chunk_.is_valid()) {
+      ReturnCompletedChunk();
+    }
+
+    drop_packets_ = true;
+    cur_chunk_ = SharedMemoryABI::Chunk();  // Reset to an invalid chunk.
+    cur_chunk_packet_count_inflated_ = false;
+    reached_max_packets_per_chunk_ = false;
+    retry_new_chunk_after_packet_ = false;
+    cur_fragment_size_field_ = nullptr;
+    cur_fragment_start_ = &g_garbage_chunk[0];
+
+    PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&g_garbage_chunk,
+                                        sizeof(g_garbage_chunk),
+                                        "nobody reads the garbage chunk")
+    return protozero::ContiguousMemoryRange{
+        &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
+  }  // if (!new_chunk.is_valid())
+
+  PERFETTO_DCHECK(new_chunk.is_valid());
+
+  if (fragmenting_packet_) {
+    // We should not be fragmenting a packet after we exited drop_packets_ mode,
+    // because we only retry to get a new chunk when a fresh packet is started.
+    PERFETTO_DCHECK(!drop_packets_);
+
+    uint8_t* const wptr = protobuf_stream_writer_.write_ptr();
+    PERFETTO_DCHECK(wptr >= cur_fragment_start_);
+    uint32_t partial_size = static_cast<uint32_t>(wptr - cur_fragment_start_);
+    PERFETTO_DCHECK(partial_size < cur_chunk_.size());
+
+    // Backfill the packet header with the fragment size.
+    PERFETTO_DCHECK(partial_size > 0);
+    cur_chunk_.SetFlag(ChunkHeader::kLastPacketContinuesOnNextChunk);
+    WriteRedundantVarInt(partial_size, cur_fragment_size_field_);
+
+    // Descend in the stack of non-finalized nested submessages (if any) and
+    // detour their |size_field| into the |patch_list_|. At this point we have
+    // to release the chunk and they cannot write anymore into that.
+    for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
+         nested_msg = nested_msg->nested_message()) {
+      uint8_t* cur_hdr = nested_msg->size_field();
+
+      // If this is false the protozero Message has already been instructed to
+      // write, upon Finalize(), its size into the patch list.
+      bool size_field_points_within_chunk =
+          cur_hdr >= cur_chunk_.payload_begin() &&
+          cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();
+
+      if (size_field_points_within_chunk) {
+        cur_hdr = TraceWriterImpl::AnnotatePatch(cur_hdr);
+        nested_msg->set_size_field(cur_hdr);
+      } else {
+#if PERFETTO_DCHECK_IS_ON()
+        // Ensure that the size field of the message points to an element of the
+        // patch list.
+        auto patch_it = std::find_if(
+            patch_list_.begin(), patch_list_.end(),
+            [cur_hdr](const Patch& p) { return &p.size_field[0] == cur_hdr; });
+        PERFETTO_DCHECK(patch_it != patch_list_.end());
+#endif
+      }
+    }  // for(nested_msg)
+  }    // if(fragmenting_packet)
+
+  if (cur_chunk_.is_valid()) {
+    // ReturnCompletedChunk will consume the first patched entries from
+    // |patch_list_| and shrink it.
+    ReturnCompletedChunk();
+  }
+
+  // Switch to the new chunk.
+  drop_packets_ = false;
+  reached_max_packets_per_chunk_ = false;
+  retry_new_chunk_after_packet_ = false;
+  next_chunk_id_++;
+  cur_chunk_ = std::move(new_chunk);
+  cur_chunk_packet_count_inflated_ = false;
+  cur_fragment_size_field_ = nullptr;
+
+  uint8_t* payload_begin = cur_chunk_.payload_begin();
+  if (fragmenting_packet_) {
+    cur_fragment_size_field_ = payload_begin;
+    memset(payload_begin, 0, kPacketHeaderSize);
+    payload_begin += kPacketHeaderSize;
+    cur_fragment_start_ = payload_begin;
+  }
+
+  return protozero::ContiguousMemoryRange{payload_begin, cur_chunk_.end()};
+}
+
+void TraceWriterImpl::FinishTracePacket() {
+  // If we hit this, this trace writer was created in a different process. This
+  // likely means that the process forked while tracing was active, and the
+  // forked child process tried to emit a trace event. This is not supported, as
+  // it would lead to two processes writing to the same tracing SMB.
+  PERFETTO_DCHECK(process_id_ == base::GetProcessId());
+
+  FinalizeFragmentIfRequired();
+
+  cur_packet_->Reset(&protobuf_stream_writer_);
+  cur_packet_->Finalize();  // To avoid the CHECK in NewTracePacket().
+
+  // cur_chunk_packet_count_inflated_ can be true if FinishTracePacket() is
+  // called multiple times.
+  if (cur_chunk_.is_valid() && !cur_chunk_packet_count_inflated_) {
+    if (protobuf_stream_writer_.bytes_available() <
+        kExtraRoomForInflatedPacket) {
+      ReturnCompletedChunk();
+    } else {
+      cur_chunk_packet_count_inflated_ = true;
+      cur_chunk_.IncrementPacketCount();
+    }
+  }
+
+  // Send any completed patches to the service to facilitate trace data
+  // recovery by the service. This should only happen when we're completing
+  // the first packet in a chunk which was a continuation from the previous
+  // chunk, i.e. at most once per chunk.
+  if (!patch_list_.empty() && patch_list_.front().is_patched()) {
+    shmem_arbiter_->SendPatches(id_, target_buffer_, &patch_list_);
+  }
+}
+
+void TraceWriterImpl::FinalizeFragmentIfRequired() {
+  if (!cur_fragment_size_field_) {
+    return;
+  }
+  uint8_t* const wptr = protobuf_stream_writer_.write_ptr();
+  PERFETTO_DCHECK(wptr >= cur_fragment_start_);
+  uint32_t partial_size = static_cast<uint32_t>(wptr - cur_fragment_start_);
+
+  // cur_fragment_size_field_, if not nullptr, is always inside or immediately
+  // before protobuf_stream_writer_.cur_range().
+  if (partial_size < protozero::proto_utils::kMaxOneByteMessageLength &&
+      cur_fragment_size_field_ >= protobuf_stream_writer_.cur_range().begin) {
+    // This handles compaction of the root message. For nested messages, the
+    // compaction is handled by protozero::Message::Finalize().
+    protobuf_stream_writer_.Rewind(
+        partial_size, protozero::proto_utils::kMessageLengthFieldSize - 1u);
+    *cur_fragment_size_field_ = static_cast<uint8_t>(partial_size);
+  } else {
+    WriteRedundantVarInt(partial_size, cur_fragment_size_field_);
+  }
+  cur_fragment_size_field_ = nullptr;
+}
+
+uint8_t* TraceWriterImpl::AnnotatePatch(uint8_t* to_patch) {
+  if (!cur_chunk_.is_valid()) {
+    return nullptr;
+  }
+  auto offset = static_cast<uint16_t>(to_patch - cur_chunk_.payload_begin());
+  const ChunkID cur_chunk_id =
+      cur_chunk_.header()->chunk_id.load(std::memory_order_relaxed);
+  static_assert(kPatchSize == sizeof(Patch::PatchContent),
+                "Patch size mismatch");
+  Patch* patch = patch_list_.emplace_back(cur_chunk_id, offset);
+  // Check that the flag is not already set before setting it. This is not
+  // necessary, but it makes the code faster.
+  if (!(cur_chunk_.GetPacketCountAndFlags().second &
+        ChunkHeader::kChunkNeedsPatching)) {
+    cur_chunk_.SetFlag(ChunkHeader::kChunkNeedsPatching);
+  }
+  return &patch->size_field[0];
+}
+
+WriterID TraceWriterImpl::writer_id() const {
+  return id_;
+}
+
+// Base class definitions.
+TraceWriter::TraceWriter() = default;
+TraceWriter::~TraceWriter() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/virtual_destructors.cc
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/consumer.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/observable_events.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
+
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+namespace perfetto {
+
+class TracePacket;
+
+class PERFETTO_EXPORT_COMPONENT Consumer {
+ public:
+  virtual ~Consumer();
+
+  // Called by Service (or more typically by the transport layer, on behalf of
+  // the remote Service), once the Consumer <> Service connection has been
+  // established.
+  virtual void OnConnect() = 0;
+
+  // Called by the Service or by the transport layer if the connection with the
+  // service drops, either voluntarily (e.g., by destroying the ConsumerEndpoint
+  // obtained through Service::ConnectConsumer()) or involuntarily (e.g., if the
+  // Service process crashes).
+  virtual void OnDisconnect() = 0;
+
+  // Called by the Service after the tracing session has ended. This can happen
+  // for a variety of reasons:
+  // - The consumer explicitly called DisableTracing()
+  // - The TraceConfig's |duration_ms| has been reached.
+  // - The TraceConfig's |max_file_size_bytes| has been reached.
+  // - An error occurred while trying to enable tracing. In this case |error|
+  //   is non-empty.
+  virtual void OnTracingDisabled(const std::string& error) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::ReadBuffers(). This function can be
+  // called more than once. Each invocation can carry one or more
+  // TracePacket(s). Upon the last call, |has_more| is set to true (i.e.
+  // |has_more| is a !EOF).
+  virtual void OnTraceData(std::vector<TracePacket>, bool has_more) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::Detach().
+  // The consumer can disconnect at this point and the trace session will keep
+  // on going. A new consumer can later re-attach passing back the same |key|
+  // passed to Detach(), but only if the two requests come from the same uid.
+  virtual void OnDetach(bool success) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::Attach().
+  virtual void OnAttach(bool success, const TraceConfig&) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::GetTraceStats().
+  virtual void OnTraceStats(bool success, const TraceStats&) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::ObserveEvents() whenever one or more
+  // ObservableEvents of enabled event types occur.
+  virtual void OnObservableEvents(const ObservableEvents&) = 0;
+
+  // Called back by the Service (or transport layer) after invoking
+  // TracingService::ConsumerEndpoint::CloneSession().
+  // TODO(primiano): make pure virtual after various 3way patches.
+  struct OnSessionClonedArgs {
+    bool success;
+    std::string error;
+    base::Uuid uuid;  // UUID of the cloned session.
+  };
+  virtual void OnSessionCloned(const OnSessionClonedArgs&);
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/producer.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/flush_flags.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+namespace perfetto {
+
+class SharedMemory;
+
+// A Producer is an entity that connects to the write-only port of the Service
+// and exposes the ability to produce performance data on-demand. The lifecycle
+// of a Producer is as follows:
+// 1. The producer connects to the service and advertises its data sources
+//    (e.g., the ability to get kernel ftraces, to list process stats).
+// 2. The service acknowledges the connection and sends over the SharedMemory
+//    region that will be used to exchange data (together with the signalling
+//    API TracingService::ProducerEndpoint::OnPageAcquired()/OnPageReleased()).
+// 3. At some point later on, the Service asks the Producer to turn on some of
+//    the previously registered data sources, together with some configuration
+//    parameters. This happens via the StartDataSource() callback.
+// 4. In response to that the Producer will spawn an instance of the given data
+//    source and inject its data into the shared memory buffer (obtained during
+//    OnConnect).
+// This interface is subclassed by:
+//  1. The actual producer code in the clients e.g., the ftrace reader process.
+//  2. The transport layer when interposing RPC between service and producers.
+class PERFETTO_EXPORT_COMPONENT Producer {
+ public:
+  virtual ~Producer();
+
+  // Called by Service (or more typically by the transport layer, on behalf of
+  // the remote Service), once the Producer <> Service connection has been
+  // established.
+  virtual void OnConnect() = 0;
+
+  // Called by the Service or by the transport layer if the connection with the
+  // service drops, either voluntarily (e.g., by destroying the ProducerEndpoint
+  // obtained through Service::ConnectProducer()) or involuntarily (e.g., if the
+  // Service process crashes).
+  // The Producer is expected to tear down all its data sources if this happens.
+  // Once this call returns it is possible to safely destroy the Producer
+  // instance.
+  virtual void OnDisconnect() = 0;
+
+  // Called by the Service after OnConnect but before the first DataSource is
+  // created. Can be used for any setup required before tracing begins.
+  virtual void OnTracingSetup() = 0;
+
+  // Called by muxer once StartupTracing is started. It will be called before
+  // SetupStartupTracingBlocking is returned.
+  virtual void OnStartupTracingSetup() {}
+
+  // The lifecycle methods below are always called in the following sequence:
+  // SetupDataSource  -> StartDataSource -> StopDataSource.
+  // Or, in the edge case where a trace is aborted immediately:
+  // SetupDataSource  -> StopDataSource.
+  // The Setup+Start call sequence is always guaranateed, regardless of the
+  // TraceConfig.deferred_start flags.
+  // Called by the Service to configure one of the data sources previously
+  // registered through TracingService::ProducerEndpoint::RegisterDataSource().
+  // This method is always called before StartDataSource. There is always a
+  // SetupDataSource() call before each StartDataSource() call.
+  // Args:
+  // - DataSourceInstanceID is an identifier chosen by the Service that should
+  //   be assigned to the newly created data source instance. It is used to
+  //   match the StopDataSource() request below.
+  // - DataSourceConfig is the configuration for the new data source (e.g.,
+  //   tells which trace categories to enable).
+  virtual void SetupDataSource(DataSourceInstanceID,
+                               const DataSourceConfig&) = 0;
+
+  // Called by the Service to turn on one of the data sources previously
+  // registered through TracingService::ProducerEndpoint::RegisterDataSource()
+  // and initialized through SetupDataSource().
+  // Both arguments are guaranteed to be identical to the ones passed to the
+  // prior SetupDataSource() call.
+  virtual void StartDataSource(DataSourceInstanceID,
+                               const DataSourceConfig&) = 0;
+
+  // Called by the Service to shut down an existing data source instance.
+  virtual void StopDataSource(DataSourceInstanceID) = 0;
+
+  // Called by the service to request the Producer to commit the data of the
+  // given data sources and return their chunks into the shared memory buffer.
+  // The Producer is expected to invoke NotifyFlushComplete(FlushRequestID) on
+  // the Service after the data has been committed. The producer has to either
+  // reply to the flush requests in order, or can just reply to the latest one
+  // Upon seeing a NotifyFlushComplete(N), the service will assume that all
+  // flushes < N have also been committed.
+  virtual void Flush(FlushRequestID,
+                     const DataSourceInstanceID* data_source_ids,
+                     size_t num_data_sources,
+                     FlushFlags) = 0;
+
+  // Called by the service to instruct the given data sources to stop referring
+  // to any trace contents emitted so far. The intent is that after processing
+  // this call, the rest of the trace should be parsable even if all of the
+  // packets emitted so far have been lost (for example due to ring buffer
+  // overwrites).
+  //
+  // Called only for Producers with active data sources that have opted in by
+  // setting |handles_incremental_state_clear| in their DataSourceDescriptor.
+  //
+  // The way this call is handled is up to the individual Producer
+  // implementation. Some might wish to emit invalidation markers in the trace
+  // (see TracePacket.incremental_state_cleared for an existing field), and
+  // handle them when parsing the trace.
+  virtual void ClearIncrementalState(
+      const DataSourceInstanceID* data_source_ids,
+      size_t num_data_sources) = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+// This translation unit contains the definitions for the destructor of pure
+// virtual interfaces for the current build target. The alternative would be
+// introducing a one-liner .cc file for each pure virtual interface, which is
+// overkill. This is for compliance with -Wweak-vtables.
+
+namespace perfetto {
+
+Consumer::~Consumer() = default;
+Producer::~Producer() = default;
+TracingService::~TracingService() = default;
+ConsumerEndpoint::~ConsumerEndpoint() = default;
+ProducerEndpoint::~ProducerEndpoint() = default;
+SharedMemory::~SharedMemory() = default;
+SharedMemory::Factory::~Factory() = default;
+SharedMemoryArbiter::~SharedMemoryArbiter() = default;
+
+// TODO(primiano): make pure virtual after various 3way patches.
+void ConsumerEndpoint::CloneSession(TracingSessionID) {}
+void Consumer::OnSessionCloned(const OnSessionClonedArgs&) {}
+
+void ConsumerEndpoint::Flush(uint32_t, FlushCallback, FlushFlags) {
+  // In the perfetto codebase, this 3-arg Flush is always overridden and this
+  // FATAL is never reached. The only case where this is used is in
+  // arctraceservice's PerfettoClient_test.cpp. That test mocks the old
+  // 2-arg version of Flush but doesn't actually invoke the 3-arg version.
+  PERFETTO_FATAL("ConsumerEndpoint::Flush(3) not implemented");
+}
+
+void ConsumerEndpoint::Flush(uint32_t timeout_ms, FlushCallback callback) {
+  // This 2-arg version of Flush() is invoked by arctraceservice's
+  // PerfettoClient::Flush().
+  Flush(timeout_ms, std::move(callback), FlushFlags(0));
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/console_interceptor.cc
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/console_interceptor.h"
+
+#include <stdarg.h>
+
+#include <algorithm>
+#include <cmath>
+#include <optional>
+#include <tuple>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+namespace perfetto {
+
+// sRGB color.
+struct ConsoleColor {
+  uint8_t r;
+  uint8_t g;
+  uint8_t b;
+};
+
+namespace {
+
+int g_output_fd_for_testing;
+
+// Google Turbo colormap.
+constexpr std::array<ConsoleColor, 16> kTurboColors = {{
+    ConsoleColor{0x30, 0x12, 0x3b},
+    ConsoleColor{0x40, 0x40, 0xa1},
+    ConsoleColor{0x46, 0x6b, 0xe3},
+    ConsoleColor{0x41, 0x93, 0xfe},
+    ConsoleColor{0x28, 0xbb, 0xeb},
+    ConsoleColor{0x17, 0xdc, 0xc2},
+    ConsoleColor{0x32, 0xf1, 0x97},
+    ConsoleColor{0x6d, 0xfd, 0x62},
+    ConsoleColor{0xa4, 0xfc, 0x3b},
+    ConsoleColor{0xcd, 0xeb, 0x34},
+    ConsoleColor{0xed, 0xcf, 0x39},
+    ConsoleColor{0xfd, 0xab, 0x33},
+    ConsoleColor{0xfa, 0x7d, 0x20},
+    ConsoleColor{0xea, 0x50, 0x0d},
+    ConsoleColor{0xd0, 0x2f, 0x04},
+    ConsoleColor{0xa9, 0x15, 0x01},
+}};
+
+constexpr size_t kHueBits = 4;
+constexpr uint32_t kMaxHue = kTurboColors.size() << kHueBits;
+constexpr uint8_t kLightness = 128u;
+constexpr ConsoleColor kWhiteColor{0xff, 0xff, 0xff};
+
+const char kDim[] = "\x1b[90m";
+const char kDefault[] = "\x1b[39m";
+const char kReset[] = "\x1b[0m";
+
+#define FMT_RGB_SET "\x1b[38;2;%d;%d;%dm"
+#define FMT_RGB_SET_BG "\x1b[48;2;%d;%d;%dm"
+
+ConsoleColor Mix(ConsoleColor a, ConsoleColor b, uint8_t ratio) {
+  return {
+      static_cast<uint8_t>(a.r + (((b.r - a.r) * ratio) >> 8)),
+      static_cast<uint8_t>(a.g + (((b.g - a.g) * ratio) >> 8)),
+      static_cast<uint8_t>(a.b + (((b.b - a.b) * ratio) >> 8)),
+  };
+}
+
+ConsoleColor HueToRGB(uint32_t hue) {
+  PERFETTO_DCHECK(hue < kMaxHue);
+  uint32_t c1 = hue >> kHueBits;
+  uint32_t c2 =
+      std::min(static_cast<uint32_t>(kTurboColors.size() - 1), c1 + 1u);
+  uint32_t ratio = hue & ((1 << kHueBits) - 1);
+  return Mix(kTurboColors[c1], kTurboColors[c2],
+             static_cast<uint8_t>(ratio | (ratio << kHueBits)));
+}
+
+uint32_t CounterToHue(uint32_t counter) {
+  // We split the hue space into 8 segments, reversing the order of bits so
+  // successive counter values will be far from each other.
+  uint32_t reversed =
+      ((counter & 0x7) >> 2) | ((counter & 0x3)) | ((counter & 0x1) << 2);
+  return reversed * kMaxHue / 8;
+}
+
+}  // namespace
+
+class ConsoleInterceptor::Delegate : public TrackEventStateTracker::Delegate {
+ public:
+  explicit Delegate(InterceptorContext&);
+  ~Delegate() override;
+
+  TrackEventStateTracker::SessionState* GetSessionState() override;
+  void OnTrackUpdated(TrackEventStateTracker::Track&) override;
+  void OnTrackEvent(const TrackEventStateTracker::Track&,
+                    const TrackEventStateTracker::ParsedTrackEvent&) override;
+
+ private:
+  using SelfHandle = LockedHandle<ConsoleInterceptor>;
+
+  InterceptorContext& context_;
+  std::optional<SelfHandle> locked_self_;
+};
+
+ConsoleInterceptor::~ConsoleInterceptor() = default;
+
+ConsoleInterceptor::ThreadLocalState::ThreadLocalState(
+    ThreadLocalStateArgs& args) {
+  if (auto self = args.GetInterceptorLocked()) {
+    start_time_ns = self->start_time_ns_;
+    use_colors = self->use_colors_;
+    fd = self->fd_;
+  }
+}
+
+ConsoleInterceptor::ThreadLocalState::~ThreadLocalState() = default;
+
+ConsoleInterceptor::Delegate::Delegate(InterceptorContext& context)
+    : context_(context) {}
+ConsoleInterceptor::Delegate::~Delegate() = default;
+
+TrackEventStateTracker::SessionState*
+ConsoleInterceptor::Delegate::GetSessionState() {
+  // When the session state is retrieved for the first time, it is cached (and
+  // kept locked) until we return from OnTracePacket. This avoids having to lock
+  // and unlock the instance multiple times per invocation.
+  if (locked_self_.has_value())
+    return &locked_self_.value()->session_state_;
+  locked_self_ =
+      std::make_optional<SelfHandle>(context_.GetInterceptorLocked());
+  return &locked_self_.value()->session_state_;
+}
+
+void ConsoleInterceptor::Delegate::OnTrackUpdated(
+    TrackEventStateTracker::Track& track) {
+  auto track_color = HueToRGB(CounterToHue(track.index));
+  std::array<char, 16> title;
+  if (!track.name.empty()) {
+    snprintf(title.data(), title.size(), "%s", track.name.c_str());
+  } else if (track.pid && track.tid) {
+    snprintf(title.data(), title.size(), "%u:%u",
+             static_cast<uint32_t>(track.pid),
+             static_cast<uint32_t>(track.tid));
+  } else if (track.pid) {
+    snprintf(title.data(), title.size(), "%" PRId64, track.pid);
+  } else {
+    snprintf(title.data(), title.size(), "%" PRIu64, track.uuid);
+  }
+  int title_width = static_cast<int>(title.size());
+
+  auto& tls = context_.GetThreadLocalState();
+  std::array<char, 128> message_prefix{};
+  size_t written = 0;
+  if (tls.use_colors) {
+    written = base::SprintfTrunc(message_prefix.data(), message_prefix.size(),
+                                 FMT_RGB_SET_BG " %s%s %-*.*s", track_color.r,
+                                 track_color.g, track_color.b, kReset, kDim,
+                                 title_width, title_width, title.data());
+  } else {
+    written = base::SprintfTrunc(message_prefix.data(), message_prefix.size(),
+                                 "%-*.*s", title_width + 2, title_width,
+                                 title.data());
+  }
+  track.user_data.assign(
+      message_prefix.begin(),
+      message_prefix.begin() + static_cast<ssize_t>(written));
+}
+
+void ConsoleInterceptor::Delegate::OnTrackEvent(
+    const TrackEventStateTracker::Track& track,
+    const TrackEventStateTracker::ParsedTrackEvent& event) {
+  // Start printing.
+  auto& tls = context_.GetThreadLocalState();
+  tls.buffer_pos = 0;
+
+  // Print timestamp and track identifier.
+  SetColor(context_, kDim);
+  Printf(context_, "[%7.3lf] %.*s",
+         static_cast<double>(event.timestamp_ns - tls.start_time_ns) / 1e9,
+         static_cast<int>(track.user_data.size()), track.user_data.data());
+
+  // Print category.
+  Printf(context_, "%-5.*s ",
+         std::min(5, static_cast<int>(event.category.size)),
+         event.category.data);
+
+  // Print stack depth.
+  for (size_t i = 0; i < event.stack_depth; i++) {
+    Printf(context_, "-  ");
+  }
+
+  // Print slice name.
+  auto slice_color = HueToRGB(event.name_hash % kMaxHue);
+  auto highlight_color = Mix(slice_color, kWhiteColor, kLightness);
+  if (event.track_event.type() == protos::pbzero::TrackEvent::TYPE_SLICE_END) {
+    SetColor(context_, kDefault);
+    Printf(context_, "} ");
+  }
+  SetColor(context_, highlight_color);
+  Printf(context_, "%.*s", static_cast<int>(event.name.size), event.name.data);
+  SetColor(context_, kReset);
+  if (event.track_event.type() ==
+      protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN) {
+    SetColor(context_, kDefault);
+    Printf(context_, " {");
+  }
+
+  // Print annotations.
+  if (event.track_event.has_debug_annotations()) {
+    PrintDebugAnnotations(context_, event.track_event, slice_color,
+                          highlight_color);
+  }
+
+  // TODO(skyostil): Print typed arguments.
+
+  // Print duration for longer events.
+  constexpr uint64_t kNsPerMillisecond = 1000000u;
+  if (event.duration_ns >= 10 * kNsPerMillisecond) {
+    SetColor(context_, kDim);
+    Printf(context_, " +%" PRIu64 "ms", event.duration_ns / kNsPerMillisecond);
+  }
+  SetColor(context_, kReset);
+  Printf(context_, "\n");
+}
+
+// static
+void ConsoleInterceptor::Register() {
+  perfetto::protos::gen::InterceptorDescriptor desc;
+  desc.set_name("console");
+  Interceptor<ConsoleInterceptor>::Register(desc);
+}
+
+// static
+void ConsoleInterceptor::SetOutputFdForTesting(int fd) {
+  g_output_fd_for_testing = fd;
+}
+
+void ConsoleInterceptor::OnSetup(const SetupArgs& args) {
+  int fd = STDOUT_FILENO;
+  if (g_output_fd_for_testing)
+    fd = g_output_fd_for_testing;
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+  bool use_colors = isatty(fd);
+#else
+  bool use_colors = false;
+#endif
+  const protos::gen::ConsoleConfig& config =
+      args.config.interceptor_config().console_config();
+  if (config.has_enable_colors())
+    use_colors = config.enable_colors();
+  if (config.output() == protos::gen::ConsoleConfig::OUTPUT_STDOUT) {
+    fd = STDOUT_FILENO;
+  } else if (config.output() == protos::gen::ConsoleConfig::OUTPUT_STDERR) {
+    fd = STDERR_FILENO;
+  }
+  fd_ = fd;
+  use_colors_ = use_colors;
+}
+
+void ConsoleInterceptor::OnStart(const StartArgs&) {
+  start_time_ns_ = internal::TrackEventInternal::GetTimeNs();
+}
+
+void ConsoleInterceptor::OnStop(const StopArgs&) {}
+
+// static
+void ConsoleInterceptor::OnTracePacket(InterceptorContext context) {
+  {
+    auto& tls = context.GetThreadLocalState();
+    Delegate delegate(context);
+    perfetto::protos::pbzero::TracePacket::Decoder packet(
+        context.packet_data.data, context.packet_data.size);
+    TrackEventStateTracker::ProcessTracePacket(delegate, tls.sequence_state,
+                                               packet);
+  }  // (Potential) lock scope for session state.
+  Flush(context);
+}
+
+// static
+void ConsoleInterceptor::Printf(InterceptorContext& context,
+                                const char* format,
+                                ...) {
+  auto& tls = context.GetThreadLocalState();
+  ssize_t remaining = static_cast<ssize_t>(tls.message_buffer.size()) -
+                      static_cast<ssize_t>(tls.buffer_pos);
+  int written = 0;
+  if (remaining > 0) {
+    va_list args;
+    va_start(args, format);
+    written = vsnprintf(&tls.message_buffer[tls.buffer_pos],
+                        static_cast<size_t>(remaining), format, args);
+    PERFETTO_DCHECK(written >= 0);
+    va_end(args);
+  }
+
+  // In case of buffer overflow, flush to the fd and write the latest message to
+  // it directly instead.
+  if (remaining <= 0 || written > remaining) {
+    FILE* output = (tls.fd == STDOUT_FILENO) ? stdout : stderr;
+    if (g_output_fd_for_testing) {
+      output = fdopen(dup(g_output_fd_for_testing), "w");
+    }
+    Flush(context);
+    va_list args;
+    va_start(args, format);
+    vfprintf(output, format, args);
+    va_end(args);
+    if (g_output_fd_for_testing) {
+      fclose(output);
+    }
+  } else if (written > 0) {
+    tls.buffer_pos += static_cast<size_t>(written);
+  }
+}
+
+// static
+void ConsoleInterceptor::Flush(InterceptorContext& context) {
+  auto& tls = context.GetThreadLocalState();
+  ssize_t res = base::WriteAll(tls.fd, &tls.message_buffer[0], tls.buffer_pos);
+  PERFETTO_DCHECK(res == static_cast<ssize_t>(tls.buffer_pos));
+  tls.buffer_pos = 0;
+}
+
+// static
+void ConsoleInterceptor::SetColor(InterceptorContext& context,
+                                  const ConsoleColor& color) {
+  auto& tls = context.GetThreadLocalState();
+  if (!tls.use_colors)
+    return;
+  Printf(context, FMT_RGB_SET, color.r, color.g, color.b);
+}
+
+// static
+void ConsoleInterceptor::SetColor(InterceptorContext& context,
+                                  const char* color) {
+  auto& tls = context.GetThreadLocalState();
+  if (!tls.use_colors)
+    return;
+  Printf(context, "%s", color);
+}
+
+// static
+void ConsoleInterceptor::PrintDebugAnnotations(
+    InterceptorContext& context,
+    const protos::pbzero::TrackEvent_Decoder& track_event,
+    const ConsoleColor& slice_color,
+    const ConsoleColor& highlight_color) {
+  SetColor(context, slice_color);
+  Printf(context, "(");
+
+  bool is_first = true;
+  for (auto it = track_event.debug_annotations(); it; it++) {
+    perfetto::protos::pbzero::DebugAnnotation::Decoder annotation(*it);
+    SetColor(context, slice_color);
+    if (!is_first)
+      Printf(context, ", ");
+
+    PrintDebugAnnotationName(context, annotation);
+    Printf(context, ":");
+
+    SetColor(context, highlight_color);
+    PrintDebugAnnotationValue(context, annotation);
+
+    is_first = false;
+  }
+  SetColor(context, slice_color);
+  Printf(context, ")");
+}
+
+// static
+void ConsoleInterceptor::PrintDebugAnnotationName(
+    InterceptorContext& context,
+    const perfetto::protos::pbzero::DebugAnnotation::Decoder& annotation) {
+  auto& tls = context.GetThreadLocalState();
+  protozero::ConstChars name{};
+  if (annotation.name_iid()) {
+    name.data =
+        tls.sequence_state.debug_annotation_names[annotation.name_iid()].data();
+    name.size =
+        tls.sequence_state.debug_annotation_names[annotation.name_iid()].size();
+  } else if (annotation.has_name()) {
+    name.data = annotation.name().data;
+    name.size = annotation.name().size;
+  }
+  Printf(context, "%.*s", static_cast<int>(name.size), name.data);
+}
+
+// static
+void ConsoleInterceptor::PrintDebugAnnotationValue(
+    InterceptorContext& context,
+    const perfetto::protos::pbzero::DebugAnnotation::Decoder& annotation) {
+  if (annotation.has_bool_value()) {
+    Printf(context, "%s", annotation.bool_value() ? "true" : "false");
+  } else if (annotation.has_uint_value()) {
+    Printf(context, "%" PRIu64, annotation.uint_value());
+  } else if (annotation.has_int_value()) {
+    Printf(context, "%" PRId64, annotation.int_value());
+  } else if (annotation.has_double_value()) {
+    Printf(context, "%f", annotation.double_value());
+  } else if (annotation.has_string_value()) {
+    Printf(context, "%.*s", static_cast<int>(annotation.string_value().size),
+           annotation.string_value().data);
+  } else if (annotation.has_pointer_value()) {
+    Printf(context, "%p", reinterpret_cast<void*>(annotation.pointer_value()));
+  } else if (annotation.has_legacy_json_value()) {
+    Printf(context, "%.*s",
+           static_cast<int>(annotation.legacy_json_value().size),
+           annotation.legacy_json_value().data);
+  } else if (annotation.has_dict_entries()) {
+    Printf(context, "{");
+    bool is_first = true;
+    for (auto it = annotation.dict_entries(); it; ++it) {
+      if (!is_first)
+        Printf(context, ", ");
+      perfetto::protos::pbzero::DebugAnnotation::Decoder key_value(*it);
+      PrintDebugAnnotationName(context, key_value);
+      Printf(context, ":");
+      PrintDebugAnnotationValue(context, key_value);
+      is_first = false;
+    }
+    Printf(context, "}");
+  } else if (annotation.has_array_values()) {
+    Printf(context, "[");
+    bool is_first = true;
+    for (auto it = annotation.array_values(); it; ++it) {
+      if (!is_first)
+        Printf(context, ", ");
+      perfetto::protos::pbzero::DebugAnnotation::Decoder key_value(*it);
+      PrintDebugAnnotationValue(context, key_value);
+      is_first = false;
+    }
+    Printf(context, "]");
+  } else {
+    Printf(context, "{}");
+  }
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/data_source.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+
+namespace perfetto {
+
+DataSourceBase::StopArgs::~StopArgs() = default;
+DataSourceBase::FlushArgs::~FlushArgs() = default;
+DataSourceBase::~DataSourceBase() = default;
+void DataSourceBase::OnSetup(const SetupArgs&) {}
+void DataSourceBase::OnStart(const StartArgs&) {}
+void DataSourceBase::OnStop(const StopArgs&) {}
+void DataSourceBase::WillClearIncrementalState(
+    const ClearIncrementalStateArgs&) {}
+void DataSourceBase::OnFlush(const FlushArgs&) {}
+
+bool DataSourceBase::CanAdoptStartupSession(
+    const DataSourceConfig& startup_config,
+    const DataSourceConfig& service_config) {
+  // Clear target buffer and tracing-service provided fields for comparison of
+  // configs for startup tracing, since these fields are not available when
+  // setting up data sources for startup tracing.
+  DataSourceConfig startup_config_stripped = startup_config;
+  DataSourceConfig service_config_stripped = service_config;
+
+  startup_config_stripped.set_target_buffer(0);
+  startup_config_stripped.set_tracing_session_id(0);
+  startup_config_stripped.set_session_initiator(
+      DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
+  startup_config_stripped.set_trace_duration_ms(0);
+  startup_config_stripped.set_stop_timeout_ms(0);
+  startup_config_stripped.set_enable_extra_guardrails(false);
+
+  service_config_stripped.set_target_buffer(0);
+  service_config_stripped.set_tracing_session_id(0);
+  service_config_stripped.set_session_initiator(
+      DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
+  service_config_stripped.set_trace_duration_ms(0);
+  service_config_stripped.set_stop_timeout_ms(0);
+  service_config_stripped.set_enable_extra_guardrails(false);
+
+  return startup_config_stripped == service_config_stripped;
+}
+
+namespace internal {
+
+void DataSourceType::PopulateTlsInst(
+    DataSourceInstanceThreadLocalState* tls_inst,
+    DataSourceState* instance_state,
+    uint32_t instance_index) {
+  auto* tracing_impl = TracingMuxer::Get();
+  tls_inst->muxer_id_for_testing = instance_state->muxer_id_for_testing;
+  tls_inst->backend_id = instance_state->backend_id;
+  tls_inst->backend_connection_id = instance_state->backend_connection_id;
+  tls_inst->buffer_id = instance_state->buffer_id;
+  tls_inst->startup_target_buffer_reservation =
+      instance_state->startup_target_buffer_reservation.load(
+          std::memory_order_relaxed);
+  tls_inst->data_source_instance_id = instance_state->data_source_instance_id;
+  tls_inst->is_intercepted = instance_state->interceptor_id != 0;
+  tls_inst->trace_writer = tracing_impl->CreateTraceWriter(
+      &state_, instance_index, instance_state, buffer_exhausted_policy_);
+  if (create_incremental_state_fn_) {
+    PERFETTO_DCHECK(!tls_inst->incremental_state);
+    CreateIncrementalState(tls_inst, instance_index);
+  }
+  if (create_custom_tls_fn_) {
+    tls_inst->data_source_custom_tls =
+        create_custom_tls_fn_(tls_inst, instance_index, user_arg_);
+  }
+  // Even in the case of out-of-IDs, SharedMemoryArbiterImpl returns a
+  // NullTraceWriter. The returned pointer should never be null.
+  PERFETTO_DCHECK(tls_inst->trace_writer);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/debug_annotation.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
+
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+
+namespace perfetto {
+
+DebugAnnotation::~DebugAnnotation() = default;
+
+void DebugAnnotation::WriteIntoTracedValue(TracedValue context) const {
+  Add(context.annotation_);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/event_context.cc
+// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_interned_fields.h
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
+
+namespace perfetto {
+namespace internal {
+
+// These helpers are exposed here to allow Chromium-without-client library
+// to share the interning buffers with Perfetto internals (e.g.
+// perfetto::TracedValue implementation).
+
+struct PERFETTO_EXPORT_COMPONENT InternedEventCategory
+    : public TrackEventInternedDataIndex<
+          InternedEventCategory,
+          perfetto::protos::pbzero::InternedData::kEventCategoriesFieldNumber,
+          const char*,
+          SmallInternedDataTraits> {
+  ~InternedEventCategory() override;
+
+  static void Add(protos::pbzero::InternedData* interned_data,
+                  size_t iid,
+                  const char* value,
+                  size_t length);
+};
+
+struct PERFETTO_EXPORT_COMPONENT InternedEventName
+    : public TrackEventInternedDataIndex<
+          InternedEventName,
+          perfetto::protos::pbzero::InternedData::kEventNamesFieldNumber,
+          const char*,
+          SmallInternedDataTraits> {
+  ~InternedEventName() override;
+
+  static void Add(protos::pbzero::InternedData* interned_data,
+                  size_t iid,
+                  const char* value);
+};
+
+struct PERFETTO_EXPORT_COMPONENT InternedDebugAnnotationName
+    : public TrackEventInternedDataIndex<
+          InternedDebugAnnotationName,
+          perfetto::protos::pbzero::InternedData::
+              kDebugAnnotationNamesFieldNumber,
+          const char*,
+          SmallInternedDataTraits> {
+  ~InternedDebugAnnotationName() override;
+
+  static void Add(protos::pbzero::InternedData* interned_data,
+                  size_t iid,
+                  const char* value);
+};
+
+struct PERFETTO_EXPORT_COMPONENT InternedDebugAnnotationValueTypeName
+    : public TrackEventInternedDataIndex<
+          InternedDebugAnnotationValueTypeName,
+          perfetto::protos::pbzero::InternedData::
+              kDebugAnnotationValueTypeNamesFieldNumber,
+          const char*,
+          SmallInternedDataTraits> {
+  ~InternedDebugAnnotationValueTypeName() override;
+
+  static void Add(protos::pbzero::InternedData* interned_data,
+                  size_t iid,
+                  const char* value);
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+namespace perfetto {
+
+EventContext::EventContext(
+    TraceWriterBase* trace_writer,
+    EventContext::TracePacketHandle trace_packet,
+    internal::TrackEventIncrementalState* incremental_state,
+    internal::TrackEventTlsState* tls_state)
+    : trace_writer_(trace_writer),
+      trace_packet_(std::move(trace_packet)),
+      event_(trace_packet_->set_track_event()),
+      incremental_state_(incremental_state),
+      tls_state_(tls_state) {}
+
+EventContext::~EventContext() {
+  if (!trace_packet_)
+    return;
+
+  // When the track event is finalized (i.e., the context is destroyed), we
+  // should flush any newly seen interned data to the trace. The data has
+  // earlier been written to a heap allocated protobuf message
+  // (|serialized_interned_data|). Here we just need to flush it to the main
+  // trace.
+  auto& serialized_interned_data = incremental_state_->serialized_interned_data;
+  if (PERFETTO_UNLIKELY(!serialized_interned_data.empty())) {
+    auto ranges = serialized_interned_data.GetRanges();
+    trace_packet_->AppendScatteredBytes(
+        perfetto::protos::pbzero::TracePacket::kInternedDataFieldNumber,
+        &ranges[0], ranges.size());
+
+    // Reset the message but keep one buffer allocated for future use.
+    serialized_interned_data.Reset();
+  }
+
+  trace_packet_ = TracePacketHandle();
+  // Make sure that the packet we just wrote is immediately visible in the
+  // shared memory buffer.
+  // TODO(b/162206162): Remove this when TracePacketHandle destruction calls
+  // FinishTracePacket automatically.
+  if (trace_writer_) {
+    trace_writer_->FinishTracePacket();
+  }
+}
+
+protos::pbzero::DebugAnnotation* EventContext::AddDebugAnnotation(
+    const char* name) {
+  auto annotation = event()->add_debug_annotations();
+  annotation->set_name_iid(
+      internal::InternedDebugAnnotationName::Get(this, name));
+  return annotation;
+}
+
+protos::pbzero::DebugAnnotation* EventContext::AddDebugAnnotation(
+    ::perfetto::DynamicString name) {
+  auto annotation = event()->add_debug_annotations();
+  annotation->set_name(name.value);
+  return annotation;
+}
+
+TrackEventTlsStateUserData* EventContext::GetTlsUserData(const void* key) {
+  PERFETTO_CHECK(tls_state_);
+  PERFETTO_CHECK(key);
+  auto it = tls_state_->user_data.find(key);
+  if (it != tls_state_->user_data.end()) {
+    return it->second.get();
+  }
+  return nullptr;
+}
+
+void EventContext::SetTlsUserData(
+    const void* key,
+    std::unique_ptr<TrackEventTlsStateUserData> data) {
+  PERFETTO_CHECK(tls_state_);
+  PERFETTO_CHECK(key);
+  tls_state_->user_data[key] = std::move(data);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/interceptor.cc
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+
+namespace perfetto {
+
+InterceptorBase::~InterceptorBase() = default;
+InterceptorBase::ThreadLocalState::~ThreadLocalState() = default;
+
+// static
+void InterceptorBase::RegisterImpl(
+    const InterceptorDescriptor& descriptor,
+    std::function<std::unique_ptr<InterceptorBase>()> factory,
+    InterceptorBase::TLSFactory tls_factory,
+    InterceptorBase::TracePacketCallback on_trace_packet) {
+  auto* tracing_impl = internal::TracingMuxer::Get();
+  tracing_impl->RegisterInterceptor(descriptor, factory, tls_factory,
+                                    on_trace_packet);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/checked_scope.cc
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/checked_scope.h"
+
+#include <utility>
+
+namespace perfetto {
+namespace internal {
+
+#if PERFETTO_DCHECK_IS_ON()
+CheckedScope::CheckedScope(CheckedScope* parent_scope)
+    : parent_scope_(parent_scope) {
+  if (parent_scope_) {
+    PERFETTO_DCHECK(parent_scope_->is_active());
+    parent_scope_->set_is_active(false);
+  }
+}
+
+CheckedScope::~CheckedScope() {
+  Reset();
+}
+
+void CheckedScope::Reset() {
+  if (!is_active_) {
+    // The only case when inactive scope could be destroyed is when Reset() was
+    // called explicitly or the contents of the object were moved away.
+    PERFETTO_DCHECK(deleted_);
+    return;
+  }
+  is_active_ = false;
+  deleted_ = true;
+  if (parent_scope_)
+    parent_scope_->set_is_active(true);
+}
+
+CheckedScope::CheckedScope(CheckedScope&& other) {
+  *this = std::move(other);
+}
+
+CheckedScope& CheckedScope::operator=(CheckedScope&& other) {
+  is_active_ = other.is_active_;
+  parent_scope_ = other.parent_scope_;
+  deleted_ = other.deleted_;
+
+  other.is_active_ = false;
+  other.parent_scope_ = nullptr;
+  other.deleted_ = true;
+
+  return *this;
+}
+#endif
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/interceptor_trace_writer.cc
+// gen_amalgamated begin header: include/perfetto/tracing/internal/interceptor_trace_writer.h
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
+
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace internal {
+
+// A heap-backed trace writer used to reroute trace packets to an interceptor.
+class InterceptorTraceWriter : public TraceWriterBase {
+ public:
+  InterceptorTraceWriter(std::unique_ptr<InterceptorBase::ThreadLocalState> tls,
+                         InterceptorBase::TracePacketCallback packet_callback,
+                         DataSourceStaticState* static_state,
+                         uint32_t instance_index);
+  ~InterceptorTraceWriter() override;
+
+  // TraceWriterBase implementation.
+  protozero::MessageHandle<protos::pbzero::TracePacket> NewTracePacket()
+      override;
+  void FinishTracePacket() override;
+  void Flush(std::function<void()> callback = {}) override;
+  uint64_t written() const override;
+
+ private:
+  std::unique_ptr<InterceptorBase::ThreadLocalState> tls_;
+  InterceptorBase::TracePacketCallback packet_callback_;
+
+  protozero::HeapBuffered<protos::pbzero::TracePacket> cur_packet_;
+  uint64_t bytes_written_ = 0;
+
+  // Static state of the data source we are intercepting.
+  DataSourceStaticState* const static_state_;
+
+  // Index of the data source tracing session which we are intercepting
+  // (0...kMaxDataSourceInstances - 1). Used to look up this interceptor's
+  // session state (i.e., the Interceptor class instance) in the
+  // DataSourceStaticState::instances array.
+  const uint32_t instance_index_;
+
+  const uint32_t sequence_id_;
+
+  static std::atomic<uint32_t> next_sequence_id_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/interceptor_trace_writer.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+
+namespace perfetto {
+namespace internal {
+
+// static
+std::atomic<uint32_t> InterceptorTraceWriter::next_sequence_id_{};
+
+InterceptorTraceWriter::InterceptorTraceWriter(
+    std::unique_ptr<InterceptorBase::ThreadLocalState> tls,
+    InterceptorBase::TracePacketCallback packet_callback,
+    DataSourceStaticState* static_state,
+    uint32_t instance_index)
+    : tls_(std::move(tls)),
+      packet_callback_(std::move(packet_callback)),
+      static_state_(static_state),
+      instance_index_(instance_index),
+      sequence_id_(++next_sequence_id_) {}
+
+InterceptorTraceWriter::~InterceptorTraceWriter() = default;
+
+protozero::MessageHandle<protos::pbzero::TracePacket>
+InterceptorTraceWriter::NewTracePacket() {
+  Flush();
+  auto packet = TraceWriter::TracePacketHandle(cur_packet_.get());
+  packet->set_trusted_packet_sequence_id(sequence_id_);
+  return packet;
+}
+
+void InterceptorTraceWriter::Flush(std::function<void()> callback) {
+  if (!cur_packet_.empty()) {
+    InterceptorBase::TracePacketCallbackArgs args{};
+    args.static_state = static_state_;
+    args.instance_index = instance_index_;
+    args.tls = tls_.get();
+
+    const auto& slices = cur_packet_.GetSlices();
+    if (slices.size() == 1) {
+      // Fast path: the current packet fits into a single slice.
+      auto slice_range = slices.begin()->GetUsedRange();
+      args.packet_data = protozero::ConstBytes{
+          slice_range.begin,
+          static_cast<size_t>(slice_range.end - slice_range.begin)};
+      bytes_written_ += static_cast<uint64_t>(args.packet_data.size);
+      packet_callback_(std::move(args));
+    } else {
+      // Fallback: stitch together multiple slices.
+      auto stitched_data = cur_packet_.SerializeAsArray();
+      args.packet_data =
+          protozero::ConstBytes{stitched_data.data(), stitched_data.size()};
+      bytes_written_ += static_cast<uint64_t>(stitched_data.size());
+      packet_callback_(std::move(args));
+    }
+    cur_packet_.Reset();
+  }
+  if (callback)
+    callback();
+}
+
+void InterceptorTraceWriter::FinishTracePacket() {}
+
+uint64_t InterceptorTraceWriter::written() const {
+  return bytes_written_;
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/tracing_backend_fake.cc
+// gen_amalgamated begin header: include/perfetto/tracing/internal/tracing_backend_fake.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+
+namespace perfetto {
+namespace internal {
+
+// A built-in implementation of TracingBackend that fails any attempt to create
+// a tracing session.
+class PERFETTO_EXPORT_COMPONENT TracingBackendFake : public TracingBackend {
+ public:
+  static TracingBackend* GetInstance();
+
+  // TracingBackend implementation.
+  std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      const ConnectProducerArgs&) override;
+  std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
+      const ConnectConsumerArgs&) override;
+
+ private:
+  TracingBackendFake();
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_backend_fake.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+namespace perfetto {
+namespace internal {
+
+namespace {
+
+class UnsupportedProducerEndpoint : public ProducerEndpoint {
+ public:
+  UnsupportedProducerEndpoint(Producer* producer, base::TaskRunner* task_runner)
+      : producer_(producer), task_runner_(task_runner) {
+    // The SDK will attempt to reconnect the producer, so instead we allow it
+    // to connect successfully, but never start any sessions.
+    auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostTask([weak_ptr] {
+      if (weak_ptr && weak_ptr->connected_)
+        weak_ptr->producer_->OnConnect();
+    });
+  }
+  ~UnsupportedProducerEndpoint() override { Disconnect(); }
+
+  void Disconnect() override {
+    if (!connected_)
+      return;
+    connected_ = false;
+    producer_->OnDisconnect();
+  }
+
+  void RegisterDataSource(const DataSourceDescriptor&) override {}
+  void UpdateDataSource(const DataSourceDescriptor&) override {}
+  void UnregisterDataSource(const std::string& /*name*/) override {}
+
+  void RegisterTraceWriter(uint32_t /*writer_id*/,
+                           uint32_t /*target_buffer*/) override {}
+  void UnregisterTraceWriter(uint32_t /*writer_id*/) override {}
+
+  void CommitData(const CommitDataRequest&,
+                  CommitDataCallback callback) override {
+    if (connected_) {
+      callback();
+    }
+  }
+
+  SharedMemory* shared_memory() const override { return nullptr; }
+  size_t shared_buffer_page_size_kb() const override { return 0; }
+
+  std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID /*target_buffer*/,
+      BufferExhaustedPolicy) override {
+    return nullptr;
+  }
+
+  SharedMemoryArbiter* MaybeSharedMemoryArbiter() override { return nullptr; }
+  bool IsShmemProvidedByProducer() const override { return false; }
+
+  void NotifyFlushComplete(FlushRequestID) override {}
+  void NotifyDataSourceStarted(DataSourceInstanceID) override {}
+  void NotifyDataSourceStopped(DataSourceInstanceID) override {}
+  void ActivateTriggers(const std::vector<std::string>&) override {}
+
+  void Sync(std::function<void()> callback) override {
+    if (connected_) {
+      callback();
+    }
+  }
+
+ private:
+  Producer* const producer_;
+  base::TaskRunner* const task_runner_;
+  bool connected_ = true;
+  base::WeakPtrFactory<UnsupportedProducerEndpoint> weak_ptr_factory_{
+      this};  // Keep last.
+};
+
+class UnsupportedConsumerEndpoint : public ConsumerEndpoint {
+ public:
+  UnsupportedConsumerEndpoint(Consumer* consumer, base::TaskRunner* task_runner)
+      : consumer_(consumer), task_runner_(task_runner) {
+    // The SDK will not to reconnect the consumer, so we just disconnect it
+    // immediately, which will cancel the tracing session.
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostTask([weak_this] {
+      if (weak_this)
+        weak_this->consumer_->OnDisconnect();
+    });
+  }
+  ~UnsupportedConsumerEndpoint() override = default;
+
+  void EnableTracing(const TraceConfig&, base::ScopedFile) override {}
+  void ChangeTraceConfig(const TraceConfig&) override {}
+
+  void StartTracing() override {}
+  void DisableTracing() override {}
+
+  void Flush(uint32_t /*timeout_ms*/,
+             FlushCallback callback,
+             FlushFlags) override {
+    callback(/*success=*/false);
+  }
+
+  void ReadBuffers() override {}
+  void FreeBuffers() override {}
+
+  void Detach(const std::string& /*key*/) override {}
+  void Attach(const std::string& /*key*/) override {}
+
+  void GetTraceStats() override {}
+  void ObserveEvents(uint32_t /*events_mask*/) override {}
+  void QueryServiceState(QueryServiceStateCallback) override {}
+  void QueryCapabilities(QueryCapabilitiesCallback) override {}
+
+  void SaveTraceForBugreport(SaveTraceForBugreportCallback) override {}
+  void CloneSession(TracingSessionID) override {}
+
+ private:
+  Consumer* const consumer_;
+  base::TaskRunner* const task_runner_;
+  base::WeakPtrFactory<UnsupportedConsumerEndpoint> weak_ptr_factory_{
+      this};  // Keep last.
+};
+
+}  // namespace
+
+// static
+TracingBackend* TracingBackendFake::GetInstance() {
+  static auto* instance = new TracingBackendFake();
+  return instance;
+}
+
+TracingBackendFake::TracingBackendFake() = default;
+
+std::unique_ptr<ProducerEndpoint> TracingBackendFake::ConnectProducer(
+    const ConnectProducerArgs& args) {
+  return std::unique_ptr<ProducerEndpoint>(
+      new UnsupportedProducerEndpoint(args.producer, args.task_runner));
+}
+
+std::unique_ptr<ConsumerEndpoint> TracingBackendFake::ConnectConsumer(
+    const ConnectConsumerArgs& args) {
+  return std::unique_ptr<ConsumerEndpoint>(
+      new UnsupportedConsumerEndpoint(args.consumer, args.task_runner));
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/tracing_muxer_fake.cc
+// gen_amalgamated begin header: src/tracing/internal/tracing_muxer_fake.h
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
+#define SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+
+namespace perfetto {
+namespace internal {
+
+// An always-fail implementation of TracingMuxer. Before tracing has been
+// initialiazed, all muxer operations will route here and fail with a helpful
+// error message. This is to avoid introducing null checks in
+// performance-critical parts of the codebase.
+class TracingMuxerFake : public TracingMuxer {
+  class FakePlatform : public Platform {
+   public:
+    ~FakePlatform() override;
+    ThreadLocalObject* GetOrCreateThreadLocalObject() override;
+    std::unique_ptr<base::TaskRunner> CreateTaskRunner(
+        const CreateTaskRunnerArgs&) override;
+    std::string GetCurrentProcessName() override;
+
+    static FakePlatform instance;
+  };
+
+ public:
+  TracingMuxerFake() : TracingMuxer(&FakePlatform::instance) {}
+  ~TracingMuxerFake() override;
+
+  static constexpr TracingMuxerFake* Get() {
+#if PERFETTO_HAS_NO_DESTROY()
+    return &instance;
+#else
+    return nullptr;
+#endif
+  }
+
+  // TracingMuxer implementation.
+  bool RegisterDataSource(const DataSourceDescriptor&,
+                          DataSourceFactory,
+                          DataSourceParams,
+                          DataSourceStaticState*) override;
+  void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
+                                  const DataSourceStaticState*) override;
+  std::unique_ptr<TraceWriterBase> CreateTraceWriter(
+      DataSourceStaticState*,
+      uint32_t data_source_instance_index,
+      DataSourceState*,
+      BufferExhaustedPolicy buffer_exhausted_policy) override;
+  void DestroyStoppedTraceWritersForCurrentThread() override;
+  void RegisterInterceptor(const InterceptorDescriptor&,
+                           InterceptorFactory,
+                           InterceptorBase::TLSFactory,
+                           InterceptorBase::TracePacketCallback) override;
+  void ActivateTriggers(const std::vector<std::string>&, uint32_t) override;
+
+ private:
+  static TracingMuxerFake instance;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"
+
+namespace perfetto {
+namespace internal {
+namespace {
+
+PERFETTO_NORETURN void FailUninitialized() {
+  PERFETTO_FATAL(
+      "Tracing not initialized. Call perfetto::Tracing::Initialize() first.");
+}
+
+}  // namespace
+
+#if PERFETTO_HAS_NO_DESTROY()
+// static
+PERFETTO_NO_DESTROY TracingMuxerFake::FakePlatform
+    TracingMuxerFake::FakePlatform::instance{};
+// static
+PERFETTO_NO_DESTROY TracingMuxerFake TracingMuxerFake::instance{};
+#endif  // PERFETTO_HAS_NO_DESTROY()
+
+TracingMuxerFake::~TracingMuxerFake() = default;
+
+TracingMuxerFake::FakePlatform::~FakePlatform() = default;
+
+Platform::ThreadLocalObject*
+TracingMuxerFake::FakePlatform::GetOrCreateThreadLocalObject() {
+  FailUninitialized();
+}
+
+std::unique_ptr<base::TaskRunner>
+TracingMuxerFake::FakePlatform::CreateTaskRunner(const CreateTaskRunnerArgs&) {
+  FailUninitialized();
+}
+
+std::string TracingMuxerFake::FakePlatform::GetCurrentProcessName() {
+  FailUninitialized();
+}
+
+bool TracingMuxerFake::RegisterDataSource(const DataSourceDescriptor&,
+                                          DataSourceFactory,
+                                          DataSourceParams,
+                                          DataSourceStaticState*) {
+  FailUninitialized();
+}
+
+void TracingMuxerFake::UpdateDataSourceDescriptor(
+    const DataSourceDescriptor&,
+    const DataSourceStaticState*) {
+  FailUninitialized();
+}
+
+std::unique_ptr<TraceWriterBase> TracingMuxerFake::CreateTraceWriter(
+    DataSourceStaticState*,
+    uint32_t,
+    DataSourceState*,
+    BufferExhaustedPolicy) {
+  FailUninitialized();
+}
+
+void TracingMuxerFake::DestroyStoppedTraceWritersForCurrentThread() {
+  FailUninitialized();
+}
+
+void TracingMuxerFake::RegisterInterceptor(
+    const InterceptorDescriptor&,
+    InterceptorFactory,
+    InterceptorBase::TLSFactory,
+    InterceptorBase::TracePacketCallback) {
+  FailUninitialized();
+}
+
+void TracingMuxerFake::ActivateTriggers(const std::vector<std::string>&,
+                                        uint32_t) {
+  FailUninitialized();
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/tracing_muxer_impl.cc
+// gen_amalgamated begin header: src/tracing/internal/tracing_muxer_impl.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
+#define SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <array>
+#include <atomic>
+#include <bitset>
+#include <functional>
+#include <list>
+#include <map>
+#include <memory>
+#include <set>
+#include <utility>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/backend_type.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
+
+namespace perfetto {
+
+class ConsumerEndpoint;
+class DataSourceBase;
+class ProducerEndpoint;
+class TraceWriterBase;
+class TracingBackend;
+class TracingSession;
+struct TracingInitArgs;
+
+namespace base {
+class TaskRunner;
+}
+
+namespace shlib {
+void ResetForTesting();
+}
+
+namespace test {
+class TracingMuxerImplInternalsForTest;
+}
+
+namespace internal {
+
+struct DataSourceStaticState;
+
+// This class acts as a bridge between the public API and the TracingBackend(s).
+// It exposes a simplified view of the world to the API methods handling all the
+// bookkeeping to map data source instances and trace writers to the various
+// backends. It deals with N data sources, M backends (1 backend == 1 tracing
+// service == 1 producer connection) and T concurrent tracing sessions.
+//
+// Handing data source registration and start/stop flows [producer side]:
+// ----------------------------------------------------------------------
+// 1. The API client subclasses perfetto::DataSource and calls
+//    DataSource::Register<MyDataSource>(). In turn this calls into the
+//    TracingMuxer.
+// 2. The tracing muxer iterates through all the backends (1 backend == 1
+//    service == 1 producer connection) and registers the data source on each
+//    backend.
+// 3. When any (services behind a) backend starts tracing and requests to start
+//    that specific data source, the TracingMuxerImpl constructs a new instance
+//    of MyDataSource and calls the OnStart() method.
+//
+// Controlling trace and retrieving trace data [consumer side]:
+// ------------------------------------------------------------
+// 1. The API client calls Tracing::NewTrace(), returns a RAII TracingSession
+//    object.
+// 2. NewTrace() calls into internal::TracingMuxer(Impl). TracingMuxer
+//    subclasses the TracingSession object (TracingSessionImpl) and returns it.
+// 3. The tracing muxer identifies the backend (according to the args passed to
+//    NewTrace), creates a new Consumer and connects to it.
+// 4. When the API client calls Start()/Stop()/ReadTrace() methods, the
+//    TracingMuxer forwards them to the consumer associated to the
+//    TracingSession. Likewise for callbacks coming from the consumer-side of
+//    the service.
+class TracingMuxerImpl : public TracingMuxer {
+ public:
+  // This is different than TracingSessionID because it's global across all
+  // backends. TracingSessionID is global only within the scope of one service.
+  using TracingSessionGlobalID = uint64_t;
+
+  struct RegisteredDataSource {
+    DataSourceDescriptor descriptor;
+    DataSourceFactory factory{};
+    bool supports_multiple_instances = false;
+    bool requires_callbacks_under_lock = false;
+    DataSourceStaticState* static_state = nullptr;
+  };
+
+  static void InitializeInstance(const TracingInitArgs&);
+  static void ResetForTesting();
+  static void Shutdown();
+
+  // TracingMuxer implementation.
+  bool RegisterDataSource(const DataSourceDescriptor&,
+                          DataSourceFactory,
+                          DataSourceParams,
+                          DataSourceStaticState*) override;
+  void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
+                                  const DataSourceStaticState*) override;
+  std::unique_ptr<TraceWriterBase> CreateTraceWriter(
+      DataSourceStaticState*,
+      uint32_t data_source_instance_index,
+      DataSourceState*,
+      BufferExhaustedPolicy buffer_exhausted_policy) override;
+  void DestroyStoppedTraceWritersForCurrentThread() override;
+  void RegisterInterceptor(const InterceptorDescriptor&,
+                           InterceptorFactory,
+                           InterceptorBase::TLSFactory,
+                           InterceptorBase::TracePacketCallback) override;
+
+  void ActivateTriggers(const std::vector<std::string>&, uint32_t) override;
+
+  std::unique_ptr<TracingSession> CreateTracingSession(
+      BackendType,
+      TracingConsumerBackend* (*system_backend_factory)());
+  std::unique_ptr<StartupTracingSession> CreateStartupTracingSession(
+      const TraceConfig& config,
+      Tracing::SetupStartupTracingOpts);
+  std::unique_ptr<StartupTracingSession> CreateStartupTracingSessionBlocking(
+      const TraceConfig& config,
+      Tracing::SetupStartupTracingOpts);
+
+  // Producer-side bookkeeping methods.
+  void UpdateDataSourcesOnAllBackends();
+  void SetupDataSource(TracingBackendId,
+                       uint32_t backend_connection_id,
+                       DataSourceInstanceID,
+                       const DataSourceConfig&);
+  void StartDataSource(TracingBackendId, DataSourceInstanceID);
+  void StopDataSource_AsyncBegin(TracingBackendId, DataSourceInstanceID);
+  void ClearDataSourceIncrementalState(TracingBackendId, DataSourceInstanceID);
+  void SyncProducersForTesting();
+
+  // Consumer-side bookkeeping methods.
+  void SetupTracingSession(TracingSessionGlobalID,
+                           const std::shared_ptr<TraceConfig>&,
+                           base::ScopedFile trace_fd = base::ScopedFile());
+  void StartTracingSession(TracingSessionGlobalID);
+  void ChangeTracingSessionConfig(TracingSessionGlobalID, const TraceConfig&);
+  void StopTracingSession(TracingSessionGlobalID);
+  void DestroyTracingSession(TracingSessionGlobalID);
+  void FlushTracingSession(TracingSessionGlobalID,
+                           uint32_t,
+                           std::function<void(bool)>);
+  void ReadTracingSessionData(
+      TracingSessionGlobalID,
+      std::function<void(TracingSession::ReadTraceCallbackArgs)>);
+  void GetTraceStats(TracingSessionGlobalID,
+                     TracingSession::GetTraceStatsCallback);
+  void QueryServiceState(TracingSessionGlobalID,
+                         TracingSession::QueryServiceStateCallback);
+
+  // Sets the batching period to |batch_commits_duration_ms| on the backends
+  // with type |backend_type|.
+  void SetBatchCommitsDurationForTesting(uint32_t batch_commits_duration_ms,
+                                         BackendType backend_type);
+
+  // Enables direct SMB patching on the backends with type |backend_type| (see
+  // SharedMemoryArbiter::EnableDirectSMBPatching). Returns true if the
+  // operation succeeded for all backends with type |backend_type|, false
+  // otherwise.
+  bool EnableDirectSMBPatchingForTesting(BackendType backend_type);
+
+  void SetMaxProducerReconnectionsForTesting(uint32_t count);
+
+ private:
+  friend class test::TracingMuxerImplInternalsForTest;
+  friend void shlib::ResetForTesting();
+
+  // For each TracingBackend we create and register one ProducerImpl instance.
+  // This talks to the producer-side of the service, gets start/stop requests
+  // from it and routes them to the registered data sources.
+  // One ProducerImpl == one backend == one tracing service.
+  // This class is needed to disambiguate callbacks coming from different
+  // services. TracingMuxerImpl can't directly implement the Producer interface
+  // because the Producer virtual methods don't allow to identify the service.
+  class ProducerImpl : public Producer {
+   public:
+    ProducerImpl(TracingMuxerImpl*,
+                 TracingBackendId,
+                 uint32_t shmem_batch_commits_duration_ms,
+                 bool shmem_direct_patching_enabled);
+    ~ProducerImpl() override;
+
+    void Initialize(std::unique_ptr<ProducerEndpoint> endpoint);
+    void RegisterDataSource(const DataSourceDescriptor&,
+                            DataSourceFactory,
+                            DataSourceStaticState*);
+    void DisposeConnection();
+
+    // perfetto::Producer implementation.
+    void OnConnect() override;
+    void OnDisconnect() override;
+    void OnTracingSetup() override;
+    void OnStartupTracingSetup() override;
+    void SetupDataSource(DataSourceInstanceID,
+                         const DataSourceConfig&) override;
+    void StartDataSource(DataSourceInstanceID,
+                         const DataSourceConfig&) override;
+    void StopDataSource(DataSourceInstanceID) override;
+    void Flush(FlushRequestID,
+               const DataSourceInstanceID*,
+               size_t,
+               FlushFlags) override;
+    void ClearIncrementalState(const DataSourceInstanceID*, size_t) override;
+
+    bool SweepDeadServices();
+    void SendOnConnectTriggers();
+    void NotifyFlushForDataSourceDone(DataSourceInstanceID, FlushRequestID);
+
+    PERFETTO_THREAD_CHECKER(thread_checker_)
+    TracingMuxerImpl* muxer_;
+    TracingBackendId const backend_id_;
+    bool connected_ = false;
+    bool did_setup_tracing_ = false;
+    bool did_setup_startup_tracing_ = false;
+    std::atomic<uint32_t> connection_id_{0};
+    uint16_t last_startup_target_buffer_reservation_ = 0;
+    bool is_producer_provided_smb_ = false;
+    bool producer_provided_smb_failed_ = false;
+
+    const uint32_t shmem_batch_commits_duration_ms_ = 0;
+    const bool shmem_direct_patching_enabled_ = false;
+
+    // Set of data sources that have been actually registered on this producer.
+    // This can be a subset of the global |data_sources_|, because data sources
+    // can register before the producer is fully connected.
+    std::bitset<kMaxDataSources> registered_data_sources_{};
+
+    // A collection of disconnected service endpoints. Since trace writers on
+    // arbitrary threads might continue writing data to disconnected services,
+    // we keep the old services around and periodically try to clean up ones
+    // that no longer have any writers (see SweepDeadServices).
+    std::list<std::shared_ptr<ProducerEndpoint>> dead_services_;
+
+    // Triggers that should be sent when the service connects (trigger_name,
+    // expiration).
+    std::list<std::pair<std::string, base::TimeMillis>> on_connect_triggers_;
+
+    std::map<FlushRequestID, std::set<DataSourceInstanceID>> pending_flushes_;
+
+    // The currently active service endpoint is maintained as an atomic shared
+    // pointer so it won't get deleted from underneath threads that are creating
+    // trace writers. At any given time one endpoint can be shared (and thus
+    // kept alive) by the |service_| pointer, an entry in |dead_services_| and
+    // as a pointer on the stack in CreateTraceWriter() (on an arbitrary
+    // thread). The endpoint is never shared outside ProducerImpl itself.
+    //
+    // WARNING: Any *write* access to this variable or any *read* access from a
+    // non-muxer thread must be done through std::atomic_{load,store} to avoid
+    // data races.
+    std::shared_ptr<ProducerEndpoint> service_;  // Keep last.
+  };
+
+  // For each TracingSession created by the API client (Tracing::NewTrace() we
+  // create and register one ConsumerImpl instance.
+  // This talks to the consumer-side of the service, gets end-of-trace and
+  // on-trace-data callbacks and routes them to the API client callbacks.
+  // This class is needed to disambiguate callbacks coming from different
+  // tracing sessions.
+  class ConsumerImpl : public Consumer {
+   public:
+    ConsumerImpl(TracingMuxerImpl*, BackendType, TracingSessionGlobalID);
+    ~ConsumerImpl() override;
+
+    void Initialize(std::unique_ptr<ConsumerEndpoint> endpoint);
+
+    // perfetto::Consumer implementation.
+    void OnConnect() override;
+    void OnDisconnect() override;
+    void OnTracingDisabled(const std::string& error) override;
+    void OnTraceData(std::vector<TracePacket>, bool has_more) override;
+    void OnDetach(bool success) override;
+    void OnAttach(bool success, const TraceConfig&) override;
+    void OnTraceStats(bool success, const TraceStats&) override;
+    void OnObservableEvents(const ObservableEvents&) override;
+    void OnSessionCloned(const OnSessionClonedArgs&) override;
+
+    void NotifyStartComplete();
+    void NotifyError(const TracingError&);
+    void NotifyStopComplete();
+
+    // Will eventually inform the |muxer_| when it is safe to remove |this|.
+    void Disconnect();
+
+    TracingMuxerImpl* muxer_;
+    BackendType const backend_type_;
+    TracingSessionGlobalID const session_id_;
+    bool connected_ = false;
+
+    // This is to handle the case where the Setup call from the API client
+    // arrives before the consumer has connected. In this case we keep around
+    // the config and check if we have it after connection.
+    bool start_pending_ = false;
+
+    // Similarly if the session is stopped before the consumer was connected, we
+    // need to wait until the session has started before stopping it.
+    bool stop_pending_ = false;
+
+    // Similarly we need to buffer a call to get trace statistics if the
+    // consumer wasn't connected yet.
+    bool get_trace_stats_pending_ = false;
+
+    // Whether this session was already stopped. This will happen in response to
+    // Stop{,Blocking}, but also if the service stops the session for us
+    // automatically (e.g., when there are no data sources).
+    bool stopped_ = false;
+
+    // shared_ptr because it's posted across threads. This is to avoid copying
+    // it more than once.
+    std::shared_ptr<TraceConfig> trace_config_;
+    base::ScopedFile trace_fd_;
+
+    // If the API client passes a callback to start, we should invoke this when
+    // NotifyStartComplete() is invoked.
+    std::function<void()> start_complete_callback_;
+
+    // An internal callback used to implement StartBlocking().
+    std::function<void()> blocking_start_complete_callback_;
+
+    // If the API client passes a callback to get notification about the
+    // errors, we should invoke this when NotifyError() is invoked.
+    std::function<void(TracingError)> error_callback_;
+
+    // If the API client passes a callback to stop, we should invoke this when
+    // OnTracingDisabled() is invoked.
+    std::function<void()> stop_complete_callback_;
+
+    // An internal callback used to implement StopBlocking().
+    std::function<void()> blocking_stop_complete_callback_;
+
+    // Callback passed to ReadTrace().
+    std::function<void(TracingSession::ReadTraceCallbackArgs)>
+        read_trace_callback_;
+
+    // Callback passed to GetTraceStats().
+    TracingSession::GetTraceStatsCallback get_trace_stats_callback_;
+
+    // Callback for a pending call to QueryServiceState().
+    TracingSession::QueryServiceStateCallback query_service_state_callback_;
+
+    // The states of all data sources in this tracing session. |true| means the
+    // data source has started tracing.
+    using DataSourceHandle = std::pair<std::string, std::string>;
+    std::map<DataSourceHandle, bool> data_source_states_;
+
+    std::unique_ptr<ConsumerEndpoint> service_;  // Keep before last.
+    PERFETTO_THREAD_CHECKER(thread_checker_)     // Keep last.
+  };
+
+  // This object is returned to API clients when they call
+  // Tracing::CreateTracingSession().
+  class TracingSessionImpl : public TracingSession {
+   public:
+    TracingSessionImpl(TracingMuxerImpl*, TracingSessionGlobalID, BackendType);
+    ~TracingSessionImpl() override;
+    void Setup(const TraceConfig&, int fd) override;
+    void Start() override;
+    void StartBlocking() override;
+    void SetOnStartCallback(std::function<void()>) override;
+    void SetOnErrorCallback(std::function<void(TracingError)>) override;
+    void Stop() override;
+    void StopBlocking() override;
+    void Flush(std::function<void(bool)>, uint32_t timeout_ms) override;
+    void ReadTrace(ReadTraceCallback) override;
+    void SetOnStopCallback(std::function<void()>) override;
+    void GetTraceStats(GetTraceStatsCallback) override;
+    void QueryServiceState(QueryServiceStateCallback) override;
+    void ChangeTraceConfig(const TraceConfig&) override;
+
+   private:
+    TracingMuxerImpl* const muxer_;
+    TracingSessionGlobalID const session_id_;
+    BackendType const backend_type_;
+  };
+
+  // This object is returned to API clients when they call
+  // Tracing::SetupStartupTracing().
+  class StartupTracingSessionImpl : public StartupTracingSession {
+   public:
+    StartupTracingSessionImpl(TracingMuxerImpl*,
+                              TracingSessionGlobalID,
+                              BackendType);
+    ~StartupTracingSessionImpl() override;
+    void Abort() override;
+    void AbortBlocking() override;
+
+   private:
+    TracingMuxerImpl* const muxer_;
+    TracingSessionGlobalID const session_id_;
+    BackendType backend_type_;
+  };
+
+  struct RegisteredInterceptor {
+    protos::gen::InterceptorDescriptor descriptor;
+    InterceptorFactory factory{};
+    InterceptorBase::TLSFactory tls_factory{};
+    InterceptorBase::TracePacketCallback packet_callback{};
+  };
+
+  struct RegisteredStartupSession {
+    TracingSessionID session_id = 0;
+    int num_unbound_data_sources = 0;
+
+    bool is_aborting = false;
+    int num_aborting_data_sources = 0;
+
+    std::function<void()> on_aborted;
+    std::function<void()> on_adopted;
+  };
+
+  struct RegisteredProducerBackend {
+    // Backends are supposed to have static lifetime.
+    TracingProducerBackend* backend = nullptr;
+    TracingBackendId id = 0;
+    BackendType type{};
+
+    TracingBackend::ConnectProducerArgs producer_conn_args;
+    std::unique_ptr<ProducerImpl> producer;
+
+    std::vector<RegisteredStartupSession> startup_sessions;
+  };
+
+  struct RegisteredConsumerBackend {
+    // Backends are supposed to have static lifetime.
+    TracingConsumerBackend* backend = nullptr;
+    BackendType type{};
+    // The calling code can request more than one concurrently active tracing
+    // session for the same backend. We need to create one consumer per session.
+    std::vector<std::unique_ptr<ConsumerImpl>> consumers;
+  };
+
+  void UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
+                                     bool is_changed);
+  explicit TracingMuxerImpl(const TracingInitArgs&);
+  void Initialize(const TracingInitArgs& args);
+  void AddBackends(const TracingInitArgs& args);
+  void AddConsumerBackend(TracingConsumerBackend* backend, BackendType type);
+  void AddProducerBackend(TracingProducerBackend* backend,
+                          BackendType type,
+                          const TracingInitArgs& args);
+  ConsumerImpl* FindConsumer(TracingSessionGlobalID session_id);
+  std::pair<ConsumerImpl*, RegisteredConsumerBackend*> FindConsumerAndBackend(
+      TracingSessionGlobalID session_id);
+  RegisteredProducerBackend* FindProducerBackendById(TracingBackendId id);
+  RegisteredProducerBackend* FindProducerBackendByType(BackendType type);
+  RegisteredConsumerBackend* FindConsumerBackendByType(BackendType type);
+  void InitializeConsumer(TracingSessionGlobalID session_id);
+  void OnConsumerDisconnected(ConsumerImpl* consumer);
+  void OnProducerDisconnected(ProducerImpl* producer);
+  // Test only method.
+  void SweepDeadBackends();
+
+  struct FindDataSourceRes {
+    FindDataSourceRes() = default;
+    FindDataSourceRes(DataSourceStaticState* a,
+                      DataSourceState* b,
+                      uint32_t c,
+                      bool d)
+        : static_state(a),
+          internal_state(b),
+          instance_idx(c),
+          requires_callbacks_under_lock(d) {}
+    explicit operator bool() const { return !!internal_state; }
+
+    DataSourceStaticState* static_state = nullptr;
+    DataSourceState* internal_state = nullptr;
+    uint32_t instance_idx = 0;
+    bool requires_callbacks_under_lock = false;
+  };
+  FindDataSourceRes FindDataSource(TracingBackendId, DataSourceInstanceID);
+
+  FindDataSourceRes SetupDataSourceImpl(
+      const RegisteredDataSource&,
+      TracingBackendId,
+      uint32_t backend_connection_id,
+      DataSourceInstanceID,
+      const DataSourceConfig&,
+      TracingSessionGlobalID startup_session_id);
+  void StartDataSourceImpl(const FindDataSourceRes&);
+  void StopDataSource_AsyncBeginImpl(const FindDataSourceRes&);
+  void StopDataSource_AsyncEnd(TracingBackendId,
+                               uint32_t backend_connection_id,
+                               DataSourceInstanceID,
+                               const FindDataSourceRes&);
+  bool FlushDataSource_AsyncBegin(TracingBackendId,
+                                  DataSourceInstanceID,
+                                  FlushRequestID,
+                                  FlushFlags);
+  void FlushDataSource_AsyncEnd(TracingBackendId,
+                                uint32_t backend_connection_id,
+                                DataSourceInstanceID,
+                                const FindDataSourceRes&,
+                                FlushRequestID);
+  void AbortStartupTracingSession(TracingSessionGlobalID, BackendType);
+  // When ResetForTesting() is executed, `cb` will be called on the calling
+  // thread and on the muxer thread.
+  void AppendResetForTestingCallback(std::function<void()> cb);
+
+  // WARNING: If you add new state here, be sure to update ResetForTesting.
+  std::unique_ptr<base::TaskRunner> task_runner_;
+  std::vector<RegisteredDataSource> data_sources_;
+  // These lists can only have one backend per BackendType. The elements are
+  // sorted by BackendType priority (see BackendTypePriority). They always
+  // contain a fake low-priority kUnspecifiedBackend at the end.
+  std::list<RegisteredProducerBackend> producer_backends_;
+  std::list<RegisteredConsumerBackend> consumer_backends_;
+  std::vector<RegisteredInterceptor> interceptors_;
+  TracingPolicy* policy_ = nullptr;
+
+  // Learn more at TracingInitArgs::supports_multiple_data_source_instances
+  bool supports_multiple_data_source_instances_ = true;
+
+  std::atomic<TracingSessionGlobalID> next_tracing_session_id_{};
+  std::atomic<uint32_t> next_data_source_index_{};
+  uint32_t muxer_id_for_testing_{};
+
+  // Maximum number of times we will try to reconnect producer backend.
+  // Should only be modified for testing purposes.
+  std::atomic<uint32_t> max_producer_reconnections_{100u};
+
+  // Test only member.
+  // After ResetForTesting() is called, holds tracing backends which needs to be
+  // kept alive until all inbound references have gone away. See
+  // SweepDeadBackends().
+  std::list<RegisteredProducerBackend> dead_backends_;
+
+  // Test only member.
+  // Executes these cleanup functions on the calling thread and on the muxer
+  // thread when ResetForTesting() is called.
+  std::list<std::function<void()>> reset_callbacks_;
+
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_stats.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
+// gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_state.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"
+
+#include <algorithm>
+#include <atomic>
+#include <mutex>
+#include <optional>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/interceptor_trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_backend_fake.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+// gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
+// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <io.h>  // For dup()
+#else
+#include <unistd.h>  // For dup()
+#endif
+
+namespace perfetto {
+namespace internal {
+
+namespace {
+
+using RegisteredDataSource = TracingMuxerImpl::RegisteredDataSource;
+
+// A task runner which prevents calls to DataSource::Trace() while an operation
+// is in progress. Used to guard against unexpected re-entrancy where the
+// user-provided task runner implementation tries to enter a trace point under
+// the hood.
+class NonReentrantTaskRunner : public base::TaskRunner {
+ public:
+  NonReentrantTaskRunner(TracingMuxer* muxer,
+                         std::unique_ptr<base::TaskRunner> task_runner)
+      : muxer_(muxer), task_runner_(std::move(task_runner)) {}
+
+  // base::TaskRunner implementation.
+  void PostTask(std::function<void()> task) override {
+    CallWithGuard([&] { task_runner_->PostTask(std::move(task)); });
+  }
+
+  void PostDelayedTask(std::function<void()> task, uint32_t delay_ms) override {
+    CallWithGuard(
+        [&] { task_runner_->PostDelayedTask(std::move(task), delay_ms); });
+  }
+
+  void AddFileDescriptorWatch(base::PlatformHandle fd,
+                              std::function<void()> callback) override {
+    CallWithGuard(
+        [&] { task_runner_->AddFileDescriptorWatch(fd, std::move(callback)); });
+  }
+
+  void RemoveFileDescriptorWatch(base::PlatformHandle fd) override {
+    CallWithGuard([&] { task_runner_->RemoveFileDescriptorWatch(fd); });
+  }
+
+  bool RunsTasksOnCurrentThread() const override {
+    bool result;
+    CallWithGuard([&] { result = task_runner_->RunsTasksOnCurrentThread(); });
+    return result;
+  }
+
+ private:
+  template <typename T>
+  void CallWithGuard(T lambda) const {
+    auto* root_tls = muxer_->GetOrCreateTracingTLS();
+    if (PERFETTO_UNLIKELY(root_tls->is_in_trace_point)) {
+      lambda();
+      return;
+    }
+    ScopedReentrancyAnnotator scoped_annotator(*root_tls);
+    lambda();
+  }
+
+  TracingMuxer* const muxer_;
+  std::unique_ptr<base::TaskRunner> task_runner_;
+};
+
+class StopArgsImpl : public DataSourceBase::StopArgs {
+ public:
+  std::function<void()> HandleStopAsynchronously() const override {
+    auto closure = std::move(async_stop_closure);
+    async_stop_closure = std::function<void()>();
+    return closure;
+  }
+
+  mutable std::function<void()> async_stop_closure;
+};
+
+class FlushArgsImpl : public DataSourceBase::FlushArgs {
+ public:
+  std::function<void()> HandleFlushAsynchronously() const override {
+    auto closure = std::move(async_flush_closure);
+    async_flush_closure = std::function<void()>();
+    return closure;
+  }
+
+  mutable std::function<void()> async_flush_closure;
+};
+
+// Holds an earlier TracingMuxerImpl instance after ResetForTesting() is called.
+static TracingMuxerImpl* g_prev_instance{};
+
+template <typename RegisteredBackend>
+struct CompareBackendByType {
+  static int BackendTypePriority(BackendType type) {
+    switch (type) {
+      case kSystemBackend:
+        return 0;
+      case kInProcessBackend:
+        return 1;
+      case kCustomBackend:
+        return 2;
+      // The UnspecifiedBackend has the highest priority so that
+      // TracingBackendFake is the last one on the backend lists.
+      case kUnspecifiedBackend:
+        break;
+    }
+    return 3;
+  }
+  bool operator()(BackendType type, const RegisteredBackend& b) {
+    return BackendTypePriority(type) < BackendTypePriority(b.type);
+  }
+};
+
+}  // namespace
+
+// ----- Begin of TracingMuxerImpl::ProducerImpl
+TracingMuxerImpl::ProducerImpl::ProducerImpl(
+    TracingMuxerImpl* muxer,
+    TracingBackendId backend_id,
+    uint32_t shmem_batch_commits_duration_ms,
+    bool shmem_direct_patching_enabled)
+    : muxer_(muxer),
+      backend_id_(backend_id),
+      shmem_batch_commits_duration_ms_(shmem_batch_commits_duration_ms),
+      shmem_direct_patching_enabled_(shmem_direct_patching_enabled) {}
+
+TracingMuxerImpl::ProducerImpl::~ProducerImpl() {
+  muxer_ = nullptr;
+}
+
+void TracingMuxerImpl::ProducerImpl::Initialize(
+    std::unique_ptr<ProducerEndpoint> endpoint) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(!connected_);
+  connection_id_.fetch_add(1, std::memory_order_relaxed);
+  is_producer_provided_smb_ = endpoint->shared_memory();
+  last_startup_target_buffer_reservation_ = 0;
+
+  // Adopt the endpoint into a shared pointer so that we can safely share it
+  // across threads that create trace writers. The custom deleter function
+  // ensures that the endpoint is always destroyed on the muxer's thread. (Note
+  // that |task_runner| is assumed to outlive tracing sessions on all threads.)
+  auto* task_runner = muxer_->task_runner_.get();
+  auto deleter = [task_runner](ProducerEndpoint* e) {
+    if (task_runner->RunsTasksOnCurrentThread()) {
+      delete e;
+      return;
+    }
+    task_runner->PostTask([e] { delete e; });
+  };
+  std::shared_ptr<ProducerEndpoint> service(endpoint.release(), deleter);
+  // This atomic store is needed because another thread might be concurrently
+  // creating a trace writer using the previous (disconnected) |service_|. See
+  // CreateTraceWriter().
+  std::atomic_store(&service_, std::move(service));
+  // Don't try to use the service here since it may not have connected yet. See
+  // OnConnect().
+}
+
+void TracingMuxerImpl::ProducerImpl::OnConnect() {
+  PERFETTO_DLOG("Producer connected");
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(!connected_);
+  if (is_producer_provided_smb_ && !service_->IsShmemProvidedByProducer()) {
+    PERFETTO_ELOG(
+        "The service likely doesn't support producer-provided SMBs. Preventing "
+        "future attempts to use producer-provided SMB again with this "
+        "backend.");
+    producer_provided_smb_failed_ = true;
+    // Will call OnDisconnect() and cause a reconnect without producer-provided
+    // SMB.
+    service_->Disconnect();
+    return;
+  }
+  connected_ = true;
+  muxer_->UpdateDataSourcesOnAllBackends();
+  SendOnConnectTriggers();
+}
+
+void TracingMuxerImpl::ProducerImpl::OnDisconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // If we're being destroyed, bail out.
+  if (!muxer_)
+    return;
+  connected_ = false;
+  // Active data sources for this producer will be stopped by
+  // DestroyStoppedTraceWritersForCurrentThread() since the reconnected producer
+  // will have a different connection id (even before it has finished
+  // connecting).
+  registered_data_sources_.reset();
+  DisposeConnection();
+
+  // Try reconnecting the producer.
+  muxer_->OnProducerDisconnected(this);
+}
+
+void TracingMuxerImpl::ProducerImpl::DisposeConnection() {
+  // Keep the old service around as a dead connection in case it has active
+  // trace writers. If any tracing sessions were created, we can't clear
+  // |service_| here because other threads may be concurrently creating new
+  // trace writers. Any reconnection attempt will atomically swap the new
+  // service in place of the old one.
+  if (did_setup_tracing_ || did_setup_startup_tracing_) {
+    dead_services_.push_back(service_);
+  } else {
+    service_.reset();
+  }
+}
+
+void TracingMuxerImpl::ProducerImpl::OnTracingSetup() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  did_setup_tracing_ = true;
+  service_->MaybeSharedMemoryArbiter()->SetBatchCommitsDuration(
+      shmem_batch_commits_duration_ms_);
+  if (shmem_direct_patching_enabled_) {
+    service_->MaybeSharedMemoryArbiter()->EnableDirectSMBPatching();
+  }
+}
+
+void TracingMuxerImpl::ProducerImpl::OnStartupTracingSetup() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  did_setup_startup_tracing_ = true;
+}
+
+void TracingMuxerImpl::ProducerImpl::SetupDataSource(
+    DataSourceInstanceID id,
+    const DataSourceConfig& cfg) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!muxer_)
+    return;
+  muxer_->SetupDataSource(
+      backend_id_, connection_id_.load(std::memory_order_relaxed), id, cfg);
+}
+
+void TracingMuxerImpl::ProducerImpl::StartDataSource(DataSourceInstanceID id,
+                                                     const DataSourceConfig&) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!muxer_)
+    return;
+  muxer_->StartDataSource(backend_id_, id);
+  service_->NotifyDataSourceStarted(id);
+}
+
+void TracingMuxerImpl::ProducerImpl::StopDataSource(DataSourceInstanceID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!muxer_)
+    return;
+  muxer_->StopDataSource_AsyncBegin(backend_id_, id);
+}
+
+void TracingMuxerImpl::ProducerImpl::Flush(
+    FlushRequestID flush_id,
+    const DataSourceInstanceID* instances,
+    size_t instance_count,
+    FlushFlags flush_flags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  bool all_handled = true;
+  if (muxer_) {
+    for (size_t i = 0; i < instance_count; i++) {
+      DataSourceInstanceID ds_id = instances[i];
+      bool handled = muxer_->FlushDataSource_AsyncBegin(backend_id_, ds_id,
+                                                        flush_id, flush_flags);
+      if (!handled) {
+        pending_flushes_[flush_id].insert(ds_id);
+        all_handled = false;
+      }
+    }
+  }
+
+  if (all_handled) {
+    service_->NotifyFlushComplete(flush_id);
+  }
+}
+
+void TracingMuxerImpl::ProducerImpl::ClearIncrementalState(
+    const DataSourceInstanceID* instances,
+    size_t instance_count) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!muxer_)
+    return;
+  for (size_t inst_idx = 0; inst_idx < instance_count; inst_idx++) {
+    muxer_->ClearDataSourceIncrementalState(backend_id_, instances[inst_idx]);
+  }
+}
+
+bool TracingMuxerImpl::ProducerImpl::SweepDeadServices() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto is_unused = [](const std::shared_ptr<ProducerEndpoint>& endpoint) {
+    auto* arbiter = endpoint->MaybeSharedMemoryArbiter();
+    return !arbiter || arbiter->TryShutdown();
+  };
+  for (auto it = dead_services_.begin(); it != dead_services_.end();) {
+    auto next_it = it;
+    next_it++;
+    if (is_unused(*it)) {
+      dead_services_.erase(it);
+    }
+    it = next_it;
+  }
+  return dead_services_.empty();
+}
+
+void TracingMuxerImpl::ProducerImpl::SendOnConnectTriggers() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  base::TimeMillis now = base::GetWallTimeMs();
+  std::vector<std::string> triggers;
+  while (!on_connect_triggers_.empty()) {
+    // Skip if we passed TTL.
+    if (on_connect_triggers_.front().second > now) {
+      triggers.push_back(std::move(on_connect_triggers_.front().first));
+    }
+    on_connect_triggers_.pop_front();
+  }
+  if (!triggers.empty()) {
+    service_->ActivateTriggers(triggers);
+  }
+}
+
+void TracingMuxerImpl::ProducerImpl::NotifyFlushForDataSourceDone(
+    DataSourceInstanceID ds_id,
+    FlushRequestID flush_id) {
+  if (!connected_) {
+    return;
+  }
+
+  {
+    auto it = pending_flushes_.find(flush_id);
+    if (it == pending_flushes_.end()) {
+      return;
+    }
+    std::set<DataSourceInstanceID>& ds_ids = it->second;
+    ds_ids.erase(ds_id);
+  }
+
+  std::optional<DataSourceInstanceID> biggest_flush_id;
+  for (auto it = pending_flushes_.begin(); it != pending_flushes_.end();) {
+    if (it->second.empty()) {
+      biggest_flush_id = it->first;
+      it = pending_flushes_.erase(it);
+    } else {
+      break;
+    }
+  }
+
+  if (biggest_flush_id) {
+    service_->NotifyFlushComplete(*biggest_flush_id);
+  }
+}
+
+// ----- End of TracingMuxerImpl::ProducerImpl methods.
+
+// ----- Begin of TracingMuxerImpl::ConsumerImpl
+TracingMuxerImpl::ConsumerImpl::ConsumerImpl(TracingMuxerImpl* muxer,
+                                             BackendType backend_type,
+                                             TracingSessionGlobalID session_id)
+    : muxer_(muxer), backend_type_(backend_type), session_id_(session_id) {}
+
+TracingMuxerImpl::ConsumerImpl::~ConsumerImpl() {
+  muxer_ = nullptr;
+}
+
+void TracingMuxerImpl::ConsumerImpl::Initialize(
+    std::unique_ptr<ConsumerEndpoint> endpoint) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_ = std::move(endpoint);
+  // Don't try to use the service here since it may not have connected yet. See
+  // OnConnect().
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnConnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(!connected_);
+  connected_ = true;
+
+  // Observe data source instance events so we get notified when tracing starts.
+  service_->ObserveEvents(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES |
+                          ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
+
+  // If the API client configured and started tracing before we connected,
+  // tell the backend about it now.
+  if (trace_config_)
+    muxer_->SetupTracingSession(session_id_, trace_config_);
+  if (start_pending_)
+    muxer_->StartTracingSession(session_id_);
+  if (get_trace_stats_pending_) {
+    auto callback = std::move(get_trace_stats_callback_);
+    get_trace_stats_callback_ = nullptr;
+    muxer_->GetTraceStats(session_id_, std::move(callback));
+  }
+  if (query_service_state_callback_) {
+    auto callback = std::move(query_service_state_callback_);
+    query_service_state_callback_ = nullptr;
+    muxer_->QueryServiceState(session_id_, std::move(callback));
+  }
+  if (stop_pending_)
+    muxer_->StopTracingSession(session_id_);
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnDisconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // If we're being destroyed, bail out.
+  if (!muxer_)
+    return;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  if (!connected_ && backend_type_ == kSystemBackend) {
+    PERFETTO_ELOG(
+        "Unable to connect to the system tracing service as a consumer. On "
+        "Android, use the \"perfetto\" command line tool instead to start "
+        "system-wide tracing sessions");
+  }
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+  // Notify the client about disconnection.
+  NotifyError(TracingError{TracingError::kDisconnected, "Peer disconnected"});
+
+  // Make sure the client doesn't hang in a blocking start/stop because of the
+  // disconnection.
+  NotifyStartComplete();
+  NotifyStopComplete();
+
+  // It shouldn't be necessary to call StopTracingSession. If we get this call
+  // it means that the service did shutdown before us, so there is no point
+  // trying it to ask it to stop the session. We should just remember to cleanup
+  // the consumer vector.
+  connected_ = false;
+
+  // Notify the muxer that it is safe to destroy |this|. This is needed because
+  // the ConsumerEndpoint stored in |service_| requires that |this| be safe to
+  // access until OnDisconnect() is called.
+  muxer_->OnConsumerDisconnected(this);
+}
+
+void TracingMuxerImpl::ConsumerImpl::Disconnect() {
+  // This is weird and deserves a comment.
+  //
+  // When we called the ConnectConsumer method on the service it returns
+  // us a ConsumerEndpoint which we stored in |service_|, however this
+  // ConsumerEndpoint holds a pointer to the ConsumerImpl pointed to by
+  // |this|. Part of the API contract to TracingService::ConnectConsumer is that
+  // the ConsumerImpl pointer has to be valid until the
+  // ConsumerImpl::OnDisconnect method is called. Therefore we reset the
+  // ConsumerEndpoint |service_|. Eventually this will call
+  // ConsumerImpl::OnDisconnect and we will inform the muxer it is safe to
+  // call the destructor of |this|.
+  service_.reset();
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnTracingDisabled(
+    const std::string& error) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(!stopped_);
+  stopped_ = true;
+
+  if (!error.empty())
+    NotifyError(TracingError{TracingError::kTracingFailed, error});
+
+  // If we're still waiting for the start event, fire it now. This may happen if
+  // there are no active data sources in the session.
+  NotifyStartComplete();
+  NotifyStopComplete();
+}
+
+void TracingMuxerImpl::ConsumerImpl::NotifyStartComplete() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (start_complete_callback_) {
+    muxer_->task_runner_->PostTask(std::move(start_complete_callback_));
+    start_complete_callback_ = nullptr;
+  }
+  if (blocking_start_complete_callback_) {
+    muxer_->task_runner_->PostTask(
+        std::move(blocking_start_complete_callback_));
+    blocking_start_complete_callback_ = nullptr;
+  }
+}
+
+void TracingMuxerImpl::ConsumerImpl::NotifyError(const TracingError& error) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (error_callback_) {
+    muxer_->task_runner_->PostTask(
+        std::bind(std::move(error_callback_), error));
+  }
+}
+
+void TracingMuxerImpl::ConsumerImpl::NotifyStopComplete() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (stop_complete_callback_) {
+    muxer_->task_runner_->PostTask(std::move(stop_complete_callback_));
+    stop_complete_callback_ = nullptr;
+  }
+  if (blocking_stop_complete_callback_) {
+    muxer_->task_runner_->PostTask(std::move(blocking_stop_complete_callback_));
+    blocking_stop_complete_callback_ = nullptr;
+  }
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnTraceData(
+    std::vector<TracePacket> packets,
+    bool has_more) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!read_trace_callback_)
+    return;
+
+  size_t capacity = 0;
+  for (const auto& packet : packets) {
+    // 16 is an over-estimation of the proto preamble size
+    capacity += packet.size() + 16;
+  }
+
+  // The shared_ptr is to avoid making a copy of the buffer when PostTask-ing.
+  std::shared_ptr<std::vector<char>> buf(new std::vector<char>());
+  buf->reserve(capacity);
+  for (auto& packet : packets) {
+    char* start;
+    size_t size;
+    std::tie(start, size) = packet.GetProtoPreamble();
+    buf->insert(buf->end(), start, start + size);
+    for (auto& slice : packet.slices()) {
+      const auto* slice_data = reinterpret_cast<const char*>(slice.start);
+      buf->insert(buf->end(), slice_data, slice_data + slice.size);
+    }
+  }
+
+  auto callback = read_trace_callback_;
+  muxer_->task_runner_->PostTask([callback, buf, has_more] {
+    TracingSession::ReadTraceCallbackArgs callback_arg{};
+    callback_arg.data = buf->empty() ? nullptr : &(*buf)[0];
+    callback_arg.size = buf->size();
+    callback_arg.has_more = has_more;
+    callback(callback_arg);
+  });
+
+  if (!has_more)
+    read_trace_callback_ = nullptr;
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnObservableEvents(
+    const ObservableEvents& events) {
+  if (events.instance_state_changes_size()) {
+    for (const auto& state_change : events.instance_state_changes()) {
+      DataSourceHandle handle{state_change.producer_name(),
+                              state_change.data_source_name()};
+      data_source_states_[handle] =
+          state_change.state() ==
+          ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED;
+    }
+  }
+
+  if (events.instance_state_changes_size() ||
+      events.all_data_sources_started()) {
+    // Data sources are first reported as being stopped before starting, so once
+    // all the data sources we know about have started we can declare tracing
+    // begun. In the case where there are no matching data sources for the
+    // session, the service will report the all_data_sources_started() event
+    // without adding any instances (only since Android S / Perfetto v10.0).
+    if (start_complete_callback_ || blocking_start_complete_callback_) {
+      bool all_data_sources_started = std::all_of(
+          data_source_states_.cbegin(), data_source_states_.cend(),
+          [](std::pair<DataSourceHandle, bool> state) { return state.second; });
+      if (all_data_sources_started)
+        NotifyStartComplete();
+    }
+  }
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnSessionCloned(
+    const OnSessionClonedArgs&) {
+  // CloneSession is not exposed in the SDK. This should never happen.
+  PERFETTO_DCHECK(false);
+}
+
+void TracingMuxerImpl::ConsumerImpl::OnTraceStats(
+    bool success,
+    const TraceStats& trace_stats) {
+  if (!get_trace_stats_callback_)
+    return;
+  TracingSession::GetTraceStatsCallbackArgs callback_arg{};
+  callback_arg.success = success;
+  callback_arg.trace_stats_data = trace_stats.SerializeAsArray();
+  muxer_->task_runner_->PostTask(
+      std::bind(std::move(get_trace_stats_callback_), std::move(callback_arg)));
+  get_trace_stats_callback_ = nullptr;
+}
+
+// The callbacks below are not used.
+void TracingMuxerImpl::ConsumerImpl::OnDetach(bool) {}
+void TracingMuxerImpl::ConsumerImpl::OnAttach(bool, const TraceConfig&) {}
+// ----- End of TracingMuxerImpl::ConsumerImpl
+
+// ----- Begin of TracingMuxerImpl::TracingSessionImpl
+
+// TracingSessionImpl is the RAII object returned to API clients when they
+// invoke Tracing::CreateTracingSession. They use it for starting/stopping
+// tracing.
+
+TracingMuxerImpl::TracingSessionImpl::TracingSessionImpl(
+    TracingMuxerImpl* muxer,
+    TracingSessionGlobalID session_id,
+    BackendType backend_type)
+    : muxer_(muxer), session_id_(session_id), backend_type_(backend_type) {}
+
+// Can be destroyed from any thread.
+TracingMuxerImpl::TracingSessionImpl::~TracingSessionImpl() {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask(
+      [muxer, session_id] { muxer->DestroyTracingSession(session_id); });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::Setup(const TraceConfig& cfg,
+                                                 int fd) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  std::shared_ptr<TraceConfig> trace_config(new TraceConfig(cfg));
+  if (fd >= 0) {
+    base::ignore_result(backend_type_);  // For -Wunused in the amalgamation.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    if (backend_type_ != kInProcessBackend) {
+      PERFETTO_FATAL(
+          "Passing a file descriptor to TracingSession::Setup() is only "
+          "supported with the kInProcessBackend on Windows. Use "
+          "TracingSession::ReadTrace() instead");
+    }
+#endif
+    trace_config->set_write_into_file(true);
+    fd = dup(fd);
+  }
+  muxer->task_runner_->PostTask([muxer, session_id, trace_config, fd] {
+    muxer->SetupTracingSession(session_id, trace_config, base::ScopedFile(fd));
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::Start() {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask(
+      [muxer, session_id] { muxer->StartTracingSession(session_id); });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::ChangeTraceConfig(
+    const TraceConfig& cfg) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cfg] {
+    muxer->ChangeTracingSessionConfig(session_id, cfg);
+  });
+}
+
+// Can be called from any thread except the service thread.
+void TracingMuxerImpl::TracingSessionImpl::StartBlocking() {
+  PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  base::WaitableEvent tracing_started;
+  muxer->task_runner_->PostTask([muxer, session_id, &tracing_started] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer) {
+      // TODO(skyostil): Signal an error to the user.
+      tracing_started.Notify();
+      return;
+    }
+    PERFETTO_DCHECK(!consumer->blocking_start_complete_callback_);
+    consumer->blocking_start_complete_callback_ = [&] {
+      tracing_started.Notify();
+    };
+    muxer->StartTracingSession(session_id);
+  });
+  tracing_started.Wait();
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::Flush(
+    std::function<void(bool)> user_callback,
+    uint32_t timeout_ms) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, timeout_ms, user_callback] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer) {
+      std::move(user_callback)(false);
+      return;
+    }
+    muxer->FlushTracingSession(session_id, timeout_ms,
+                               std::move(user_callback));
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::Stop() {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask(
+      [muxer, session_id] { muxer->StopTracingSession(session_id); });
+}
+
+// Can be called from any thread except the service thread.
+void TracingMuxerImpl::TracingSessionImpl::StopBlocking() {
+  PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  base::WaitableEvent tracing_stopped;
+  muxer->task_runner_->PostTask([muxer, session_id, &tracing_stopped] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer) {
+      // TODO(skyostil): Signal an error to the user.
+      tracing_stopped.Notify();
+      return;
+    }
+    PERFETTO_DCHECK(!consumer->blocking_stop_complete_callback_);
+    consumer->blocking_stop_complete_callback_ = [&] {
+      tracing_stopped.Notify();
+    };
+    muxer->StopTracingSession(session_id);
+  });
+  tracing_stopped.Wait();
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::ReadTrace(ReadTraceCallback cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    muxer->ReadTracingSessionData(session_id, std::move(cb));
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::SetOnStartCallback(
+    std::function<void()> cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer)
+      return;
+    consumer->start_complete_callback_ = cb;
+  });
+}
+
+// Can be called from any thread
+void TracingMuxerImpl::TracingSessionImpl::SetOnErrorCallback(
+    std::function<void(TracingError)> cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer) {
+      // Notify the client about concurrent disconnection of the session.
+      if (cb)
+        cb(TracingError{TracingError::kDisconnected, "Peer disconnected"});
+      return;
+    }
+    consumer->error_callback_ = cb;
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::SetOnStopCallback(
+    std::function<void()> cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    auto* consumer = muxer->FindConsumer(session_id);
+    if (!consumer)
+      return;
+    consumer->stop_complete_callback_ = cb;
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::GetTraceStats(
+    GetTraceStatsCallback cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    muxer->GetTraceStats(session_id, std::move(cb));
+  });
+}
+
+// Can be called from any thread.
+void TracingMuxerImpl::TracingSessionImpl::QueryServiceState(
+    QueryServiceStateCallback cb) {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  muxer->task_runner_->PostTask([muxer, session_id, cb] {
+    muxer->QueryServiceState(session_id, std::move(cb));
+  });
+}
+
+// ----- End of TracingMuxerImpl::TracingSessionImpl
+
+// ----- Begin of TracingMuxerImpl::StartupTracingSessionImpl
+
+TracingMuxerImpl::StartupTracingSessionImpl::StartupTracingSessionImpl(
+    TracingMuxerImpl* muxer,
+    TracingSessionGlobalID session_id,
+    BackendType backend_type)
+    : muxer_(muxer), session_id_(session_id), backend_type_(backend_type) {}
+
+// Can be destroyed from any thread.
+TracingMuxerImpl::StartupTracingSessionImpl::~StartupTracingSessionImpl() =
+    default;
+
+void TracingMuxerImpl::StartupTracingSessionImpl::Abort() {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  auto backend_type = backend_type_;
+  muxer->task_runner_->PostTask([muxer, session_id, backend_type] {
+    muxer->AbortStartupTracingSession(session_id, backend_type);
+  });
+}
+
+// Must not be called from the SDK's internal thread.
+void TracingMuxerImpl::StartupTracingSessionImpl::AbortBlocking() {
+  auto* muxer = muxer_;
+  auto session_id = session_id_;
+  auto backend_type = backend_type_;
+  PERFETTO_CHECK(!muxer->task_runner_->RunsTasksOnCurrentThread());
+  base::WaitableEvent event;
+  muxer->task_runner_->PostTask([muxer, session_id, backend_type, &event] {
+    muxer->AbortStartupTracingSession(session_id, backend_type);
+    event.Notify();
+  });
+  event.Wait();
+}
+
+// ----- End of TracingMuxerImpl::StartupTracingSessionImpl
+
+// static
+TracingMuxer* TracingMuxer::instance_ = TracingMuxerFake::Get();
+
+// This is called by perfetto::Tracing::Initialize().
+// Can be called on any thread. Typically, but not necessarily, that will be
+// the embedder's main thread.
+TracingMuxerImpl::TracingMuxerImpl(const TracingInitArgs& args)
+    : TracingMuxer(args.platform ? args.platform
+                                 : Platform::GetDefaultPlatform()) {
+  PERFETTO_DETACH_FROM_THREAD(thread_checker_);
+  instance_ = this;
+
+  // Create the thread where muxer, producers and service will live.
+  Platform::CreateTaskRunnerArgs tr_args{/*name_for_debugging=*/"TracingMuxer"};
+  task_runner_.reset(new NonReentrantTaskRunner(
+      this, platform_->CreateTaskRunner(std::move(tr_args))));
+
+  // Run the initializer on that thread.
+  task_runner_->PostTask([this, args] {
+    Initialize(args);
+    AddBackends(args);
+  });
+}
+
+void TracingMuxerImpl::Initialize(const TracingInitArgs& args) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);  // Rebind the thread checker.
+
+  policy_ = args.tracing_policy;
+  supports_multiple_data_source_instances_ =
+      args.supports_multiple_data_source_instances;
+
+  // Fallback backend for producer creation for an unsupported backend type.
+  PERFETTO_CHECK(producer_backends_.empty());
+  AddProducerBackend(internal::TracingBackendFake::GetInstance(),
+                     BackendType::kUnspecifiedBackend, args);
+  // Fallback backend for consumer creation for an unsupported backend type.
+  // This backend simply fails any attempt to start a tracing session.
+  PERFETTO_CHECK(consumer_backends_.empty());
+  AddConsumerBackend(internal::TracingBackendFake::GetInstance(),
+                     BackendType::kUnspecifiedBackend);
+}
+
+void TracingMuxerImpl::AddConsumerBackend(TracingConsumerBackend* backend,
+                                          BackendType type) {
+  if (!backend) {
+    // We skip the log in release builds because the *_backend_fake.cc code
+    // has already an ELOG before returning a nullptr.
+    PERFETTO_DLOG("Consumer backend creation failed, type %d",
+                  static_cast<int>(type));
+    return;
+  }
+  // Keep the backends sorted by type.
+  auto it =
+      std::upper_bound(consumer_backends_.begin(), consumer_backends_.end(),
+                       type, CompareBackendByType<RegisteredConsumerBackend>());
+  it = consumer_backends_.emplace(it);
+
+  RegisteredConsumerBackend& rb = *it;
+  rb.backend = backend;
+  rb.type = type;
+}
+
+void TracingMuxerImpl::AddProducerBackend(TracingProducerBackend* backend,
+                                          BackendType type,
+                                          const TracingInitArgs& args) {
+  if (!backend) {
+    // We skip the log in release builds because the *_backend_fake.cc code
+    // has already an ELOG before returning a nullptr.
+    PERFETTO_DLOG("Producer backend creation failed, type %d",
+                  static_cast<int>(type));
+    return;
+  }
+  TracingBackendId backend_id = producer_backends_.size();
+  // Keep the backends sorted by type.
+  auto it =
+      std::upper_bound(producer_backends_.begin(), producer_backends_.end(),
+                       type, CompareBackendByType<RegisteredProducerBackend>());
+  it = producer_backends_.emplace(it);
+
+  RegisteredProducerBackend& rb = *it;
+  rb.backend = backend;
+  rb.id = backend_id;
+  rb.type = type;
+  rb.producer.reset(new ProducerImpl(this, backend_id,
+                                     args.shmem_batch_commits_duration_ms,
+                                     args.shmem_direct_patching_enabled));
+  rb.producer_conn_args.producer = rb.producer.get();
+  rb.producer_conn_args.producer_name = platform_->GetCurrentProcessName();
+  rb.producer_conn_args.task_runner = task_runner_.get();
+  rb.producer_conn_args.shmem_size_hint_bytes = args.shmem_size_hint_kb * 1024;
+  rb.producer_conn_args.shmem_page_size_hint_bytes =
+      args.shmem_page_size_hint_kb * 1024;
+  rb.producer_conn_args.create_socket_async = args.create_socket_async;
+  rb.producer->Initialize(rb.backend->ConnectProducer(rb.producer_conn_args));
+}
+
+TracingMuxerImpl::RegisteredProducerBackend*
+TracingMuxerImpl::FindProducerBackendById(TracingBackendId id) {
+  for (RegisteredProducerBackend& b : producer_backends_) {
+    if (b.id == id) {
+      return &b;
+    }
+  }
+  return nullptr;
+}
+
+TracingMuxerImpl::RegisteredProducerBackend*
+TracingMuxerImpl::FindProducerBackendByType(BackendType type) {
+  for (RegisteredProducerBackend& b : producer_backends_) {
+    if (b.type == type) {
+      return &b;
+    }
+  }
+  return nullptr;
+}
+
+TracingMuxerImpl::RegisteredConsumerBackend*
+TracingMuxerImpl::FindConsumerBackendByType(BackendType type) {
+  for (RegisteredConsumerBackend& b : consumer_backends_) {
+    if (b.type == type) {
+      return &b;
+    }
+  }
+  return nullptr;
+}
+
+void TracingMuxerImpl::AddBackends(const TracingInitArgs& args) {
+  if (args.backends & kSystemBackend) {
+    PERFETTO_CHECK(args.system_producer_backend_factory_);
+    if (FindProducerBackendByType(kSystemBackend) == nullptr) {
+      AddProducerBackend(args.system_producer_backend_factory_(),
+                         kSystemBackend, args);
+    }
+    if (args.enable_system_consumer) {
+      PERFETTO_CHECK(args.system_consumer_backend_factory_);
+      if (FindConsumerBackendByType(kSystemBackend) == nullptr) {
+        AddConsumerBackend(args.system_consumer_backend_factory_(),
+                           kSystemBackend);
+      }
+    }
+  }
+
+  if (args.backends & kInProcessBackend) {
+    TracingBackend* b = nullptr;
+    if (FindProducerBackendByType(kInProcessBackend) == nullptr) {
+      if (!b) {
+        PERFETTO_CHECK(args.in_process_backend_factory_);
+        b = args.in_process_backend_factory_();
+      }
+      AddProducerBackend(b, kInProcessBackend, args);
+    }
+    if (FindConsumerBackendByType(kInProcessBackend) == nullptr) {
+      if (!b) {
+        PERFETTO_CHECK(args.in_process_backend_factory_);
+        b = args.in_process_backend_factory_();
+      }
+      AddConsumerBackend(b, kInProcessBackend);
+    }
+  }
+
+  if (args.backends & kCustomBackend) {
+    PERFETTO_CHECK(args.custom_backend);
+    if (FindProducerBackendByType(kCustomBackend) == nullptr) {
+      AddProducerBackend(args.custom_backend, kCustomBackend, args);
+    }
+    if (FindConsumerBackendByType(kCustomBackend) == nullptr) {
+      AddConsumerBackend(args.custom_backend, kCustomBackend);
+    }
+  }
+
+  if (args.backends & ~(kSystemBackend | kInProcessBackend | kCustomBackend)) {
+    PERFETTO_FATAL("Unsupported tracing backend type");
+  }
+}
+
+// Can be called from any thread (but not concurrently).
+bool TracingMuxerImpl::RegisterDataSource(
+    const DataSourceDescriptor& descriptor,
+    DataSourceFactory factory,
+    DataSourceParams params,
+    DataSourceStaticState* static_state) {
+  // Ignore repeated registrations.
+  if (static_state->index != kMaxDataSources)
+    return true;
+
+  uint32_t new_index = next_data_source_index_++;
+  if (new_index >= kMaxDataSources) {
+    PERFETTO_DLOG(
+        "RegisterDataSource failed: too many data sources already registered");
+    return false;
+  }
+
+  // Initialize the static state.
+  static_assert(sizeof(static_state->instances[0]) >= sizeof(DataSourceState),
+                "instances[] size mismatch");
+  for (size_t i = 0; i < static_state->instances.size(); i++)
+    new (&static_state->instances[i]) DataSourceState{};
+
+  static_state->index = new_index;
+
+  // Generate a semi-unique id for this data source.
+  base::Hasher hash;
+  hash.Update(reinterpret_cast<intptr_t>(static_state));
+  hash.Update(base::GetWallTimeNs().count());
+  static_state->id = hash.digest() ? hash.digest() : 1;
+
+  task_runner_->PostTask([this, descriptor, factory, static_state, params] {
+    data_sources_.emplace_back();
+    RegisteredDataSource& rds = data_sources_.back();
+    rds.descriptor = descriptor;
+    rds.factory = factory;
+    rds.supports_multiple_instances =
+        supports_multiple_data_source_instances_ &&
+        params.supports_multiple_instances;
+    rds.requires_callbacks_under_lock = params.requires_callbacks_under_lock;
+    rds.static_state = static_state;
+
+    UpdateDataSourceOnAllBackends(rds, /*is_changed=*/false);
+  });
+  return true;
+}
+
+// Can be called from any thread (but not concurrently).
+void TracingMuxerImpl::UpdateDataSourceDescriptor(
+    const DataSourceDescriptor& descriptor,
+    const DataSourceStaticState* static_state) {
+  task_runner_->PostTask([this, descriptor, static_state] {
+    for (auto& rds : data_sources_) {
+      if (rds.static_state == static_state) {
+        PERFETTO_CHECK(rds.descriptor.name() == descriptor.name());
+        rds.descriptor = descriptor;
+        rds.descriptor.set_id(static_state->id);
+        UpdateDataSourceOnAllBackends(rds, /*is_changed=*/true);
+        return;
+      }
+    }
+  });
+}
+
+// Can be called from any thread (but not concurrently).
+void TracingMuxerImpl::RegisterInterceptor(
+    const InterceptorDescriptor& descriptor,
+    InterceptorFactory factory,
+    InterceptorBase::TLSFactory tls_factory,
+    InterceptorBase::TracePacketCallback packet_callback) {
+  task_runner_->PostTask([this, descriptor, factory, tls_factory,
+                          packet_callback] {
+    // Ignore repeated registrations.
+    for (const auto& interceptor : interceptors_) {
+      if (interceptor.descriptor.name() == descriptor.name()) {
+        PERFETTO_DCHECK(interceptor.tls_factory == tls_factory);
+        PERFETTO_DCHECK(interceptor.packet_callback == packet_callback);
+        return;
+      }
+    }
+    // Only allow certain interceptors for now.
+    if (descriptor.name() != "test_interceptor" &&
+        descriptor.name() != "console" && descriptor.name() != "etwexport") {
+      PERFETTO_ELOG(
+          "Interceptors are experimental. If you want to use them, please "
+          "get in touch with the project maintainers "
+          "(https://perfetto.dev/docs/contributing/"
+          "getting-started#community).");
+      return;
+    }
+    interceptors_.emplace_back();
+    RegisteredInterceptor& interceptor = interceptors_.back();
+    interceptor.descriptor = descriptor;
+    interceptor.factory = factory;
+    interceptor.tls_factory = tls_factory;
+    interceptor.packet_callback = packet_callback;
+  });
+}
+
+void TracingMuxerImpl::ActivateTriggers(
+    const std::vector<std::string>& triggers,
+    uint32_t ttl_ms) {
+  base::TimeMillis expire_time =
+      base::GetWallTimeMs() + base::TimeMillis(ttl_ms);
+  task_runner_->PostTask([this, triggers, expire_time] {
+    for (RegisteredProducerBackend& backend : producer_backends_) {
+      if (backend.producer->connected_) {
+        backend.producer->service_->ActivateTriggers(triggers);
+      } else {
+        for (const std::string& trigger : triggers) {
+          backend.producer->on_connect_triggers_.emplace_back(trigger,
+                                                              expire_time);
+        }
+      }
+    }
+  });
+}
+
+// Checks if there is any matching startup tracing data source instance for a
+// new SetupDataSource call. If so, moves the data source to this tracing
+// session (and its target buffer) and returns true, otherwise returns false.
+static bool MaybeAdoptStartupTracingInDataSource(
+    TracingBackendId backend_id,
+    uint32_t backend_connection_id,
+    DataSourceInstanceID instance_id,
+    const DataSourceConfig& cfg,
+    const std::vector<RegisteredDataSource>& data_sources) {
+  for (const auto& rds : data_sources) {
+    DataSourceStaticState* static_state = rds.static_state;
+    for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+      auto* internal_state = static_state->TryGet(i);
+
+      if (internal_state &&
+          internal_state->startup_target_buffer_reservation.load(
+              std::memory_order_relaxed) &&
+          internal_state->data_source_instance_id == 0 &&
+          internal_state->backend_id == backend_id &&
+          internal_state->backend_connection_id == backend_connection_id &&
+          internal_state->config &&
+          internal_state->data_source->CanAdoptStartupSession(
+              *internal_state->config, cfg)) {
+        PERFETTO_DLOG("Setting up data source %" PRIu64
+                      " %s by adopting it from a startup tracing session",
+                      instance_id, cfg.name().c_str());
+
+        std::lock_guard<std::recursive_mutex> lock(internal_state->lock);
+        // Set the associations. The actual takeover happens in
+        // StartDataSource().
+        internal_state->data_source_instance_id = instance_id;
+        internal_state->buffer_id =
+            static_cast<internal::BufferId>(cfg.target_buffer());
+        internal_state->config.reset(new DataSourceConfig(cfg));
+
+        // TODO(eseckler): Should the data souce config provided by the service
+        // be allowed to specify additional interceptors / additional data
+        // source params?
+
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+// Called by the service of one of the backends.
+void TracingMuxerImpl::SetupDataSource(TracingBackendId backend_id,
+                                       uint32_t backend_connection_id,
+                                       DataSourceInstanceID instance_id,
+                                       const DataSourceConfig& cfg) {
+  PERFETTO_DLOG("Setting up data source %" PRIu64 " %s", instance_id,
+                cfg.name().c_str());
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  // First check if there is any matching startup tracing data source instance.
+  if (MaybeAdoptStartupTracingInDataSource(backend_id, backend_connection_id,
+                                           instance_id, cfg, data_sources_)) {
+    return;
+  }
+
+  for (const auto& rds : data_sources_) {
+    if (rds.descriptor.name() != cfg.name())
+      continue;
+    DataSourceStaticState& static_state = *rds.static_state;
+
+    // If this data source is already active for this exact config, don't start
+    // another instance. This happens when we have several data sources with the
+    // same name, in which case the service sends one SetupDataSource event for
+    // each one. Since we can't map which event maps to which data source, we
+    // ensure each event only starts one data source instance.
+    // TODO(skyostil): Register a unique id with each data source to the service
+    // to disambiguate.
+    bool active_for_config = false;
+    for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+      if (!static_state.TryGet(i))
+        continue;
+      auto* internal_state =
+          reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
+      if (internal_state->backend_id == backend_id &&
+          internal_state->backend_connection_id == backend_connection_id &&
+          internal_state->config && *internal_state->config == cfg) {
+        active_for_config = true;
+        break;
+      }
+    }
+    if (active_for_config) {
+      PERFETTO_DLOG(
+          "Data source %s is already active with this config, skipping",
+          cfg.name().c_str());
+      continue;
+    }
+
+    SetupDataSourceImpl(rds, backend_id, backend_connection_id, instance_id,
+                        cfg, /*startup_session_id=*/0);
+    return;
+  }
+}
+
+TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::SetupDataSourceImpl(
+    const RegisteredDataSource& rds,
+    TracingBackendId backend_id,
+    uint32_t backend_connection_id,
+    DataSourceInstanceID instance_id,
+    const DataSourceConfig& cfg,
+    TracingSessionGlobalID startup_session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  DataSourceStaticState& static_state = *rds.static_state;
+
+  // If any bit is set in `static_state.valid_instances` then at least one
+  // other instance of data source is running.
+  if (!rds.supports_multiple_instances &&
+      static_state.valid_instances.load(std::memory_order_acquire) != 0) {
+    PERFETTO_ELOG(
+        "Failed to setup data source because some another instance of this "
+        "data source is already active");
+    return FindDataSourceRes();
+  }
+
+  for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+    // Find a free slot.
+    if (static_state.TryGet(i))
+      continue;
+
+    auto* internal_state =
+        reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
+    std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
+    static_assert(
+        std::is_same<decltype(internal_state->data_source_instance_id),
+                     DataSourceInstanceID>::value,
+        "data_source_instance_id type mismatch");
+    internal_state->muxer_id_for_testing = muxer_id_for_testing_;
+    RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
+
+    if (startup_session_id) {
+      uint16_t& last_reservation =
+          backend.producer->last_startup_target_buffer_reservation_;
+      if (last_reservation == std::numeric_limits<uint16_t>::max()) {
+        PERFETTO_ELOG(
+            "Startup buffer reservations exhausted, dropping data source");
+        return FindDataSourceRes();
+      }
+      internal_state->startup_target_buffer_reservation.store(
+          ++last_reservation, std::memory_order_relaxed);
+    } else {
+      internal_state->startup_target_buffer_reservation.store(
+          0, std::memory_order_relaxed);
+    }
+
+    internal_state->backend_id = backend_id;
+    internal_state->backend_connection_id = backend_connection_id;
+    internal_state->data_source_instance_id = instance_id;
+    internal_state->buffer_id =
+        static_cast<internal::BufferId>(cfg.target_buffer());
+    internal_state->config.reset(new DataSourceConfig(cfg));
+    internal_state->startup_session_id = startup_session_id;
+    internal_state->data_source = rds.factory();
+    internal_state->interceptor = nullptr;
+    internal_state->interceptor_id = 0;
+
+    if (cfg.has_interceptor_config()) {
+      for (size_t j = 0; j < interceptors_.size(); j++) {
+        if (cfg.interceptor_config().name() ==
+            interceptors_[j].descriptor.name()) {
+          PERFETTO_DLOG("Intercepting data source %" PRIu64
+                        " \"%s\" into \"%s\"",
+                        instance_id, cfg.name().c_str(),
+                        cfg.interceptor_config().name().c_str());
+          internal_state->interceptor_id = static_cast<uint32_t>(j + 1);
+          internal_state->interceptor = interceptors_[j].factory();
+          internal_state->interceptor->OnSetup({cfg});
+          break;
+        }
+      }
+      if (!internal_state->interceptor_id) {
+        PERFETTO_ELOG("Unknown interceptor configured for data source: %s",
+                      cfg.interceptor_config().name().c_str());
+      }
+    }
+
+    // This must be made at the end. See matching acquire-load in
+    // DataSource::Trace().
+    static_state.valid_instances.fetch_or(1 << i, std::memory_order_release);
+
+    DataSourceBase::SetupArgs setup_args;
+    setup_args.config = &cfg;
+    setup_args.backend_type = backend.type;
+    setup_args.internal_instance_index = i;
+
+    if (!rds.requires_callbacks_under_lock)
+      lock.unlock();
+    internal_state->data_source->OnSetup(setup_args);
+
+    return FindDataSourceRes(&static_state, internal_state, i,
+                             rds.requires_callbacks_under_lock);
+  }
+  PERFETTO_ELOG(
+      "Maximum number of data source instances exhausted. "
+      "Dropping data source %" PRIu64,
+      instance_id);
+  return FindDataSourceRes();
+}
+
+// Called by the service of one of the backends.
+void TracingMuxerImpl::StartDataSource(TracingBackendId backend_id,
+                                       DataSourceInstanceID instance_id) {
+  PERFETTO_DLOG("Starting data source %" PRIu64, instance_id);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto ds = FindDataSource(backend_id, instance_id);
+  if (!ds) {
+    PERFETTO_ELOG("Could not find data source to start");
+    return;
+  }
+
+  // Check if the data source was already started for startup tracing.
+  uint16_t startup_reservation =
+      ds.internal_state->startup_target_buffer_reservation.load(
+          std::memory_order_relaxed);
+  if (startup_reservation) {
+    RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
+    TracingSessionGlobalID session_id = ds.internal_state->startup_session_id;
+    auto session_it = std::find_if(
+        backend.startup_sessions.begin(), backend.startup_sessions.end(),
+        [session_id](const RegisteredStartupSession& session) {
+          return session.session_id == session_id;
+        });
+    PERFETTO_DCHECK(session_it != backend.startup_sessions.end());
+
+    if (session_it->is_aborting) {
+      PERFETTO_DLOG("Data source %" PRIu64
+                    " was already aborted for startup tracing, not starting it",
+                    instance_id);
+      return;
+    }
+
+    PERFETTO_DLOG(
+        "Data source %" PRIu64
+        " was already started for startup tracing, binding its target buffer",
+        instance_id);
+
+    backend.producer->service_->MaybeSharedMemoryArbiter()
+        ->BindStartupTargetBuffer(startup_reservation,
+                                  ds.internal_state->buffer_id);
+
+    // The reservation ID can be used even after binding it, so there's no need
+    // for any barriers here - we just need atomicity.
+    ds.internal_state->startup_target_buffer_reservation.store(
+        0, std::memory_order_relaxed);
+
+    // TODO(eseckler): Should we reset incremental state at this point, or
+    // notify the data source some other way?
+
+    // The session should not have been fully bound yet (or aborted).
+    PERFETTO_DCHECK(session_it->num_unbound_data_sources > 0);
+
+    session_it->num_unbound_data_sources--;
+    if (session_it->num_unbound_data_sources == 0) {
+      if (session_it->on_adopted)
+        task_runner_->PostTask(session_it->on_adopted);
+      backend.startup_sessions.erase(session_it);
+    }
+    return;
+  }
+
+  StartDataSourceImpl(ds);
+}
+
+void TracingMuxerImpl::StartDataSourceImpl(const FindDataSourceRes& ds) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  DataSourceBase::StartArgs start_args{};
+  start_args.internal_instance_index = ds.instance_idx;
+
+  std::unique_lock<std::recursive_mutex> lock(ds.internal_state->lock);
+  if (ds.internal_state->interceptor)
+    ds.internal_state->interceptor->OnStart({});
+  ds.internal_state->trace_lambda_enabled.store(true,
+                                                std::memory_order_relaxed);
+  PERFETTO_DCHECK(ds.internal_state->data_source != nullptr);
+
+  if (!ds.requires_callbacks_under_lock)
+    lock.unlock();
+  ds.internal_state->data_source->OnStart(start_args);
+}
+
+// Called by the service of one of the backends.
+void TracingMuxerImpl::StopDataSource_AsyncBegin(
+    TracingBackendId backend_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DLOG("Stopping data source %" PRIu64, instance_id);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto ds = FindDataSource(backend_id, instance_id);
+  if (!ds) {
+    PERFETTO_ELOG("Could not find data source to stop");
+    return;
+  }
+
+  StopDataSource_AsyncBeginImpl(ds);
+}
+
+void TracingMuxerImpl::StopDataSource_AsyncBeginImpl(
+    const FindDataSourceRes& ds) {
+  TracingBackendId backend_id = ds.internal_state->backend_id;
+  uint32_t backend_connection_id = ds.internal_state->backend_connection_id;
+  DataSourceInstanceID instance_id = ds.internal_state->data_source_instance_id;
+
+  StopArgsImpl stop_args{};
+  stop_args.internal_instance_index = ds.instance_idx;
+  stop_args.async_stop_closure = [this, backend_id, backend_connection_id,
+                                  instance_id, ds] {
+    // TracingMuxerImpl is long lived, capturing |this| is okay.
+    // The notification closure can be moved out of the StopArgs by the
+    // embedder to handle stop asynchronously. The embedder might then
+    // call the closure on a different thread than the current one, hence
+    // this nested PostTask().
+    task_runner_->PostTask(
+        [this, backend_id, backend_connection_id, instance_id, ds] {
+          StopDataSource_AsyncEnd(backend_id, backend_connection_id,
+                                  instance_id, ds);
+        });
+  };
+
+  {
+    std::unique_lock<std::recursive_mutex> lock(ds.internal_state->lock);
+    if (ds.internal_state->interceptor)
+      ds.internal_state->interceptor->OnStop({});
+
+    if (!ds.requires_callbacks_under_lock)
+      lock.unlock();
+    ds.internal_state->data_source->OnStop(stop_args);
+  }
+
+  // If the embedder hasn't called StopArgs.HandleStopAsynchronously() run the
+  // async closure here. In theory we could avoid the PostTask and call
+  // straight into CompleteDataSourceAsyncStop(). We keep that to reduce
+  // divergencies between the deferred-stop vs non-deferred-stop code paths.
+  if (stop_args.async_stop_closure)
+    std::move(stop_args.async_stop_closure)();
+}
+
+void TracingMuxerImpl::StopDataSource_AsyncEnd(TracingBackendId backend_id,
+                                               uint32_t backend_connection_id,
+                                               DataSourceInstanceID instance_id,
+                                               const FindDataSourceRes& ds) {
+  PERFETTO_DLOG("Ending async stop of data source %" PRIu64, instance_id);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  // Check that the data source instance is still active and was not modified
+  // while it was being stopped.
+  if (!ds.static_state->TryGet(ds.instance_idx) ||
+      ds.internal_state->backend_id != backend_id ||
+      ds.internal_state->backend_connection_id != backend_connection_id ||
+      ds.internal_state->data_source_instance_id != instance_id) {
+    PERFETTO_ELOG(
+        "Async stop of data source %" PRIu64
+        " failed. This might be due to calling the async_stop_closure twice.",
+        instance_id);
+    return;
+  }
+
+  const uint32_t mask = ~(1 << ds.instance_idx);
+  ds.static_state->valid_instances.fetch_and(mask, std::memory_order_acq_rel);
+
+  // Take the mutex to prevent that the data source is in the middle of
+  // a Trace() execution where it called GetDataSourceLocked() while we
+  // destroy it.
+  uint16_t startup_buffer_reservation;
+  TracingSessionGlobalID startup_session_id;
+  {
+    std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
+    ds.internal_state->trace_lambda_enabled.store(false,
+                                                  std::memory_order_relaxed);
+    ds.internal_state->data_source.reset();
+    ds.internal_state->interceptor.reset();
+    ds.internal_state->config.reset();
+    startup_buffer_reservation =
+        ds.internal_state->startup_target_buffer_reservation.load(
+            std::memory_order_relaxed);
+    startup_session_id = ds.internal_state->startup_session_id;
+  }
+
+  // The other fields of internal_state are deliberately *not* cleared.
+  // See races-related comments of DataSource::Trace().
+
+  TracingMuxer::generation_++;
+
+  // |producer_backends_| is append-only, Backend instances are always valid.
+  PERFETTO_CHECK(backend_id < producer_backends_.size());
+  RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
+  ProducerImpl* producer = backend.producer.get();
+  if (!producer)
+    return;
+
+  // If the data source instance still has a startup buffer reservation, it was
+  // only active for startup tracing and never started by the service. Discard
+  // the startup buffer reservation.
+  if (startup_buffer_reservation) {
+    PERFETTO_DCHECK(startup_session_id);
+
+    if (producer->service_ && producer->service_->MaybeSharedMemoryArbiter()) {
+      producer->service_->MaybeSharedMemoryArbiter()
+          ->AbortStartupTracingForReservation(startup_buffer_reservation);
+    }
+
+    auto session_it = std::find_if(
+        backend.startup_sessions.begin(), backend.startup_sessions.end(),
+        [startup_session_id](const RegisteredStartupSession& session) {
+          return session.session_id == startup_session_id;
+        });
+
+    // Session should not be removed until abortion of all data source instances
+    // is complete.
+    PERFETTO_DCHECK(session_it != backend.startup_sessions.end());
+
+    session_it->num_aborting_data_sources--;
+    if (session_it->num_aborting_data_sources == 0) {
+      if (session_it->on_aborted)
+        task_runner_->PostTask(session_it->on_aborted);
+
+      backend.startup_sessions.erase(session_it);
+    }
+  }
+
+  if (producer->connected_ &&
+      backend.producer->connection_id_.load(std::memory_order_relaxed) ==
+          backend_connection_id) {
+    // Flush any commits that might have been batched by SharedMemoryArbiter.
+    producer->service_->MaybeSharedMemoryArbiter()
+        ->FlushPendingCommitDataRequests();
+    if (instance_id)
+      producer->service_->NotifyDataSourceStopped(instance_id);
+  }
+  producer->SweepDeadServices();
+}
+
+void TracingMuxerImpl::ClearDataSourceIncrementalState(
+    TracingBackendId backend_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Clearing incremental state for data source %" PRIu64,
+                instance_id);
+  auto ds = FindDataSource(backend_id, instance_id);
+  if (!ds) {
+    PERFETTO_ELOG("Could not find data source to clear incremental state for");
+    return;
+  }
+
+  DataSourceBase::ClearIncrementalStateArgs clear_incremental_state_args;
+  clear_incremental_state_args.internal_instance_index = ds.instance_idx;
+  {
+    std::unique_lock<std::recursive_mutex> lock;
+    if (ds.requires_callbacks_under_lock)
+      lock = std::unique_lock<std::recursive_mutex>(ds.internal_state->lock);
+    ds.internal_state->data_source->WillClearIncrementalState(
+        clear_incremental_state_args);
+  }
+
+  // Make DataSource::TraceContext::GetIncrementalState() eventually notice that
+  // the incremental state should be cleared.
+  ds.static_state->incremental_state_generation.fetch_add(
+      1, std::memory_order_relaxed);
+}
+
+bool TracingMuxerImpl::FlushDataSource_AsyncBegin(
+    TracingBackendId backend_id,
+    DataSourceInstanceID instance_id,
+    FlushRequestID flush_id,
+    FlushFlags flush_flags) {
+  PERFETTO_DLOG("Flushing data source %" PRIu64, instance_id);
+  auto ds = FindDataSource(backend_id, instance_id);
+  if (!ds) {
+    PERFETTO_ELOG("Could not find data source to flush");
+    return true;
+  }
+
+  uint32_t backend_connection_id = ds.internal_state->backend_connection_id;
+
+  FlushArgsImpl flush_args;
+  flush_args.flush_flags = flush_flags;
+  flush_args.internal_instance_index = ds.instance_idx;
+  flush_args.async_flush_closure = [this, backend_id, backend_connection_id,
+                                    instance_id, ds, flush_id] {
+    // TracingMuxerImpl is long lived, capturing |this| is okay.
+    // The notification closure can be moved out of the StopArgs by the
+    // embedder to handle stop asynchronously. The embedder might then
+    // call the closure on a different thread than the current one, hence
+    // this nested PostTask().
+    task_runner_->PostTask(
+        [this, backend_id, backend_connection_id, instance_id, ds, flush_id] {
+          FlushDataSource_AsyncEnd(backend_id, backend_connection_id,
+                                   instance_id, ds, flush_id);
+        });
+  };
+  {
+    std::unique_lock<std::recursive_mutex> lock;
+    if (ds.requires_callbacks_under_lock)
+      lock = std::unique_lock<std::recursive_mutex>(ds.internal_state->lock);
+    ds.internal_state->data_source->OnFlush(flush_args);
+  }
+
+  // |async_flush_closure| is moved out of |flush_args| if the producer
+  // requested to handle the flush asynchronously.
+  bool handled = static_cast<bool>(flush_args.async_flush_closure);
+  return handled;
+}
+
+void TracingMuxerImpl::FlushDataSource_AsyncEnd(
+    TracingBackendId backend_id,
+    uint32_t backend_connection_id,
+    DataSourceInstanceID instance_id,
+    const FindDataSourceRes& ds,
+    FlushRequestID flush_id) {
+  PERFETTO_DLOG("Ending async flush of data source %" PRIu64, instance_id);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  // Check that the data source instance is still active and was not modified
+  // while it was being flushed.
+  if (!ds.static_state->TryGet(ds.instance_idx) ||
+      ds.internal_state->backend_id != backend_id ||
+      ds.internal_state->backend_connection_id != backend_connection_id ||
+      ds.internal_state->data_source_instance_id != instance_id) {
+    PERFETTO_ELOG("Async flush of data source %" PRIu64
+                  " failed. This might be due to the data source being stopped "
+                  "in the meantime",
+                  instance_id);
+    return;
+  }
+
+  // |producer_backends_| is append-only, Backend instances are always valid.
+  PERFETTO_CHECK(backend_id < producer_backends_.size());
+  RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
+
+  ProducerImpl* producer = backend.producer.get();
+  if (!producer)
+    return;
+
+  // If the tracing service disconnects and reconnects while a data source is
+  // handling a flush request, there's no point is sending the flush reply to
+  // the newly reconnected producer.
+  if (producer->connected_ &&
+      backend.producer->connection_id_.load(std::memory_order_relaxed) ==
+          backend_connection_id) {
+    producer->NotifyFlushForDataSourceDone(instance_id, flush_id);
+  }
+}
+
+void TracingMuxerImpl::SyncProducersForTesting() {
+  std::mutex mutex;
+  std::condition_variable cv;
+
+  // IPC-based producers don't report connection errors explicitly for each
+  // command, but instead with an asynchronous callback
+  // (ProducerImpl::OnDisconnected). This means that the sync command below
+  // may have completed but failed to reach the service because of a
+  // disconnection, but we can't tell until the disconnection message comes
+  // through. To guard against this, we run two whole rounds of sync round-trips
+  // before returning; the first one will detect any disconnected producers and
+  // the second one will ensure any reconnections have completed and all data
+  // sources are registered in the service again.
+  for (size_t i = 0; i < 2; i++) {
+    size_t countdown = std::numeric_limits<size_t>::max();
+    task_runner_->PostTask([this, &mutex, &cv, &countdown] {
+      {
+        std::unique_lock<std::mutex> countdown_lock(mutex);
+        countdown = producer_backends_.size();
+      }
+      for (auto& backend : producer_backends_) {
+        auto* producer = backend.producer.get();
+        producer->service_->Sync([&mutex, &cv, &countdown] {
+          std::unique_lock<std::mutex> countdown_lock(mutex);
+          countdown--;
+          cv.notify_one();
+        });
+      }
+    });
+
+    {
+      std::unique_lock<std::mutex> countdown_lock(mutex);
+      cv.wait(countdown_lock, [&countdown] { return !countdown; });
+    }
+  }
+
+  // Check that all producers are indeed connected.
+  bool done = false;
+  bool all_producers_connected = true;
+  task_runner_->PostTask([this, &mutex, &cv, &done, &all_producers_connected] {
+    for (auto& backend : producer_backends_)
+      all_producers_connected &= backend.producer->connected_;
+    std::unique_lock<std::mutex> lock(mutex);
+    done = true;
+    cv.notify_one();
+  });
+
+  {
+    std::unique_lock<std::mutex> lock(mutex);
+    cv.wait(lock, [&done] { return done; });
+  }
+  PERFETTO_DCHECK(all_producers_connected);
+}
+
+void TracingMuxerImpl::DestroyStoppedTraceWritersForCurrentThread() {
+  // Iterate across all possible data source types.
+  auto cur_generation = generation_.load(std::memory_order_acquire);
+  auto* root_tls = GetOrCreateTracingTLS();
+
+  auto destroy_stopped_instances = [](DataSourceThreadLocalState& tls) {
+    // |tls| has a vector of per-data-source-instance thread-local state.
+    DataSourceStaticState* static_state = tls.static_state;
+    if (!static_state)
+      return;  // Slot not used.
+
+    // Iterate across all possible instances for this data source.
+    for (uint32_t inst = 0; inst < kMaxDataSourceInstances; inst++) {
+      DataSourceInstanceThreadLocalState& ds_tls = tls.per_instance[inst];
+      if (!ds_tls.trace_writer)
+        continue;
+
+      DataSourceState* ds_state = static_state->TryGet(inst);
+      if (ds_state &&
+          ds_state->muxer_id_for_testing == ds_tls.muxer_id_for_testing &&
+          ds_state->backend_id == ds_tls.backend_id &&
+          ds_state->backend_connection_id == ds_tls.backend_connection_id &&
+          ds_state->startup_target_buffer_reservation.load(
+              std::memory_order_relaxed) ==
+              ds_tls.startup_target_buffer_reservation &&
+          ds_state->buffer_id == ds_tls.buffer_id &&
+          ds_state->data_source_instance_id == ds_tls.data_source_instance_id) {
+        continue;
+      }
+
+      // The DataSource instance has been destroyed or recycled.
+      ds_tls.Reset();  // Will also destroy the |ds_tls.trace_writer|.
+    }
+  };
+
+  for (size_t ds_idx = 0; ds_idx < kMaxDataSources; ds_idx++) {
+    // |tls| has a vector of per-data-source-instance thread-local state.
+    DataSourceThreadLocalState& tls = root_tls->data_sources_tls[ds_idx];
+    destroy_stopped_instances(tls);
+  }
+  destroy_stopped_instances(root_tls->track_event_tls);
+  root_tls->generation = cur_generation;
+}
+
+// Called both when a new data source is registered or when a new backend
+// connects. In both cases we want to be sure we reflected the data source
+// registrations on the backends.
+void TracingMuxerImpl::UpdateDataSourcesOnAllBackends() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredDataSource& rds : data_sources_) {
+    UpdateDataSourceOnAllBackends(rds, /*is_changed=*/false);
+  }
+}
+
+void TracingMuxerImpl::UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
+                                                     bool is_changed) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredProducerBackend& backend : producer_backends_) {
+    // We cannot call RegisterDataSource on the backend before it connects.
+    if (!backend.producer->connected_)
+      continue;
+
+    PERFETTO_DCHECK(rds.static_state->index < kMaxDataSources);
+    bool is_registered = backend.producer->registered_data_sources_.test(
+        rds.static_state->index);
+    if (is_registered && !is_changed)
+      continue;
+
+    rds.descriptor.set_will_notify_on_start(true);
+    rds.descriptor.set_will_notify_on_stop(true);
+    rds.descriptor.set_handles_incremental_state_clear(true);
+    rds.descriptor.set_id(rds.static_state->id);
+    if (is_registered) {
+      backend.producer->service_->UpdateDataSource(rds.descriptor);
+    } else {
+      backend.producer->service_->RegisterDataSource(rds.descriptor);
+    }
+    backend.producer->registered_data_sources_.set(rds.static_state->index);
+  }
+}
+
+void TracingMuxerImpl::SetupTracingSession(
+    TracingSessionGlobalID session_id,
+    const std::shared_ptr<TraceConfig>& trace_config,
+    base::ScopedFile trace_fd) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_CHECK(!trace_fd || trace_config->write_into_file());
+
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer)
+    return;
+
+  consumer->trace_config_ = trace_config;
+  if (trace_fd)
+    consumer->trace_fd_ = std::move(trace_fd);
+
+  if (!consumer->connected_)
+    return;
+
+  // Only used in the deferred start mode.
+  if (trace_config->deferred_start()) {
+    consumer->service_->EnableTracing(*trace_config,
+                                      std::move(consumer->trace_fd_));
+  }
+}
+
+void TracingMuxerImpl::StartTracingSession(TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto* consumer = FindConsumer(session_id);
+
+  if (!consumer)
+    return;
+
+  if (!consumer->trace_config_) {
+    PERFETTO_ELOG("Must call Setup(config) first");
+    return;
+  }
+
+  if (!consumer->connected_) {
+    consumer->start_pending_ = true;
+    return;
+  }
+
+  consumer->start_pending_ = false;
+  if (consumer->trace_config_->deferred_start()) {
+    consumer->service_->StartTracing();
+  } else {
+    consumer->service_->EnableTracing(*consumer->trace_config_,
+                                      std::move(consumer->trace_fd_));
+  }
+
+  // TODO implement support for the deferred-start + fast-triggering case.
+}
+
+void TracingMuxerImpl::ChangeTracingSessionConfig(
+    TracingSessionGlobalID session_id,
+    const TraceConfig& trace_config) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto* consumer = FindConsumer(session_id);
+
+  if (!consumer)
+    return;
+
+  if (!consumer->trace_config_) {
+    // Changing the config is only supported for started sessions.
+    PERFETTO_ELOG("Must call Setup(config) and Start() first");
+    return;
+  }
+
+  consumer->trace_config_ = std::make_shared<TraceConfig>(trace_config);
+  if (consumer->connected_)
+    consumer->service_->ChangeTraceConfig(trace_config);
+}
+
+void TracingMuxerImpl::FlushTracingSession(TracingSessionGlobalID session_id,
+                                           uint32_t timeout_ms,
+                                           std::function<void(bool)> callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer || consumer->start_pending_ || consumer->stop_pending_ ||
+      !consumer->trace_config_) {
+    PERFETTO_ELOG("Flush() can be called only after Start() and before Stop()");
+    std::move(callback)(false);
+    return;
+  }
+
+  // For now we don't want to expose the flush reason to the consumer-side SDK
+  // users to avoid misuses until there is a strong need.
+  consumer->service_->Flush(timeout_ms, std::move(callback),
+                            FlushFlags(FlushFlags::Initiator::kConsumerSdk,
+                                       FlushFlags::Reason::kExplicit));
+}
+
+void TracingMuxerImpl::StopTracingSession(TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer)
+    return;
+
+  if (consumer->start_pending_) {
+    // If the session hasn't started yet, wait until it does before stopping.
+    consumer->stop_pending_ = true;
+    return;
+  }
+
+  consumer->stop_pending_ = false;
+  if (consumer->stopped_) {
+    // If the session was already stopped (e.g., it failed to start), don't try
+    // stopping again.
+    consumer->NotifyStopComplete();
+  } else if (!consumer->trace_config_) {
+    PERFETTO_ELOG("Must call Setup(config) and Start() first");
+    return;
+  } else {
+    consumer->service_->DisableTracing();
+  }
+
+  consumer->trace_config_.reset();
+}
+
+void TracingMuxerImpl::DestroyTracingSession(
+    TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredConsumerBackend& backend : consumer_backends_) {
+    // We need to find the consumer (if any) and call Disconnect as we destroy
+    // the tracing session. We can't call Disconnect() inside this for loop
+    // because in the in-process case this will end up to a synchronous call to
+    // OnConsumerDisconnect which will invalidate all the iterators to
+    // |backend.consumers|.
+    ConsumerImpl* consumer = nullptr;
+    for (auto& con : backend.consumers) {
+      if (con->session_id_ == session_id) {
+        consumer = con.get();
+        break;
+      }
+    }
+    if (consumer) {
+      // We broke out of the loop above on the assumption that each backend will
+      // only have a single consumer per session. This DCHECK ensures that
+      // this is the case.
+      PERFETTO_DCHECK(
+          std::count_if(backend.consumers.begin(), backend.consumers.end(),
+                        [session_id](const std::unique_ptr<ConsumerImpl>& con) {
+                          return con->session_id_ == session_id;
+                        }) == 1u);
+      consumer->Disconnect();
+    }
+  }
+}
+
+void TracingMuxerImpl::ReadTracingSessionData(
+    TracingSessionGlobalID session_id,
+    std::function<void(TracingSession::ReadTraceCallbackArgs)> callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer) {
+    // TODO(skyostil): Signal an error to the user.
+    TracingSession::ReadTraceCallbackArgs callback_arg{};
+    callback(callback_arg);
+    return;
+  }
+  PERFETTO_DCHECK(!consumer->read_trace_callback_);
+  consumer->read_trace_callback_ = std::move(callback);
+  consumer->service_->ReadBuffers();
+}
+
+void TracingMuxerImpl::GetTraceStats(
+    TracingSessionGlobalID session_id,
+    TracingSession::GetTraceStatsCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer) {
+    TracingSession::GetTraceStatsCallbackArgs callback_arg{};
+    callback_arg.success = false;
+    callback(std::move(callback_arg));
+    return;
+  }
+  PERFETTO_DCHECK(!consumer->get_trace_stats_callback_);
+  consumer->get_trace_stats_callback_ = std::move(callback);
+  if (!consumer->connected_) {
+    consumer->get_trace_stats_pending_ = true;
+    return;
+  }
+  consumer->get_trace_stats_pending_ = false;
+  consumer->service_->GetTraceStats();
+}
+
+void TracingMuxerImpl::QueryServiceState(
+    TracingSessionGlobalID session_id,
+    TracingSession::QueryServiceStateCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* consumer = FindConsumer(session_id);
+  if (!consumer) {
+    TracingSession::QueryServiceStateCallbackArgs callback_arg{};
+    callback_arg.success = false;
+    callback(std::move(callback_arg));
+    return;
+  }
+  PERFETTO_DCHECK(!consumer->query_service_state_callback_);
+  if (!consumer->connected_) {
+    consumer->query_service_state_callback_ = std::move(callback);
+    return;
+  }
+  auto callback_wrapper = [callback](bool success,
+                                     protos::gen::TracingServiceState state) {
+    TracingSession::QueryServiceStateCallbackArgs callback_arg{};
+    callback_arg.success = success;
+    callback_arg.service_state_data = state.SerializeAsArray();
+    callback(std::move(callback_arg));
+  };
+  consumer->service_->QueryServiceState(std::move(callback_wrapper));
+}
+
+void TracingMuxerImpl::SetBatchCommitsDurationForTesting(
+    uint32_t batch_commits_duration_ms,
+    BackendType backend_type) {
+  for (RegisteredProducerBackend& backend : producer_backends_) {
+    if (backend.producer && backend.producer->connected_ &&
+        backend.type == backend_type) {
+      backend.producer->service_->MaybeSharedMemoryArbiter()
+          ->SetBatchCommitsDuration(batch_commits_duration_ms);
+    }
+  }
+}
+
+bool TracingMuxerImpl::EnableDirectSMBPatchingForTesting(
+    BackendType backend_type) {
+  for (RegisteredProducerBackend& backend : producer_backends_) {
+    if (backend.producer && backend.producer->connected_ &&
+        backend.type == backend_type &&
+        !backend.producer->service_->MaybeSharedMemoryArbiter()
+             ->EnableDirectSMBPatching()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+TracingMuxerImpl::ConsumerImpl* TracingMuxerImpl::FindConsumer(
+    TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  return FindConsumerAndBackend(session_id).first;
+}
+
+std::pair<TracingMuxerImpl::ConsumerImpl*,
+          TracingMuxerImpl::RegisteredConsumerBackend*>
+TracingMuxerImpl::FindConsumerAndBackend(TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredConsumerBackend& backend : consumer_backends_) {
+    for (auto& consumer : backend.consumers) {
+      if (consumer->session_id_ == session_id) {
+        return {consumer.get(), &backend};
+      }
+    }
+  }
+  return {nullptr, nullptr};
+}
+
+void TracingMuxerImpl::InitializeConsumer(TracingSessionGlobalID session_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto res = FindConsumerAndBackend(session_id);
+  if (!res.first || !res.second)
+    return;
+  TracingMuxerImpl::ConsumerImpl* consumer = res.first;
+  RegisteredConsumerBackend& backend = *res.second;
+
+  TracingBackend::ConnectConsumerArgs conn_args;
+  conn_args.consumer = consumer;
+  conn_args.task_runner = task_runner_.get();
+  consumer->Initialize(backend.backend->ConnectConsumer(conn_args));
+}
+
+void TracingMuxerImpl::OnConsumerDisconnected(ConsumerImpl* consumer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredConsumerBackend& backend : consumer_backends_) {
+    auto pred = [consumer](const std::unique_ptr<ConsumerImpl>& con) {
+      return con.get() == consumer;
+    };
+    backend.consumers.erase(std::remove_if(backend.consumers.begin(),
+                                           backend.consumers.end(), pred),
+                            backend.consumers.end());
+  }
+}
+
+void TracingMuxerImpl::SetMaxProducerReconnectionsForTesting(uint32_t count) {
+  max_producer_reconnections_.store(count);
+}
+
+void TracingMuxerImpl::OnProducerDisconnected(ProducerImpl* producer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (RegisteredProducerBackend& backend : producer_backends_) {
+    if (backend.producer.get() != producer)
+      continue;
+
+    // The tracing service is disconnected. It does not make sense to keep
+    // tracing (we wouldn't be able to commit). On reconnection, the tracing
+    // service will restart the data sources.
+    for (const auto& rds : data_sources_) {
+      DataSourceStaticState* static_state = rds.static_state;
+      for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+        auto* internal_state = static_state->TryGet(i);
+        if (internal_state && internal_state->backend_id == backend.id &&
+            internal_state->backend_connection_id ==
+                backend.producer->connection_id_.load(
+                    std::memory_order_relaxed)) {
+          StopDataSource_AsyncBeginImpl(
+              FindDataSourceRes(static_state, internal_state, i,
+                                rds.requires_callbacks_under_lock));
+        }
+      }
+    }
+
+    // Try reconnecting the disconnected producer. If the connection succeeds,
+    // all the data sources will be automatically re-registered.
+    if (producer->connection_id_.load(std::memory_order_relaxed) >
+        max_producer_reconnections_.load()) {
+      // Avoid reconnecting a failing producer too many times. Instead we just
+      // leak the producer instead of trying to avoid further complicating
+      // cross-thread trace writer creation.
+      PERFETTO_ELOG("Producer disconnected too many times; not reconnecting");
+      continue;
+    }
+
+    backend.producer->Initialize(
+        backend.backend->ConnectProducer(backend.producer_conn_args));
+    // Don't use producer-provided SMBs for the next connection unless startup
+    // tracing requires it again.
+    backend.producer_conn_args.use_producer_provided_smb = false;
+  }
+}
+
+void TracingMuxerImpl::SweepDeadBackends() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (auto it = dead_backends_.begin(); it != dead_backends_.end();) {
+    auto next_it = it;
+    next_it++;
+    if (it->producer->SweepDeadServices())
+      dead_backends_.erase(it);
+    it = next_it;
+  }
+}
+
+TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::FindDataSource(
+    TracingBackendId backend_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
+  for (const auto& rds : data_sources_) {
+    DataSourceStaticState* static_state = rds.static_state;
+    for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+      auto* internal_state = static_state->TryGet(i);
+      if (internal_state && internal_state->backend_id == backend_id &&
+          internal_state->backend_connection_id ==
+              backend.producer->connection_id_.load(
+                  std::memory_order_relaxed) &&
+          internal_state->data_source_instance_id == instance_id) {
+        return FindDataSourceRes(static_state, internal_state, i,
+                                 rds.requires_callbacks_under_lock);
+      }
+    }
+  }
+  return FindDataSourceRes();
+}
+
+// Can be called from any thread.
+std::unique_ptr<TraceWriterBase> TracingMuxerImpl::CreateTraceWriter(
+    DataSourceStaticState* static_state,
+    uint32_t data_source_instance_index,
+    DataSourceState* data_source,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  if (PERFETTO_UNLIKELY(data_source->interceptor_id)) {
+    // If the session is being intercepted, return a heap-backed trace writer
+    // instead. This is safe because all the data given to the interceptor is
+    // either thread-local (|instance_index|), statically allocated
+    // (|static_state|) or constant after initialization (|interceptor|). Access
+    // to the interceptor instance itself through |data_source| is protected by
+    // a statically allocated lock (similarly to the data source instance).
+    auto& interceptor = interceptors_[data_source->interceptor_id - 1];
+    return std::unique_ptr<TraceWriterBase>(new InterceptorTraceWriter(
+        interceptor.tls_factory(static_state, data_source_instance_index),
+        interceptor.packet_callback, static_state, data_source_instance_index));
+  }
+  ProducerImpl* producer =
+      FindProducerBackendById(data_source->backend_id)->producer.get();
+  // Atomically load the current service endpoint. We keep the pointer as a
+  // shared pointer on the stack to guard against it from being concurrently
+  // modified on the thread by ProducerImpl::Initialize() swapping in a
+  // reconnected service on the muxer task runner thread.
+  //
+  // The endpoint may also be concurrently modified by SweepDeadServices()
+  // clearing out old disconnected services. We guard against that by
+  // SharedMemoryArbiter keeping track of any outstanding trace writers. After
+  // shutdown has started, the trace writer created below will be a null one
+  // which will drop any written data. See SharedMemoryArbiter::TryShutdown().
+  //
+  // We use an atomic pointer instead of holding a lock because
+  // CreateTraceWriter posts tasks under the hood.
+  std::shared_ptr<ProducerEndpoint> service =
+      std::atomic_load(&producer->service_);
+
+  // The service may have been disconnected and reconnected concurrently after
+  // the data source was enabled, in which case we may not have an arbiter, or
+  // would be creating a TraceWriter for the wrong (a newer) connection / SMB.
+  // Instead, early-out now. A relaxed load is fine here because the atomic_load
+  // above ensures that the |service| isn't newer.
+  if (producer->connection_id_.load(std::memory_order_relaxed) !=
+      data_source->backend_connection_id) {
+    return std::unique_ptr<TraceWriter>(new NullTraceWriter());
+  }
+
+  // We just need a relaxed atomic read here: We can use the reservation ID even
+  // after the buffer was bound, we just need to be sure to read it atomically.
+  uint16_t startup_buffer_reservation =
+      data_source->startup_target_buffer_reservation.load(
+          std::memory_order_relaxed);
+  if (startup_buffer_reservation) {
+    return service->MaybeSharedMemoryArbiter()->CreateStartupTraceWriter(
+        startup_buffer_reservation);
+  }
+  return service->CreateTraceWriter(data_source->buffer_id,
+                                    buffer_exhausted_policy);
+}
+
+// This is called via the public API Tracing::NewTrace().
+// Can be called from any thread.
+std::unique_ptr<TracingSession> TracingMuxerImpl::CreateTracingSession(
+    BackendType requested_backend_type,
+    TracingConsumerBackend* (*system_backend_factory)()) {
+  TracingSessionGlobalID session_id = ++next_tracing_session_id_;
+
+  // |backend_type| can only specify one backend, not an OR-ed mask.
+  PERFETTO_CHECK((requested_backend_type & (requested_backend_type - 1)) == 0);
+
+  // Capturing |this| is fine because the TracingMuxer is a leaky singleton.
+  task_runner_->PostTask([this, requested_backend_type, session_id,
+                          system_backend_factory] {
+    if (requested_backend_type == kSystemBackend && system_backend_factory &&
+        !FindConsumerBackendByType(kSystemBackend)) {
+      AddConsumerBackend(system_backend_factory(), kSystemBackend);
+    }
+    for (RegisteredConsumerBackend& backend : consumer_backends_) {
+      if (requested_backend_type && backend.type &&
+          backend.type != requested_backend_type) {
+        continue;
+      }
+
+      // Create the consumer now, even if we have to ask the embedder below, so
+      // that any other tasks executing after this one can find the consumer and
+      // change its pending attributes.
+      backend.consumers.emplace_back(
+          new ConsumerImpl(this, backend.type, session_id));
+
+      // The last registered backend in |consumer_backends_| is the unsupported
+      // backend without a valid type.
+      if (!backend.type) {
+        PERFETTO_ELOG(
+            "No tracing backend ready for type=%d, consumer will disconnect",
+            requested_backend_type);
+        InitializeConsumer(session_id);
+        return;
+      }
+
+      // Check if the embedder wants to be asked for permission before
+      // connecting the consumer.
+      if (!policy_) {
+        InitializeConsumer(session_id);
+        return;
+      }
+
+      BackendType type = backend.type;
+      TracingPolicy::ShouldAllowConsumerSessionArgs args;
+      args.backend_type = backend.type;
+      args.result_callback = [this, type, session_id](bool allow) {
+        task_runner_->PostTask([this, type, session_id, allow] {
+          if (allow) {
+            InitializeConsumer(session_id);
+            return;
+          }
+
+          PERFETTO_ELOG(
+              "Consumer session for backend type type=%d forbidden, "
+              "consumer will disconnect",
+              type);
+
+          auto* consumer = FindConsumer(session_id);
+          if (!consumer)
+            return;
+
+          consumer->OnDisconnect();
+        });
+      };
+      policy_->ShouldAllowConsumerSession(args);
+      return;
+    }
+    PERFETTO_DFATAL("Not reached");
+  });
+
+  return std::unique_ptr<TracingSession>(
+      new TracingSessionImpl(this, session_id, requested_backend_type));
+}
+
+// static
+// This is called via the public API Tracing::SetupStartupTracing().
+// Can be called from any thread.
+std::unique_ptr<StartupTracingSession>
+TracingMuxerImpl::CreateStartupTracingSession(
+    const TraceConfig& config,
+    Tracing::SetupStartupTracingOpts opts) {
+  BackendType backend_type = opts.backend;
+  // |backend_type| can only specify one backend, not an OR-ed mask.
+  PERFETTO_CHECK((backend_type & (backend_type - 1)) == 0);
+  // The in-process backend doesn't support startup tracing.
+  PERFETTO_CHECK(backend_type != BackendType::kInProcessBackend);
+
+  TracingSessionGlobalID session_id = ++next_tracing_session_id_;
+
+  // Capturing |this| is fine because the TracingMuxer is a leaky singleton.
+  task_runner_->PostTask([this, config, opts, backend_type, session_id] {
+    for (RegisteredProducerBackend& backend : producer_backends_) {
+      if (backend_type && backend.type && backend.type != backend_type) {
+        continue;
+      }
+
+      TracingBackendId backend_id = backend.id;
+
+      // The last registered backend in |producer_backends_| is the unsupported
+      // backend without a valid type.
+      if (!backend.type) {
+        PERFETTO_ELOG(
+            "No tracing backend initialized for type=%d, startup tracing "
+            "failed",
+            backend_type);
+        if (opts.on_setup)
+          opts.on_setup(Tracing::OnStartupTracingSetupCallbackArgs{
+              0 /* num_data_sources_started */});
+        return;
+      }
+
+      if (!backend.producer->service_ ||
+          !backend.producer->service_->shared_memory()) {
+        // If we unsuccessfully attempted to use a producer-provided SMB in the
+        // past, don't try again.
+        if (backend.producer->producer_provided_smb_failed_) {
+          PERFETTO_ELOG(
+              "Backend %zu doesn't seem to support producer-provided "
+              "SMBs, startup tracing failed",
+              backend_id);
+          if (opts.on_setup)
+            opts.on_setup(Tracing::OnStartupTracingSetupCallbackArgs{
+                0 /* num_data_sources_started */});
+          return;
+        }
+
+        PERFETTO_DLOG("Reconnecting backend %zu for startup tracing",
+                      backend_id);
+        backend.producer_conn_args.use_producer_provided_smb = true;
+        backend.producer->service_->Disconnect();  // Causes a reconnect.
+        PERFETTO_DCHECK(backend.producer->service_ &&
+                        backend.producer->service_->MaybeSharedMemoryArbiter());
+      }
+
+      RegisteredStartupSession session;
+      session.session_id = session_id;
+      session.on_aborted = opts.on_aborted;
+      session.on_adopted = opts.on_adopted;
+
+      for (const TraceConfig::DataSource& ds_cfg : config.data_sources()) {
+        // Find all matching data sources and start one instance of each.
+        for (const auto& rds : data_sources_) {
+          if (rds.descriptor.name() != ds_cfg.config().name())
+            continue;
+
+          PERFETTO_DLOG(
+              "Setting up data source %s for startup tracing with target "
+              "buffer reservation %" PRIi32,
+              rds.descriptor.name().c_str(),
+              backend.producer->last_startup_target_buffer_reservation_ + 1u);
+          auto ds = SetupDataSourceImpl(
+              rds, backend_id,
+              backend.producer->connection_id_.load(std::memory_order_relaxed),
+              /*instance_id=*/0, ds_cfg.config(),
+              /*startup_session_id=*/session_id);
+          if (ds) {
+            StartDataSourceImpl(ds);
+            session.num_unbound_data_sources++;
+          }
+        }
+      }
+
+      int num_ds = session.num_unbound_data_sources;
+      auto on_setup = opts.on_setup;
+      if (on_setup) {
+        backend.producer->OnStartupTracingSetup();
+        task_runner_->PostTask([on_setup, num_ds] {
+          on_setup(Tracing::OnStartupTracingSetupCallbackArgs{num_ds});
+        });
+      }
+
+      if (num_ds > 0) {
+        backend.startup_sessions.push_back(std::move(session));
+
+        if (opts.timeout_ms > 0) {
+          task_runner_->PostDelayedTask(
+              [this, session_id, backend_type] {
+                AbortStartupTracingSession(session_id, backend_type);
+              },
+              opts.timeout_ms);
+        }
+      }
+      return;
+    }
+    PERFETTO_DFATAL("Invalid startup tracing session backend");
+  });
+
+  return std::unique_ptr<StartupTracingSession>(
+      new StartupTracingSessionImpl(this, session_id, backend_type));
+}
+
+// Must not be called from the SDK's internal thread.
+std::unique_ptr<StartupTracingSession>
+TracingMuxerImpl::CreateStartupTracingSessionBlocking(
+    const TraceConfig& config,
+    Tracing::SetupStartupTracingOpts opts) {
+  auto previous_on_setup = std::move(opts.on_setup);
+  PERFETTO_CHECK(!task_runner_->RunsTasksOnCurrentThread());
+  base::WaitableEvent event;
+  // It is safe to capture by reference because once on_setup is called only
+  // once before this method returns.
+  opts.on_setup = [&](Tracing::OnStartupTracingSetupCallbackArgs args) {
+    if (previous_on_setup) {
+      previous_on_setup(std::move(args));
+    }
+    event.Notify();
+  };
+  auto session = CreateStartupTracingSession(config, std::move(opts));
+  event.Wait();
+  return session;
+}
+
+void TracingMuxerImpl::AbortStartupTracingSession(
+    TracingSessionGlobalID session_id,
+    BackendType backend_type) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  for (RegisteredProducerBackend& backend : producer_backends_) {
+    if (backend_type != backend.type)
+      continue;
+
+    auto session_it = std::find_if(
+        backend.startup_sessions.begin(), backend.startup_sessions.end(),
+        [session_id](const RegisteredStartupSession& session) {
+          return session.session_id == session_id;
+        });
+
+    // The startup session may have already been aborted or fully adopted.
+    if (session_it == backend.startup_sessions.end())
+      return;
+    if (session_it->is_aborting)
+      return;
+
+    session_it->is_aborting = true;
+
+    // Iterate all data sources and abort them if they weren't adopted yet.
+    for (const auto& rds : data_sources_) {
+      DataSourceStaticState* static_state = rds.static_state;
+      for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
+        auto* internal_state = static_state->TryGet(i);
+        if (internal_state &&
+            internal_state->startup_target_buffer_reservation.load(
+                std::memory_order_relaxed) &&
+            internal_state->data_source_instance_id == 0 &&
+            internal_state->startup_session_id == session_id) {
+          PERFETTO_DLOG(
+              "Aborting startup tracing for data source %s (target buffer "
+              "reservation %" PRIu16 ")",
+              rds.descriptor.name().c_str(),
+              internal_state->startup_target_buffer_reservation.load(
+                  std::memory_order_relaxed));
+
+          // Abort the instance asynchronously by stopping it. From this point
+          // onwards, the service will not be able to adopt it via
+          // StartDataSource().
+          session_it->num_aborting_data_sources++;
+          StopDataSource_AsyncBeginImpl(
+              FindDataSourceRes(static_state, internal_state, i,
+                                rds.requires_callbacks_under_lock));
+        }
+      }
+    }
+
+    // If we did everything right, we should have aborted all still-unbound data
+    // source instances.
+    PERFETTO_DCHECK(session_it->num_unbound_data_sources ==
+                    session_it->num_aborting_data_sources);
+
+    if (session_it->num_aborting_data_sources == 0) {
+      if (session_it->on_aborted)
+        task_runner_->PostTask(session_it->on_aborted);
+
+      backend.startup_sessions.erase(session_it);
+    }
+    return;
+  }
+  // We might reach here in tests because when we start a trace, we post the
+  // Task(AbortStartupTrace, delay=timeout). When we do
+  // perfetto::ResetForTesting, we sweep dead backends, and we are not able to
+  // kill those delayed tasks because TaskRunner doesn't have support for
+  // deleting scheduled future tasks and TaskRunner doesn't have any API for us
+  // to wait for the completion of all the scheduled tasks (apart from
+  // deleting the TaskRunner) and we want to avoid doing that because we need
+  // a long running TaskRunner in muxer.
+  PERFETTO_DLOG("Invalid startup tracing session backend");
+}
+
+void TracingMuxerImpl::InitializeInstance(const TracingInitArgs& args) {
+  if (instance_ != TracingMuxerFake::Get()) {
+    // The tracing muxer was already initialized. We might need to initialize
+    // additional backends that were not configured earlier.
+    auto* muxer = static_cast<TracingMuxerImpl*>(instance_);
+    muxer->task_runner_->PostTask([muxer, args] { muxer->AddBackends(args); });
+    return;
+  }
+  // If we previously had a TracingMuxerImpl instance which was reset,
+  // reinitialize and reuse it instead of trying to create a new one. See
+  // ResetForTesting().
+  if (g_prev_instance) {
+    auto* muxer = g_prev_instance;
+    g_prev_instance = nullptr;
+    instance_ = muxer;
+    muxer->task_runner_->PostTask([muxer, args] {
+      muxer->Initialize(args);
+      muxer->AddBackends(args);
+    });
+  } else {
+    new TracingMuxerImpl(args);
+  }
+}
+
+// static
+void TracingMuxerImpl::ResetForTesting() {
+  // Ideally we'd tear down the entire TracingMuxerImpl, but the lifetimes of
+  // various objects make that a non-starter. In particular:
+  //
+  // 1) Any thread that has entered a trace event has a TraceWriter, which holds
+  //    a reference back to ProducerImpl::service_.
+  //
+  // 2) ProducerImpl::service_ has a reference back to the ProducerImpl.
+  //
+  // 3) ProducerImpl holds reference to TracingMuxerImpl::task_runner_, which in
+  //    turn depends on TracingMuxerImpl itself.
+  //
+  // Because of this, it's not safe to deallocate TracingMuxerImpl until all
+  // threads have dropped their TraceWriters. Since we can't really ask the
+  // caller to guarantee this, we'll instead reset enough of the muxer's state
+  // so that it can be reinitialized later and ensure all necessary objects from
+  // the old state remain alive until all references have gone away.
+  auto* muxer = reinterpret_cast<TracingMuxerImpl*>(instance_);
+
+  base::WaitableEvent reset_done;
+  auto do_reset = [muxer, &reset_done] {
+    muxer->DestroyStoppedTraceWritersForCurrentThread();
+    // Unregister all data sources so they don't interfere with any future
+    // tracing sessions.
+    for (RegisteredDataSource& rds : muxer->data_sources_) {
+      for (RegisteredProducerBackend& backend : muxer->producer_backends_) {
+        if (!backend.producer->service_ || !backend.producer->connected_)
+          continue;
+        backend.producer->service_->UnregisterDataSource(rds.descriptor.name());
+      }
+    }
+    for (auto& backend : muxer->consumer_backends_) {
+      // Check that no consumer session is currently active on any backend.
+      for (auto& consumer : backend.consumers)
+        PERFETTO_CHECK(!consumer->service_);
+    }
+    for (auto& backend : muxer->producer_backends_) {
+      backend.producer->muxer_ = nullptr;
+      backend.producer->DisposeConnection();
+      muxer->dead_backends_.push_back(std::move(backend));
+    }
+    muxer->consumer_backends_.clear();
+    muxer->producer_backends_.clear();
+    muxer->interceptors_.clear();
+
+    for (auto& ds : muxer->data_sources_) {
+      ds.static_state->ResetForTesting();
+    }
+
+    muxer->data_sources_.clear();
+    muxer->next_data_source_index_ = 0;
+
+    // Free all backends without active trace writers or other inbound
+    // references. Note that even if all the backends get swept, the muxer still
+    // needs to stay around since |task_runner_| is assumed to be long-lived.
+    muxer->SweepDeadBackends();
+
+    // Make sure we eventually discard any per-thread trace writers from the
+    // previous instance.
+    muxer->muxer_id_for_testing_++;
+
+    g_prev_instance = muxer;
+    instance_ = TracingMuxerFake::Get();
+
+    // Call the user provided cleanups on the muxer thread.
+    for (auto& cb : muxer->reset_callbacks_) {
+      cb();
+    }
+
+    reset_done.Notify();
+  };
+
+  // Some tests run the muxer and the test on the same thread. In these cases,
+  // we can reset synchronously.
+  if (muxer->task_runner_->RunsTasksOnCurrentThread()) {
+    do_reset();
+  } else {
+    muxer->DestroyStoppedTraceWritersForCurrentThread();
+    muxer->task_runner_->PostTask(std::move(do_reset));
+    reset_done.Wait();
+    // Call the user provided cleanups also on this thread.
+    for (auto& cb : muxer->reset_callbacks_) {
+      cb();
+    }
+  }
+  muxer->reset_callbacks_.clear();
+}
+
+// static
+void TracingMuxerImpl::Shutdown() {
+  auto* muxer = reinterpret_cast<TracingMuxerImpl*>(instance_);
+
+  // Shutting down on the muxer thread would lead to a deadlock.
+  PERFETTO_CHECK(!muxer->task_runner_->RunsTasksOnCurrentThread());
+  muxer->DestroyStoppedTraceWritersForCurrentThread();
+
+  std::unique_ptr<base::TaskRunner> owned_task_runner(
+      muxer->task_runner_.get());
+  base::WaitableEvent shutdown_done;
+  owned_task_runner->PostTask([muxer, &shutdown_done] {
+    // Check that no consumer session is currently active on any backend.
+    // Producers will be automatically disconnected as a part of deleting the
+    // muxer below.
+    for (auto& backend : muxer->consumer_backends_) {
+      for (auto& consumer : backend.consumers) {
+        PERFETTO_CHECK(!consumer->service_);
+      }
+    }
+    // Make sure no trace writers are lingering around on the muxer thread. Note
+    // that we can't do this for any arbitrary thread in the process; it is the
+    // caller's responsibility to clean them up before shutting down Perfetto.
+    muxer->DestroyStoppedTraceWritersForCurrentThread();
+    // The task runner must be deleted outside the muxer thread. This is done by
+    // `owned_task_runner` above.
+    muxer->task_runner_.release();
+    auto* platform = muxer->platform_;
+    delete muxer;
+    instance_ = TracingMuxerFake::Get();
+    platform->Shutdown();
+    shutdown_done.Notify();
+  });
+  shutdown_done.Wait();
+}
+
+void TracingMuxerImpl::AppendResetForTestingCallback(std::function<void()> cb) {
+  reset_callbacks_.push_back(std::move(cb));
+}
+
+TracingMuxer::~TracingMuxer() = default;
+
+static_assert(std::is_same<internal::BufferId, BufferID>::value,
+              "public's BufferId and tracing/core's BufferID diverged");
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/track_event_internal.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+
+using perfetto::protos::pbzero::ClockSnapshot;
+
+namespace perfetto {
+
+TrackEventSessionObserver::~TrackEventSessionObserver() = default;
+void TrackEventSessionObserver::OnSetup(const DataSourceBase::SetupArgs&) {}
+void TrackEventSessionObserver::OnStart(const DataSourceBase::StartArgs&) {}
+void TrackEventSessionObserver::OnStop(const DataSourceBase::StopArgs&) {}
+void TrackEventSessionObserver::WillClearIncrementalState(
+    const DataSourceBase::ClearIncrementalStateArgs&) {}
+
+TrackEventTlsStateUserData::~TrackEventTlsStateUserData() = default;
+
+namespace internal {
+
+BaseTrackEventInternedDataIndex::~BaseTrackEventInternedDataIndex() = default;
+
+namespace {
+
+static constexpr const char kLegacySlowPrefix[] = "disabled-by-default-";
+static constexpr const char kSlowTag[] = "slow";
+static constexpr const char kDebugTag[] = "debug";
+static constexpr const char kFilteredEventName[] = "FILTERED";
+
+constexpr auto kClockIdIncremental =
+    TrackEventIncrementalState::kClockIdIncremental;
+
+constexpr auto kClockIdAbsolute = TrackEventIncrementalState::kClockIdAbsolute;
+
+class TrackEventSessionObserverRegistry {
+ public:
+  static TrackEventSessionObserverRegistry* GetInstance() {
+    static TrackEventSessionObserverRegistry* instance =
+        new TrackEventSessionObserverRegistry();  // leaked
+    return instance;
+  }
+
+  void AddObserverForRegistry(const TrackEventCategoryRegistry& registry,
+                              TrackEventSessionObserver* observer) {
+    std::unique_lock<std::recursive_mutex> lock(mutex_);
+    observers_.emplace_back(&registry, observer);
+  }
+
+  void RemoveObserverForRegistry(const TrackEventCategoryRegistry& registry,
+                                 TrackEventSessionObserver* observer) {
+    std::unique_lock<std::recursive_mutex> lock(mutex_);
+    observers_.erase(std::remove(observers_.begin(), observers_.end(),
+                                 RegisteredObserver(&registry, observer)),
+                     observers_.end());
+  }
+
+  void ForEachObserverForRegistry(
+      const TrackEventCategoryRegistry& registry,
+      std::function<void(TrackEventSessionObserver*)> callback) {
+    std::unique_lock<std::recursive_mutex> lock(mutex_);
+    for (auto& registered_observer : observers_) {
+      if (&registry == registered_observer.registry) {
+        callback(registered_observer.observer);
+      }
+    }
+  }
+
+ private:
+  struct RegisteredObserver {
+    RegisteredObserver(const TrackEventCategoryRegistry* r,
+                       TrackEventSessionObserver* o)
+        : registry(r), observer(o) {}
+    bool operator==(const RegisteredObserver& other) {
+      return registry == other.registry && observer == other.observer;
+    }
+    const TrackEventCategoryRegistry* registry;
+    TrackEventSessionObserver* observer;
+  };
+
+  std::recursive_mutex mutex_;
+  std::vector<RegisteredObserver> observers_;
+};
+
+enum class MatchType { kExact, kPattern };
+
+bool NameMatchesPattern(const std::string& pattern,
+                        const std::string& name,
+                        MatchType match_type) {
+  // To avoid pulling in all of std::regex, for now we only support a single "*"
+  // wildcard at the end of the pattern.
+  size_t i = pattern.find('*');
+  if (i != std::string::npos) {
+    PERFETTO_DCHECK(i == pattern.size() - 1);
+    if (match_type != MatchType::kPattern)
+      return false;
+    return name.substr(0, i) == pattern.substr(0, i);
+  }
+  return name == pattern;
+}
+
+bool NameMatchesPatternList(const std::vector<std::string>& patterns,
+                            const std::string& name,
+                            MatchType match_type) {
+  for (const auto& pattern : patterns) {
+    if (NameMatchesPattern(pattern, name, match_type))
+      return true;
+  }
+  return false;
+}
+
+}  // namespace
+
+// static
+const Track TrackEventInternal::kDefaultTrack{};
+
+// static
+std::atomic<int> TrackEventInternal::session_count_{};
+
+// static
+bool TrackEventInternal::Initialize(
+    const TrackEventCategoryRegistry& registry,
+    bool (*register_data_source)(const DataSourceDescriptor&)) {
+  DataSourceDescriptor dsd;
+  dsd.set_name("track_event");
+  dsd.set_no_flush(true);
+
+  protozero::HeapBuffered<protos::pbzero::TrackEventDescriptor> ted;
+  for (size_t i = 0; i < registry.category_count(); i++) {
+    auto category = registry.GetCategory(i);
+    // Don't register group categories.
+    if (category->IsGroup())
+      continue;
+    auto cat = ted->add_available_categories();
+    cat->set_name(category->name);
+    if (category->description)
+      cat->set_description(category->description);
+    for (const auto& tag : category->tags) {
+      if (tag)
+        cat->add_tags(tag);
+    }
+    // Disabled-by-default categories get a "slow" tag.
+    if (!strncmp(category->name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)))
+      cat->add_tags(kSlowTag);
+  }
+  dsd.set_track_event_descriptor_raw(ted.SerializeAsString());
+
+  return register_data_source(dsd);
+}
+
+// static
+bool TrackEventInternal::AddSessionObserver(
+    const TrackEventCategoryRegistry& registry,
+    TrackEventSessionObserver* observer) {
+  TrackEventSessionObserverRegistry::GetInstance()->AddObserverForRegistry(
+      registry, observer);
+  return true;
+}
+
+// static
+void TrackEventInternal::RemoveSessionObserver(
+    const TrackEventCategoryRegistry& registry,
+    TrackEventSessionObserver* observer) {
+  TrackEventSessionObserverRegistry::GetInstance()->RemoveObserverForRegistry(
+      registry, observer);
+}
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+static constexpr protos::pbzero::BuiltinClock kDefaultTraceClock =
+    protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
+#else
+static constexpr protos::pbzero::BuiltinClock kDefaultTraceClock =
+    protos::pbzero::BUILTIN_CLOCK_MONOTONIC;
+#endif
+
+// static
+protos::pbzero::BuiltinClock TrackEventInternal::clock_ = kDefaultTraceClock;
+
+// static
+bool TrackEventInternal::disallow_merging_with_system_tracks_ = false;
+
+// static
+void TrackEventInternal::EnableTracing(
+    const TrackEventCategoryRegistry& registry,
+    const protos::gen::TrackEventConfig& config,
+    const DataSourceBase::SetupArgs& args) {
+  for (size_t i = 0; i < registry.category_count(); i++) {
+    if (IsCategoryEnabled(registry, config, *registry.GetCategory(i)))
+      registry.EnableCategoryForInstance(i, args.internal_instance_index);
+  }
+  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
+      registry, [&](TrackEventSessionObserver* o) { o->OnSetup(args); });
+}
+
+// static
+void TrackEventInternal::OnStart(const TrackEventCategoryRegistry& registry,
+                                 const DataSourceBase::StartArgs& args) {
+  session_count_.fetch_add(1);
+  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
+      registry, [&](TrackEventSessionObserver* o) { o->OnStart(args); });
+}
+
+// static
+void TrackEventInternal::OnStop(const TrackEventCategoryRegistry& registry,
+                                const DataSourceBase::StopArgs& args) {
+  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
+      registry, [&](TrackEventSessionObserver* o) { o->OnStop(args); });
+}
+
+// static
+void TrackEventInternal::DisableTracing(
+    const TrackEventCategoryRegistry& registry,
+    uint32_t internal_instance_index) {
+  for (size_t i = 0; i < registry.category_count(); i++)
+    registry.DisableCategoryForInstance(i, internal_instance_index);
+}
+
+// static
+void TrackEventInternal::WillClearIncrementalState(
+    const TrackEventCategoryRegistry& registry,
+    const DataSourceBase::ClearIncrementalStateArgs& args) {
+  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
+      registry, [&](TrackEventSessionObserver* o) {
+        o->WillClearIncrementalState(args);
+      });
+}
+
+// static
+bool TrackEventInternal::IsCategoryEnabled(
+    const TrackEventCategoryRegistry& registry,
+    const protos::gen::TrackEventConfig& config,
+    const Category& category) {
+  // If this is a group category, check if any of its constituent categories are
+  // enabled. If so, then this one is enabled too.
+  if (category.IsGroup()) {
+    bool result = false;
+    category.ForEachGroupMember([&](const char* member_name, size_t name_size) {
+      for (size_t i = 0; i < registry.category_count(); i++) {
+        const auto ref_category = registry.GetCategory(i);
+        // Groups can't refer to other groups.
+        if (ref_category->IsGroup())
+          continue;
+        // Require an exact match.
+        if (ref_category->name_size() != name_size ||
+            strncmp(ref_category->name, member_name, name_size)) {
+          continue;
+        }
+        if (IsCategoryEnabled(registry, config, *ref_category)) {
+          result = true;
+          // Break ForEachGroupMember() loop.
+          return false;
+        }
+        break;
+      }
+      // No match? Must be a dynamic category.
+      DynamicCategory dyn_category(std::string(member_name, name_size));
+      Category ref_category{Category::FromDynamicCategory(dyn_category)};
+      if (IsCategoryEnabled(registry, config, ref_category)) {
+        result = true;
+        // Break ForEachGroupMember() loop.
+        return false;
+      }
+      // No match found => keep iterating.
+      return true;
+    });
+    return result;
+  }
+
+  auto has_matching_tag = [&](std::function<bool(const char*)> matcher) {
+    for (const auto& tag : category.tags) {
+      if (!tag)
+        break;
+      if (matcher(tag))
+        return true;
+    }
+    // Legacy "disabled-by-default" categories automatically get the "slow" tag.
+    if (!strncmp(category.name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)) &&
+        matcher(kSlowTag)) {
+      return true;
+    }
+    return false;
+  };
+
+  // First try exact matches, then pattern matches.
+  const std::array<MatchType, 2> match_types = {
+      {MatchType::kExact, MatchType::kPattern}};
+  for (auto match_type : match_types) {
+    // 1. Enabled categories.
+    if (NameMatchesPatternList(config.enabled_categories(), category.name,
+                               match_type)) {
+      return true;
+    }
+
+    // 2. Enabled tags.
+    if (has_matching_tag([&](const char* tag) {
+          return NameMatchesPatternList(config.enabled_tags(), tag, match_type);
+        })) {
+      return true;
+    }
+
+    // 2.5. A special case for Chrome's legacy disabled-by-default categories.
+    // We treat them as having a "slow" tag with one exception: they can be
+    // enabled by a pattern if the pattern starts with "disabled-by-default-"
+    // itself.
+    if (match_type == MatchType::kExact &&
+        !strncmp(category.name, kLegacySlowPrefix, strlen(kLegacySlowPrefix))) {
+      for (const auto& pattern : config.enabled_categories()) {
+        if (!strncmp(pattern.c_str(), kLegacySlowPrefix,
+                     strlen(kLegacySlowPrefix)) &&
+            NameMatchesPattern(pattern, category.name, MatchType::kPattern)) {
+          return true;
+        }
+      }
+    }
+
+    // 3. Disabled categories.
+    if (NameMatchesPatternList(config.disabled_categories(), category.name,
+                               match_type)) {
+      return false;
+    }
+
+    // 4. Disabled tags.
+    if (has_matching_tag([&](const char* tag) {
+          if (config.disabled_tags_size()) {
+            return NameMatchesPatternList(config.disabled_tags(), tag,
+                                          match_type);
+          } else {
+            // The "slow" and "debug" tags are disabled by default.
+            return NameMatchesPattern(kSlowTag, tag, match_type) ||
+                   NameMatchesPattern(kDebugTag, tag, match_type);
+          }
+        })) {
+      return false;
+    }
+  }
+
+  // If nothing matched, enable the category by default.
+  return true;
+}
+
+// static
+uint64_t TrackEventInternal::GetTimeNs() {
+  if (GetClockId() == protos::pbzero::BUILTIN_CLOCK_BOOTTIME)
+    return static_cast<uint64_t>(perfetto::base::GetBootTimeNs().count());
+  else if (GetClockId() == protos::pbzero::BUILTIN_CLOCK_MONOTONIC)
+    return static_cast<uint64_t>(perfetto::base::GetWallTimeNs().count());
+  PERFETTO_DCHECK(GetClockId() == protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW);
+  return static_cast<uint64_t>(perfetto::base::GetWallTimeRawNs().count());
+}
+
+// static
+TraceTimestamp TrackEventInternal::GetTraceTime() {
+  return {kClockIdIncremental, GetTimeNs()};
+}
+
+// static
+int TrackEventInternal::GetSessionCount() {
+  return session_count_.load();
+}
+
+// static
+void TrackEventInternal::ResetIncrementalState(
+    TraceWriterBase* trace_writer,
+    TrackEventIncrementalState* incr_state,
+    const TrackEventTlsState& tls_state,
+    const TraceTimestamp& timestamp) {
+  auto sequence_timestamp = timestamp;
+  if (timestamp.clock_id != kClockIdIncremental) {
+    sequence_timestamp = TrackEventInternal::GetTraceTime();
+  }
+
+  incr_state->last_timestamp_ns = sequence_timestamp.value;
+  auto default_track = ThreadTrack::Current();
+  auto ts_unit_multiplier = tls_state.timestamp_unit_multiplier;
+  auto thread_time_counter_track =
+      CounterTrack("thread_time", default_track)
+          .set_is_incremental(true)
+          .set_unit_multiplier(static_cast<int64_t>(ts_unit_multiplier))
+          .set_type(protos::gen::CounterDescriptor::COUNTER_THREAD_TIME_NS);
+  {
+    // Mark any incremental state before this point invalid. Also set up
+    // defaults so that we don't need to repeat constant data for each packet.
+    auto packet = NewTracePacket(
+        trace_writer, incr_state, tls_state, timestamp,
+        protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
+    auto defaults = packet->set_trace_packet_defaults();
+    defaults->set_timestamp_clock_id(tls_state.default_clock);
+    // Establish the default track for this event sequence.
+    auto track_defaults = defaults->set_track_event_defaults();
+    track_defaults->set_track_uuid(default_track.uuid);
+    if (tls_state.enable_thread_time_sampling) {
+      track_defaults->add_extra_counter_track_uuids(
+          thread_time_counter_track.uuid);
+    }
+
+    if (tls_state.default_clock != static_cast<uint32_t>(GetClockId())) {
+      ClockSnapshot* clocks = packet->set_clock_snapshot();
+      // Trace clock.
+      ClockSnapshot::Clock* trace_clock = clocks->add_clocks();
+      trace_clock->set_clock_id(static_cast<uint32_t>(GetClockId()));
+      trace_clock->set_timestamp(sequence_timestamp.value);
+
+      if (PERFETTO_LIKELY(tls_state.default_clock == kClockIdIncremental)) {
+        // Delta-encoded incremental clock in nanoseconds by default but
+        // configurable by |tls_state.timestamp_unit_multiplier|.
+        ClockSnapshot::Clock* clock_incremental = clocks->add_clocks();
+        clock_incremental->set_clock_id(kClockIdIncremental);
+        clock_incremental->set_timestamp(sequence_timestamp.value /
+                                         ts_unit_multiplier);
+        clock_incremental->set_is_incremental(true);
+        clock_incremental->set_unit_multiplier_ns(ts_unit_multiplier);
+      }
+      if (ts_unit_multiplier > 1) {
+        // absolute clock with custom timestamp_unit_multiplier.
+        ClockSnapshot::Clock* absolute_clock = clocks->add_clocks();
+        absolute_clock->set_clock_id(kClockIdAbsolute);
+        absolute_clock->set_timestamp(sequence_timestamp.value /
+                                      ts_unit_multiplier);
+        absolute_clock->set_is_incremental(false);
+        absolute_clock->set_unit_multiplier_ns(ts_unit_multiplier);
+      }
+    }
+  }
+
+  // Every thread should write a descriptor for its default track, because most
+  // trace points won't explicitly reference it. We also write the process
+  // descriptor from every thread that writes trace events to ensure it gets
+  // emitted at least once.
+  WriteTrackDescriptor(default_track, trace_writer, incr_state, tls_state,
+                       sequence_timestamp);
+
+  WriteTrackDescriptor(ProcessTrack::Current(), trace_writer, incr_state,
+                       tls_state, sequence_timestamp);
+
+  if (tls_state.enable_thread_time_sampling) {
+    WriteTrackDescriptor(thread_time_counter_track, trace_writer, incr_state,
+                         tls_state, sequence_timestamp);
+  }
+}
+
+// static
+protozero::MessageHandle<protos::pbzero::TracePacket>
+TrackEventInternal::NewTracePacket(TraceWriterBase* trace_writer,
+                                   TrackEventIncrementalState* incr_state,
+                                   const TrackEventTlsState& tls_state,
+                                   TraceTimestamp timestamp,
+                                   uint32_t seq_flags) {
+  if (PERFETTO_UNLIKELY(tls_state.default_clock != kClockIdIncremental &&
+                        timestamp.clock_id == kClockIdIncremental)) {
+    timestamp.clock_id = tls_state.default_clock;
+  }
+  auto packet = trace_writer->NewTracePacket();
+  auto ts_unit_multiplier = tls_state.timestamp_unit_multiplier;
+  if (PERFETTO_LIKELY(timestamp.clock_id == kClockIdIncremental)) {
+    if (PERFETTO_LIKELY(incr_state->last_timestamp_ns <= timestamp.value)) {
+      // No need to set the clock id here, since kClockIdIncremental is the
+      // clock id assumed by default.
+      auto time_diff_ns = timestamp.value - incr_state->last_timestamp_ns;
+      auto time_diff_units = time_diff_ns / ts_unit_multiplier;
+      packet->set_timestamp(time_diff_units);
+      incr_state->last_timestamp_ns += time_diff_units * ts_unit_multiplier;
+    } else {
+      packet->set_timestamp(timestamp.value / ts_unit_multiplier);
+      packet->set_timestamp_clock_id(ts_unit_multiplier == 1
+                                         ? static_cast<uint32_t>(GetClockId())
+                                         : kClockIdAbsolute);
+    }
+  } else if (PERFETTO_LIKELY(timestamp.clock_id == tls_state.default_clock)) {
+    packet->set_timestamp(timestamp.value / ts_unit_multiplier);
+  } else {
+    packet->set_timestamp(timestamp.value);
+    packet->set_timestamp_clock_id(timestamp.clock_id);
+  }
+  packet->set_sequence_flags(seq_flags);
+  return packet;
+}
+
+// static
+void TrackEventInternal::WriteEventName(StaticString event_name,
+                                        perfetto::EventContext& event_ctx,
+                                        const TrackEventTlsState&) {
+  if (PERFETTO_LIKELY(event_name.value != nullptr)) {
+    size_t name_iid = InternedEventName::Get(&event_ctx, event_name.value);
+    event_ctx.event()->set_name_iid(name_iid);
+  }
+}
+
+// static
+void TrackEventInternal::WriteEventName(perfetto::DynamicString event_name,
+                                        perfetto::EventContext& event_ctx,
+                                        const TrackEventTlsState& tls_state) {
+  if (PERFETTO_UNLIKELY(tls_state.filter_dynamic_event_names)) {
+    event_ctx.event()->set_name(kFilteredEventName,
+                                sizeof(kFilteredEventName) - 1);
+  } else {
+    event_ctx.event()->set_name(event_name.value, event_name.length);
+  }
+}
+
+// static
+EventContext TrackEventInternal::WriteEvent(
+    TraceWriterBase* trace_writer,
+    TrackEventIncrementalState* incr_state,
+    TrackEventTlsState& tls_state,
+    const Category* category,
+    perfetto::protos::pbzero::TrackEvent::Type type,
+    const TraceTimestamp& timestamp,
+    bool on_current_thread_track) {
+  PERFETTO_DCHECK(!incr_state->was_cleared);
+  auto packet = NewTracePacket(trace_writer, incr_state, tls_state, timestamp);
+  EventContext ctx(trace_writer, std::move(packet), incr_state, &tls_state);
+
+  auto track_event = ctx.event();
+  if (type != protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
+    track_event->set_type(type);
+
+  if (tls_state.enable_thread_time_sampling && on_current_thread_track) {
+    int64_t thread_time_ns = base::GetThreadCPUTimeNs().count();
+    auto thread_time_delta_ns =
+        thread_time_ns - incr_state->last_thread_time_ns;
+    incr_state->last_thread_time_ns = thread_time_ns;
+    track_event->add_extra_counter_values(
+        thread_time_delta_ns /
+        static_cast<int64_t>(tls_state.timestamp_unit_multiplier));
+  }
+
+  // We assume that |category| points to the string with static lifetime.
+  // This means we can use their addresses as interning keys.
+  // TODO(skyostil): Intern categories at compile time.
+  if (category && type != protos::pbzero::TrackEvent::TYPE_SLICE_END &&
+      type != protos::pbzero::TrackEvent::TYPE_COUNTER) {
+    category->ForEachGroupMember(
+        [&](const char* member_name, size_t name_size) {
+          size_t category_iid =
+              InternedEventCategory::Get(&ctx, member_name, name_size);
+          track_event->add_category_iids(category_iid);
+          return true;
+        });
+  }
+  return ctx;
+}
+
+// static
+protos::pbzero::DebugAnnotation* TrackEventInternal::AddDebugAnnotation(
+    perfetto::EventContext* event_ctx,
+    const char* name) {
+  auto annotation = event_ctx->event()->add_debug_annotations();
+  annotation->set_name_iid(InternedDebugAnnotationName::Get(event_ctx, name));
+  return annotation;
+}
+
+// static
+protos::pbzero::DebugAnnotation* TrackEventInternal::AddDebugAnnotation(
+    perfetto::EventContext* event_ctx,
+    perfetto::DynamicString name) {
+  auto annotation = event_ctx->event()->add_debug_annotations();
+  annotation->set_name(name.value);
+  return annotation;
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/track_event_interned_fields.cc
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
+
+namespace perfetto {
+namespace internal {
+
+InternedEventCategory::~InternedEventCategory() = default;
+
+// static
+void InternedEventCategory::Add(protos::pbzero::InternedData* interned_data,
+                                size_t iid,
+                                const char* value,
+                                size_t length) {
+  auto category = interned_data->add_event_categories();
+  category->set_iid(iid);
+  category->set_name(value, length);
+}
+
+InternedEventName::~InternedEventName() = default;
+
+// static
+void InternedEventName::Add(protos::pbzero::InternedData* interned_data,
+                            size_t iid,
+                            const char* value) {
+  auto name = interned_data->add_event_names();
+  name->set_iid(iid);
+  name->set_name(value);
+}
+
+InternedDebugAnnotationName::~InternedDebugAnnotationName() = default;
+
+// static
+void InternedDebugAnnotationName::Add(
+    protos::pbzero::InternedData* interned_data,
+    size_t iid,
+    const char* value) {
+  auto name = interned_data->add_debug_annotation_names();
+  name->set_iid(iid);
+  name->set_name(value);
+}
+
+InternedDebugAnnotationValueTypeName::~InternedDebugAnnotationValueTypeName() =
+    default;
+
+// static
+void InternedDebugAnnotationValueTypeName::Add(
+    protos::pbzero::InternedData* interned_data,
+    size_t iid,
+    const char* value) {
+  auto name = interned_data->add_debug_annotation_value_type_names();
+  name->set_iid(iid);
+  name->set_name(value);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/platform.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+namespace perfetto {
+
+PlatformThreadLocalObject::~PlatformThreadLocalObject() = default;
+Platform::~Platform() = default;
+
+void Platform::Shutdown() {}
+
+base::PlatformThreadId Platform::GetCurrentThreadId() {
+  return base::GetThreadId();
+}
+
+// static
+std::unique_ptr<PlatformThreadLocalObject>
+PlatformThreadLocalObject::CreateInstance() {
+  return std::unique_ptr<PlatformThreadLocalObject>(new internal::TracingTLS());
+}
+
+// static
+base::PlatformProcessId Platform::process_id_ = 0;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/traced_value.cc
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+
+namespace perfetto {
+
+namespace internal {
+
+TracedValue CreateTracedValueFromProto(
+    protos::pbzero::DebugAnnotation* annotation,
+    EventContext* event_context) {
+  return TracedValue::CreateFromProto(annotation, event_context);
+}
+
+}  // namespace internal
+
+// static
+TracedValue TracedValue::CreateFromProto(
+    protos::pbzero::DebugAnnotation* annotation,
+    EventContext* event_context) {
+  return TracedValue(annotation, event_context, nullptr);
+}
+
+TracedValue::TracedValue(TracedValue&&) = default;
+TracedValue::~TracedValue() = default;
+
+void TracedValue::WriteInt64(int64_t value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_int_value(value);
+}
+
+void TracedValue::WriteUInt64(uint64_t value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_uint_value(value);
+}
+
+void TracedValue::WriteDouble(double value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_double_value(value);
+}
+
+void TracedValue::WriteBoolean(bool value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_bool_value(value);
+}
+
+void TracedValue::WriteString(const char* value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_string_value(value);
+}
+
+void TracedValue::WriteString(const char* value, size_t len) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_string_value(value, len);
+}
+
+void TracedValue::WriteString(const std::string& value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_string_value(value);
+}
+
+void TracedValue::WriteString(std::string_view value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_string_value(value.data(), value.size());
+}
+
+void TracedValue::WritePointer(const void* value) && {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  annotation_->set_pointer_value(reinterpret_cast<uint64_t>(value));
+}
+
+TracedDictionary TracedValue::WriteDictionary() && {
+  // Note: this passes |checked_scope_.is_active_| bit to the parent to be
+  // picked up later by the new TracedDictionary.
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  checked_scope_.Reset();
+
+  PERFETTO_DCHECK(!annotation_->is_finalized());
+  return TracedDictionary(annotation_,
+                          protos::pbzero::DebugAnnotation::kDictEntries,
+                          event_context_, checked_scope_.parent_scope());
+}
+
+TracedArray TracedValue::WriteArray() && {
+  // Note: this passes |checked_scope_.is_active_| bit to the parent to be
+  // picked up later by the new TracedDictionary.
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  checked_scope_.Reset();
+
+  PERFETTO_DCHECK(!annotation_->is_finalized());
+  return TracedArray(annotation_, event_context_,
+                     checked_scope_.parent_scope());
+}
+
+protozero::Message* TracedValue::WriteProtoInternal(const char* name) {
+  if (event_context_) {
+    annotation_->set_proto_type_name_iid(
+        internal::InternedDebugAnnotationValueTypeName::Get(event_context_,
+                                                            name));
+  } else {
+    annotation_->set_proto_type_name(name);
+  }
+  return annotation_->template BeginNestedMessage<protozero::Message>(
+      protos::pbzero::DebugAnnotation::kProtoValueFieldNumber);
+}
+
+TracedArray::TracedArray(TracedValue annotation)
+    : TracedArray(std::move(annotation).WriteArray()) {}
+
+TracedValue TracedArray::AppendItem() {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return TracedValue(annotation_->add_array_values(), event_context_,
+                     &checked_scope_);
+}
+
+TracedDictionary TracedArray::AppendDictionary() {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AppendItem().WriteDictionary();
+}
+
+TracedArray TracedArray::AppendArray() {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AppendItem().WriteArray();
+}
+
+TracedDictionary::TracedDictionary(TracedValue annotation)
+    : TracedDictionary(std::move(annotation).WriteDictionary()) {}
+
+TracedValue TracedDictionary::AddItem(StaticString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  protos::pbzero::DebugAnnotation* item =
+      message_->BeginNestedMessage<protos::pbzero::DebugAnnotation>(field_id_);
+  item->set_name(key.value);
+  return TracedValue(item, event_context_, &checked_scope_);
+}
+
+TracedValue TracedDictionary::AddItem(DynamicString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  protos::pbzero::DebugAnnotation* item =
+      message_->BeginNestedMessage<protos::pbzero::DebugAnnotation>(field_id_);
+  item->set_name(key.value);
+  return TracedValue(item, event_context_, &checked_scope_);
+}
+
+TracedDictionary TracedDictionary::AddDictionary(StaticString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AddItem(key).WriteDictionary();
+}
+
+TracedDictionary TracedDictionary::AddDictionary(DynamicString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AddItem(key).WriteDictionary();
+}
+
+TracedArray TracedDictionary::AddArray(StaticString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AddItem(key).WriteArray();
+}
+
+TracedArray TracedDictionary::AddArray(DynamicString key) {
+  PERFETTO_DCHECK(checked_scope_.is_active());
+  return AddItem(key).WriteArray();
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/tracing.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/no_destructor.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_NO_DESTRUCTOR_H_
+#define INCLUDE_PERFETTO_EXT_BASE_NO_DESTRUCTOR_H_
+
+#include <new>
+#include <utility>
+
+namespace perfetto {
+namespace base {
+
+// Wrapper that can hold an object of type T, without invoking the contained
+// object's destructor when being destroyed. Useful for creating statics while
+// avoiding static destructors.
+//
+// Stores the object inline, and therefore doesn't incur memory allocation and
+// pointer indirection overheads.
+//
+// Example of use:
+//
+//   const std::string& GetStr() {
+//     static base::NoDestructor<std::string> s("hello");
+//     return s.ref();
+//   }
+//
+template <typename T>
+class NoDestructor {
+ public:
+  // Forward arguments to T's constructor. Note that this doesn't cover
+  // construction from initializer lists.
+  template <typename... Args>
+  explicit NoDestructor(Args&&... args) {
+    new (storage_) T(std::forward<Args>(args)...);
+  }
+
+  NoDestructor(const NoDestructor&) = delete;
+  NoDestructor& operator=(const NoDestructor&) = delete;
+  NoDestructor(NoDestructor&&) = delete;
+  NoDestructor& operator=(NoDestructor&&) = delete;
+
+  ~NoDestructor() = default;
+
+  /* To avoid type-punned pointer strict aliasing warnings on GCC6 and below
+   * these need to be split over two lines. If they are collapsed onto one line.
+   *   return reinterpret_cast<const T*>(storage_);
+   * The error fires.
+   */
+  const T& ref() const {
+    auto* const cast = reinterpret_cast<const T*>(storage_);
+    return *cast;
+  }
+  T& ref() {
+    auto* const cast = reinterpret_cast<T*>(storage_);
+    return *cast;
+  }
+
+ private:
+  alignas(T) char storage_[sizeof(T)];
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_NO_DESTRUCTOR_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/no_destructor.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"
+
+namespace perfetto {
+namespace {
+bool g_was_initialized = false;
+
+// Wrapped in a function to avoid global constructor
+std::mutex& InitializedMutex() {
+  static base::NoDestructor<std::mutex> initialized_mutex;
+  return initialized_mutex.ref();
+}
+}  // namespace
+
+// static
+void Tracing::InitializeInternal(const TracingInitArgs& args) {
+  base::InitializeTime();
+  std::unique_lock<std::mutex> lock(InitializedMutex());
+  // If it's the first time Initialize is called, set some global params.
+  if (!g_was_initialized) {
+    // Make sure the headers and implementation files agree on the build config.
+    PERFETTO_CHECK(args.dcheck_is_on_ == PERFETTO_DCHECK_IS_ON());
+    if (args.log_message_callback) {
+      base::SetLogMessageCallback(args.log_message_callback);
+    }
+
+    if (args.use_monotonic_clock) {
+      PERFETTO_CHECK(!args.use_monotonic_raw_clock);
+      internal::TrackEventInternal::SetClockId(
+          protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
+    } else if (args.use_monotonic_raw_clock) {
+      internal::TrackEventInternal::SetClockId(
+          protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW);
+    }
+
+    if (args.disallow_merging_with_system_tracks) {
+      internal::TrackEventInternal::SetDisallowMergingWithSystemTracks(true);
+    }
+  }
+
+  internal::TracingMuxerImpl::InitializeInstance(args);
+  internal::TrackRegistry::InitializeInstance();
+  g_was_initialized = true;
+}
+
+// static
+bool Tracing::IsInitialized() {
+  std::unique_lock<std::mutex> lock(InitializedMutex());
+  return g_was_initialized;
+}
+
+// static
+void Tracing::Shutdown() {
+  std::unique_lock<std::mutex> lock(InitializedMutex());
+  if (!g_was_initialized)
+    return;
+  internal::TracingMuxerImpl::Shutdown();
+  g_was_initialized = false;
+}
+
+// static
+void Tracing::ResetForTesting() {
+  std::unique_lock<std::mutex> lock(InitializedMutex());
+  if (!g_was_initialized)
+    return;
+  base::SetLogMessageCallback(nullptr);
+  internal::TracingMuxerImpl::ResetForTesting();
+  internal::TrackRegistry::ResetForTesting();
+  g_was_initialized = false;
+}
+
+//  static
+std::unique_ptr<TracingSession> Tracing::NewTraceInternal(
+    BackendType backend,
+    TracingConsumerBackend* (*system_backend_factory)()) {
+  return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
+      ->CreateTracingSession(backend, system_backend_factory);
+}
+
+//  static
+std::unique_ptr<StartupTracingSession> Tracing::SetupStartupTracing(
+    const TraceConfig& config,
+    Tracing::SetupStartupTracingOpts opts) {
+  return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
+      ->CreateStartupTracingSession(config, std::move(opts));
+}
+
+//  static
+std::unique_ptr<StartupTracingSession> Tracing::SetupStartupTracingBlocking(
+    const TraceConfig& config,
+    Tracing::SetupStartupTracingOpts opts) {
+  return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
+      ->CreateStartupTracingSessionBlocking(config, std::move(opts));
+}
+
+//  static
+void Tracing::ActivateTriggers(const std::vector<std::string>& triggers,
+                               uint32_t ttl_ms) {
+  internal::TracingMuxer::Get()->ActivateTriggers(triggers, ttl_ms);
+}
+
+TracingSession::~TracingSession() = default;
+
+// Can be called from any thread.
+bool TracingSession::FlushBlocking(uint32_t timeout_ms) {
+  std::atomic<bool> flush_result;
+  base::WaitableEvent flush_ack;
+
+  // The non blocking Flush() can be called on any thread. It does the PostTask
+  // internally.
+  Flush(
+      [&flush_ack, &flush_result](bool res) {
+        flush_result = res;
+        flush_ack.Notify();
+      },
+      timeout_ms);
+  flush_ack.Wait();
+  return flush_result;
+}
+
+std::vector<char> TracingSession::ReadTraceBlocking() {
+  std::vector<char> raw_trace;
+  std::mutex mutex;
+  std::condition_variable cv;
+
+  bool all_read = false;
+
+  ReadTrace([&mutex, &raw_trace, &all_read, &cv](ReadTraceCallbackArgs cb) {
+    raw_trace.insert(raw_trace.end(), cb.data, cb.data + cb.size);
+    std::unique_lock<std::mutex> lock(mutex);
+    all_read = !cb.has_more;
+    if (all_read)
+      cv.notify_one();
+  });
+
+  {
+    std::unique_lock<std::mutex> lock(mutex);
+    cv.wait(lock, [&all_read] { return all_read; });
+  }
+  return raw_trace;
+}
+
+TracingSession::GetTraceStatsCallbackArgs
+TracingSession::GetTraceStatsBlocking() {
+  std::mutex mutex;
+  std::condition_variable cv;
+  GetTraceStatsCallbackArgs result;
+  bool stats_read = false;
+
+  GetTraceStats(
+      [&mutex, &result, &stats_read, &cv](GetTraceStatsCallbackArgs args) {
+        result = std::move(args);
+        std::unique_lock<std::mutex> lock(mutex);
+        stats_read = true;
+        cv.notify_one();
+      });
+
+  {
+    std::unique_lock<std::mutex> lock(mutex);
+    cv.wait(lock, [&stats_read] { return stats_read; });
+  }
+  return result;
+}
+
+TracingSession::QueryServiceStateCallbackArgs
+TracingSession::QueryServiceStateBlocking() {
+  std::mutex mutex;
+  std::condition_variable cv;
+  QueryServiceStateCallbackArgs result;
+  bool status_read = false;
+
+  QueryServiceState(
+      [&mutex, &result, &status_read, &cv](QueryServiceStateCallbackArgs args) {
+        result = std::move(args);
+        std::unique_lock<std::mutex> lock(mutex);
+        status_read = true;
+        cv.notify_one();
+      });
+
+  {
+    std::unique_lock<std::mutex> lock(mutex);
+    cv.wait(lock, [&status_read] { return status_read; });
+  }
+  return result;
+}
+
+StartupTracingSession::~StartupTracingSession() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/tracing_policy.cc
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_policy.h"
+
+namespace perfetto {
+
+TracingPolicy::~TracingPolicy() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/track.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
+
+namespace perfetto {
+
+// static
+uint64_t Track::process_uuid;
+
+protos::gen::TrackDescriptor Track::Serialize() const {
+  protos::gen::TrackDescriptor desc;
+  desc.set_uuid(uuid);
+  if (parent_uuid)
+    desc.set_parent_uuid(parent_uuid);
+  return desc;
+}
+
+void Track::Serialize(protos::pbzero::TrackDescriptor* desc) const {
+  auto bytes = Serialize().SerializeAsString();
+  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
+}
+
+protos::gen::TrackDescriptor ProcessTrack::Serialize() const {
+  auto desc = Track::Serialize();
+  auto pd = desc.mutable_process();
+  pd->set_pid(static_cast<int32_t>(pid));
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  std::string cmdline;
+  if (base::ReadFile("/proc/self/cmdline", &cmdline)) {
+    // Since cmdline is a zero-terminated list of arguments, this ends up
+    // writing just the first element, i.e., the process name, into the process
+    // name field.
+    pd->set_process_name(cmdline.c_str());
+    base::StringSplitter splitter(std::move(cmdline), '\0');
+    while (splitter.Next()) {
+      pd->add_cmdline(
+          std::string(splitter.cur_token(), splitter.cur_token_size()));
+    }
+  }
+  // TODO(skyostil): Record command line on Windows and Mac.
+#endif
+  return desc;
+}
+
+void ProcessTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
+  auto bytes = Serialize().SerializeAsString();
+  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
+}
+
+protos::gen::TrackDescriptor ThreadTrack::Serialize() const {
+  auto desc = Track::Serialize();
+  auto td = desc.mutable_thread();
+  td->set_pid(static_cast<int32_t>(pid));
+  td->set_tid(static_cast<int32_t>(tid));
+  if (disallow_merging_with_system_tracks) {
+    desc.set_disallow_merging_with_system_tracks(true);
+  }
+  std::string thread_name;
+  if (base::GetThreadName(thread_name))
+    td->set_thread_name(thread_name);
+  return desc;
+}
+
+// static
+ThreadTrack ThreadTrack::Current() {
+  return ThreadTrack(
+      internal::TracingMuxer::Get()->GetCurrentThreadId(),
+      internal::TrackEventInternal::GetDisallowMergingWithSystemTracks());
+}
+
+// static
+ThreadTrack ThreadTrack::ForThread(base::PlatformThreadId tid_) {
+  return ThreadTrack(
+      tid_, internal::TrackEventInternal::GetDisallowMergingWithSystemTracks());
+}
+
+void ThreadTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
+  auto bytes = Serialize().SerializeAsString();
+  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
+}
+
+protos::gen::TrackDescriptor CounterTrack::Serialize() const {
+  auto desc = Track::Serialize();
+  desc.set_name(name_);
+  auto* counter = desc.mutable_counter();
+  if (category_)
+    counter->add_categories(category_);
+  if (unit_ != perfetto::protos::pbzero::CounterDescriptor::UNIT_UNSPECIFIED)
+    counter->set_unit(static_cast<protos::gen::CounterDescriptor_Unit>(unit_));
+  {
+    // if |type| is set, we don't want to emit |unit_name|. Trace processor
+    // infers the track name from the type in that case.
+    if (type_ !=
+        perfetto::protos::gen::CounterDescriptor::COUNTER_UNSPECIFIED) {
+      counter->set_type(type_);
+    } else if (unit_name_) {
+      counter->set_unit_name(unit_name_);
+    }
+  }
+  if (unit_multiplier_ != 1)
+    counter->set_unit_multiplier(unit_multiplier_);
+  if (is_incremental_)
+    counter->set_is_incremental(is_incremental_);
+  return desc;
+}
+
+void CounterTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
+  auto bytes = Serialize().SerializeAsString();
+  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
+}
+
+namespace internal {
+namespace {
+
+uint64_t GetProcessStartTime() {
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  std::string stat;
+  if (!base::ReadFile("/proc/self/stat", &stat))
+    return 0u;
+  // The stat file is a single line split into space-separated fields as "pid
+  // (comm) state ppid ...". However because the command name can contain any
+  // characters (including parentheses and spaces), we need to skip past it
+  // before parsing the rest of the fields. To do that, we look for the last
+  // instance of ") " (parentheses followed by space) and parse forward from
+  // that point.
+  size_t comm_end = stat.rfind(") ");
+  if (comm_end == std::string::npos)
+    return 0u;
+  stat = stat.substr(comm_end + strlen(") "));
+  base::StringSplitter splitter(stat, ' ');
+  for (size_t skip = 0; skip < 20; skip++) {
+    if (!splitter.Next())
+      return 0u;
+  }
+  return base::CStringToUInt64(splitter.cur_token()).value_or(0u);
+#else
+  return 0;
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+}
+
+}  // namespace
+
+// static
+TrackRegistry* TrackRegistry::instance_;
+
+TrackRegistry::TrackRegistry() = default;
+TrackRegistry::~TrackRegistry() = default;
+
+// static
+void TrackRegistry::InitializeInstance() {
+  if (instance_)
+    return;
+  instance_ = new TrackRegistry();
+  Track::process_uuid = ComputeProcessUuid();
+}
+
+// static
+uint64_t TrackRegistry::ComputeProcessUuid() {
+  // Use the process start time + pid as the unique identifier for this process.
+  // This ensures that if there are two independent copies of the Perfetto SDK
+  // in the same process (e.g., one in the app and another in a system
+  // framework), events emitted by each will be consistently interleaved on
+  // common thread and process tracks.
+  if (uint64_t start_time = GetProcessStartTime()) {
+    base::Hasher hash;
+    hash.Update(start_time);
+    hash.Update(Platform::GetCurrentProcessId());
+    return hash.digest();
+  }
+  // Fall back to a randomly generated identifier.
+  static uint64_t random_once = static_cast<uint64_t>(base::Uuidv4().lsb());
+  return random_once;
+}
+
+void TrackRegistry::ResetForTesting() {
+  instance_->tracks_.clear();
+}
+
+void TrackRegistry::UpdateTrack(Track track,
+                                const std::string& serialized_desc) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  tracks_[track.uuid] = std::move(serialized_desc);
+}
+
+void TrackRegistry::UpdateTrackImpl(
+    Track track,
+    std::function<void(protos::pbzero::TrackDescriptor*)> fill_function) {
+  constexpr size_t kInitialSliceSize = 32;
+  constexpr size_t kMaximumSliceSize = 4096;
+  protozero::HeapBuffered<protos::pbzero::TrackDescriptor> new_descriptor(
+      kInitialSliceSize, kMaximumSliceSize);
+  fill_function(new_descriptor.get());
+  auto serialized_desc = new_descriptor.SerializeAsString();
+  UpdateTrack(track, serialized_desc);
+}
+
+void TrackRegistry::EraseTrack(Track track) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  tracks_.erase(track.uuid);
+}
+
+// static
+void TrackRegistry::WriteTrackDescriptor(
+    const SerializedTrackDescriptor& desc,
+    protozero::MessageHandle<protos::pbzero::TracePacket> packet) {
+  packet->AppendString(
+      perfetto::protos::pbzero::TracePacket::kTrackDescriptorFieldNumber, desc);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/track_event_category_registry.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
+
+namespace perfetto {
+
+// static
+Category Category::FromDynamicCategory(const char* name) {
+  if (GetNthNameSize(1, name, name)) {
+    Category group(Group(name));
+    PERFETTO_DCHECK(group.name);
+    return group;
+  }
+  Category category(name);
+  PERFETTO_DCHECK(category.name);
+  return category;
+}
+
+Category Category::FromDynamicCategory(
+    const DynamicCategory& dynamic_category) {
+  return FromDynamicCategory(dynamic_category.name.c_str());
+}
+
+namespace internal {
+
+perfetto::DynamicCategory NullCategory(const perfetto::DynamicCategory&) {
+  return perfetto::DynamicCategory{};
+}
+
+void TrackEventCategoryRegistry::EnableCategoryForInstance(
+    size_t category_index,
+    uint32_t instance_index) const {
+  PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
+  PERFETTO_DCHECK(category_index < category_count_);
+  // Matches the acquire_load in DataSource::Trace().
+  state_storage_[category_index].fetch_or(
+      static_cast<uint8_t>(1u << instance_index), std::memory_order_release);
+}
+
+void TrackEventCategoryRegistry::DisableCategoryForInstance(
+    size_t category_index,
+    uint32_t instance_index) const {
+  PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
+  PERFETTO_DCHECK(category_index < category_count_);
+  // Matches the acquire_load in DataSource::Trace().
+  state_storage_[category_index].fetch_and(
+      static_cast<uint8_t>(~(1u << instance_index)), std::memory_order_release);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/track_event_legacy.cc
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_legacy.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+
+namespace perfetto {
+namespace legacy {
+
+template <>
+ThreadTrack ConvertThreadId(const PerfettoLegacyCurrentThreadId&) {
+  // Because of the short-circuit in PERFETTO_INTERNAL_LEGACY_EVENT, we should
+  // never get here.
+  PERFETTO_DCHECK(false);
+  return ThreadTrack::Current();
+}
+
+}  // namespace legacy
+
+namespace internal {
+
+void LegacyTraceId::Write(protos::pbzero::TrackEvent::LegacyEvent* event,
+                          uint32_t event_flags) const {
+  // Legacy flow events always use bind_id.
+  if (event_flags &
+      (legacy::kTraceEventFlagFlowOut | legacy::kTraceEventFlagFlowIn)) {
+    // Flow bind_ids don't have scopes, so we need to mangle in-process ones to
+    // avoid collisions.
+    if (id_flags_ & legacy::kTraceEventFlagHasLocalId) {
+      event->set_bind_id(raw_id_ ^ ProcessTrack::Current().uuid);
+    } else {
+      event->set_bind_id(raw_id_);
+    }
+    return;
+  }
+
+  uint32_t scope_flags = id_flags_ & (legacy::kTraceEventFlagHasId |
+                                      legacy::kTraceEventFlagHasLocalId |
+                                      legacy::kTraceEventFlagHasGlobalId);
+  uint64_t id = raw_id_;
+  if (scope_ && scope_flags != legacy::kTraceEventFlagHasGlobalId) {
+    id = base::Hasher::Combine(id, scope_);
+  }
+
+  switch (scope_flags) {
+    case legacy::kTraceEventFlagHasId:
+      event->set_unscoped_id(id);
+      break;
+    case legacy::kTraceEventFlagHasLocalId:
+      event->set_local_id(id);
+      break;
+    case legacy::kTraceEventFlagHasGlobalId:
+      event->set_global_id(id);
+      break;
+  }
+  if (scope_)
+    event->set_id_scope(scope_);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/track_event_state_tracker.cc
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_state_tracker.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+namespace perfetto {
+
+using internal::TrackEventIncrementalState;
+
+TrackEventStateTracker::~TrackEventStateTracker() = default;
+TrackEventStateTracker::Delegate::~Delegate() = default;
+
+// static
+void TrackEventStateTracker::ProcessTracePacket(
+    Delegate& delegate,
+    SequenceState& sequence_state,
+    const protos::pbzero::TracePacket_Decoder& packet) {
+  UpdateIncrementalState(delegate, sequence_state, packet);
+
+  if (!packet.has_track_event())
+    return;
+  perfetto::protos::pbzero::TrackEvent::Decoder track_event(
+      packet.track_event());
+
+  auto clock_id = packet.timestamp_clock_id();
+  if (!packet.has_timestamp_clock_id())
+    clock_id = sequence_state.default_clock_id;
+  uint64_t timestamp = packet.timestamp();
+  // TODO(mohitms): Incorporate unit multiplier as well.
+  if (clock_id == internal::TrackEventIncrementalState::kClockIdIncremental) {
+    timestamp += sequence_state.most_recent_absolute_time_ns;
+    sequence_state.most_recent_absolute_time_ns = timestamp;
+  }
+
+  Track* track = &sequence_state.track;
+  if (track_event.has_track_uuid()) {
+    auto* session_state = delegate.GetSessionState();
+    if (!session_state)
+      return;  // Tracing must have ended.
+    track = &session_state->tracks[track_event.track_uuid()];
+  }
+
+  // We only log the first category of each event.
+  protozero::ConstChars category{};
+  uint64_t category_iid = 0;
+  if (auto iid_it = track_event.category_iids()) {
+    category_iid = *iid_it;
+    category.data = sequence_state.event_categories[category_iid].data();
+    category.size = sequence_state.event_categories[category_iid].size();
+  } else if (auto cat_it = track_event.categories()) {
+    category.data = reinterpret_cast<const char*>(cat_it->data());
+    category.size = cat_it->size();
+  }
+
+  protozero::ConstChars name{};
+  uint64_t name_iid = track_event.name_iid();
+  uint64_t name_hash = 0;
+  uint64_t duration = 0;
+  if (name_iid) {
+    name.data = sequence_state.event_names[name_iid].data();
+    name.size = sequence_state.event_names[name_iid].size();
+  } else if (track_event.has_name()) {
+    name.data = track_event.name().data;
+    name.size = track_event.name().size;
+  }
+
+  if (name.data) {
+    base::Hasher hash;
+    hash.Update(name.data, name.size);
+    name_hash = hash.digest();
+  }
+
+  size_t depth = track->stack.size();
+  switch (track_event.type()) {
+    case protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN: {
+      StackFrame frame;
+      frame.timestamp = timestamp;
+      frame.name_hash = name_hash;
+      if (track_event.has_track_uuid()) {
+        frame.name = name.ToStdString();
+        frame.category = category.ToStdString();
+      } else {
+        frame.name_iid = name_iid;
+        frame.category_iid = category_iid;
+      }
+      track->stack.push_back(std::move(frame));
+      break;
+    }
+    case protos::pbzero::TrackEvent::TYPE_SLICE_END:
+      if (!track->stack.empty()) {
+        const auto& prev_frame = track->stack.back();
+        if (prev_frame.name_iid) {
+          name.data = sequence_state.event_names[prev_frame.name_iid].data();
+          name.size = sequence_state.event_names[prev_frame.name_iid].size();
+        } else {
+          name.data = prev_frame.name.data();
+          name.size = prev_frame.name.size();
+        }
+        name_hash = prev_frame.name_hash;
+        if (prev_frame.category_iid) {
+          category.data =
+              sequence_state.event_categories[prev_frame.category_iid].data();
+          category.size =
+              sequence_state.event_categories[prev_frame.category_iid].size();
+        } else {
+          category.data = prev_frame.category.data();
+          category.size = prev_frame.category.size();
+        }
+        duration = timestamp - prev_frame.timestamp;
+        depth--;
+      }
+      break;
+    case protos::pbzero::TrackEvent::TYPE_INSTANT:
+      break;
+    case protos::pbzero::TrackEvent::TYPE_COUNTER:
+    case protos::pbzero::TrackEvent::TYPE_UNSPECIFIED:
+      // TODO(skyostil): Support counters.
+      return;
+  }
+
+  ParsedTrackEvent parsed_event{track_event};
+  parsed_event.timestamp_ns = timestamp;
+  parsed_event.duration_ns = duration;
+  parsed_event.stack_depth = depth;
+  parsed_event.category = category;
+  parsed_event.name = name;
+  parsed_event.name_hash = name_hash;
+  delegate.OnTrackEvent(*track, parsed_event);
+
+  if (track_event.type() == protos::pbzero::TrackEvent::TYPE_SLICE_END &&
+      !track->stack.empty()) {
+    track->stack.pop_back();
+  }
+}
+
+// static
+void TrackEventStateTracker::UpdateIncrementalState(
+    Delegate& delegate,
+    SequenceState& sequence_state,
+    const protos::pbzero::TracePacket_Decoder& packet) {
+#if PERFETTO_DCHECK_IS_ON()
+  if (!sequence_state.sequence_id) {
+    sequence_state.sequence_id = packet.trusted_packet_sequence_id();
+  } else {
+    PERFETTO_DCHECK(sequence_state.sequence_id ==
+                    packet.trusted_packet_sequence_id());
+  }
+#endif
+
+  perfetto::protos::pbzero::ClockSnapshot::Decoder snapshot(
+      packet.clock_snapshot());
+  for (auto it = snapshot.clocks(); it; ++it) {
+    perfetto::protos::pbzero::ClockSnapshot::Clock::Decoder clock(*it);
+    // TODO(mohitms) : Handle the incremental clock other than default one.
+    if (clock.is_incremental() &&
+        clock.clock_id() ==
+            internal::TrackEventIncrementalState::kClockIdIncremental) {
+      sequence_state.most_recent_absolute_time_ns =
+          clock.timestamp() * clock.unit_multiplier_ns();
+      break;
+    }
+  }
+
+  if (packet.sequence_flags() &
+      perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
+    // Convert any existing event names and categories on the stack to
+    // non-interned strings so we can look up their names even after the
+    // incremental state is gone.
+    for (auto& frame : sequence_state.track.stack) {
+      if (frame.name_iid) {
+        frame.name = sequence_state.event_names[frame.name_iid];
+        frame.name_iid = 0u;
+      }
+      if (frame.category_iid) {
+        frame.category = sequence_state.event_categories[frame.category_iid];
+        frame.category_iid = 0u;
+      }
+    }
+    sequence_state.event_names.clear();
+    sequence_state.event_categories.clear();
+    sequence_state.debug_annotation_names.clear();
+    sequence_state.track.uuid = 0u;
+    sequence_state.track.index = 0u;
+  }
+  if (packet.has_interned_data()) {
+    perfetto::protos::pbzero::InternedData::Decoder interned_data(
+        packet.interned_data());
+    for (auto it = interned_data.event_names(); it; it++) {
+      perfetto::protos::pbzero::EventName::Decoder entry(*it);
+      sequence_state.event_names[entry.iid()] = entry.name().ToStdString();
+    }
+    for (auto it = interned_data.event_categories(); it; it++) {
+      perfetto::protos::pbzero::EventCategory::Decoder entry(*it);
+      sequence_state.event_categories[entry.iid()] = entry.name().ToStdString();
+    }
+    for (auto it = interned_data.debug_annotation_names(); it; it++) {
+      perfetto::protos::pbzero::DebugAnnotationName::Decoder entry(*it);
+      sequence_state.debug_annotation_names[entry.iid()] =
+          entry.name().ToStdString();
+    }
+  }
+  if (packet.has_trace_packet_defaults()) {
+    perfetto::protos::pbzero::TracePacketDefaults::Decoder defaults(
+        packet.trace_packet_defaults());
+    if (defaults.has_track_event_defaults()) {
+      perfetto::protos::pbzero::TrackEventDefaults::Decoder
+          track_event_defaults(defaults.track_event_defaults());
+      sequence_state.track.uuid = track_event_defaults.track_uuid();
+      if (defaults.has_timestamp_clock_id())
+        sequence_state.default_clock_id = defaults.timestamp_clock_id();
+    }
+  }
+  if (packet.has_track_descriptor()) {
+    perfetto::protos::pbzero::TrackDescriptor::Decoder track_descriptor(
+        packet.track_descriptor());
+    auto* session_state = delegate.GetSessionState();
+    auto& track = session_state->tracks[track_descriptor.uuid()];
+    if (!track.index)
+      track.index = static_cast<uint32_t>(session_state->tracks.size() + 1);
+    track.uuid = track_descriptor.uuid();
+
+    track.name = track_descriptor.name().ToStdString();
+    track.pid = 0;
+    track.tid = 0;
+    if (track_descriptor.has_process()) {
+      perfetto::protos::pbzero::ProcessDescriptor::Decoder process(
+          track_descriptor.process());
+      track.pid = process.pid();
+      if (track.name.empty())
+        track.name = process.process_name().ToStdString();
+    } else if (track_descriptor.has_thread()) {
+      perfetto::protos::pbzero::ThreadDescriptor::Decoder thread(
+          track_descriptor.thread());
+      track.pid = thread.pid();
+      track.tid = thread.tid();
+      if (track.name.empty())
+        track.name = thread.thread_name().ToStdString();
+    }
+    delegate.OnTrackUpdated(track);
+
+    // Mirror properties to the default track of the sequence. Note that
+    // this does not catch updates to the default track written through other
+    // sequences.
+    if (track.uuid == sequence_state.track.uuid) {
+      sequence_state.track.index = track.index;
+      sequence_state.track.name = track.name;
+      sequence_state.track.pid = track.pid;
+      sequence_state.track.tid = track.tid;
+      sequence_state.track.user_data = track.user_data;
+    }
+  }
+}
+
+TrackEventStateTracker::ParsedTrackEvent::ParsedTrackEvent(
+    const perfetto::protos::pbzero::TrackEvent::Decoder& track_event_)
+    : track_event(track_event_) {}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/virtual_destructors.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+
+// This translation unit contains the definitions for the destructor of pure
+// virtual interfaces for the src/public:public target. The alternative would be
+// introducing a one-liner .cc file for each pure virtual interface, which is
+// overkill. This is for compliance with -Wweak-vtables.
+
+namespace perfetto {
+namespace internal {
+
+TracingTLS::~TracingTLS() {
+  // Avoid entering trace points while the thread is being torn down.
+  // This is the problem: when a thread exits, the at-thread-exit destroys the
+  // TracingTLS. As part of that the various TraceWriter for the active data
+  // sources are destroyd. A TraceWriter dtor will issue a PostTask on the IPC
+  // thread to issue a final flush and unregister its ID with the service.
+  // The PostTask, in chromium, might have a trace event that will try to
+  // re-enter the tracing system.
+  // We fix this by resetting the TLS key to the TracingTLS object that is
+  // being destroyed in the platform impl (platform_posix.cc,
+  // platform_windows.cc, chromium's platform.cc). We carefully rely on the fact
+  // that all the tracing path that will be invoked during thread exit will
+  // early out if |is_in_trace_point| == true and will not depend on the other
+  // TLS state that has been destroyed.
+  is_in_trace_point = true;
+}
+
+}  // namespace internal
+
+TracingProducerBackend::~TracingProducerBackend() = default;
+TracingConsumerBackend::~TracingConsumerBackend() = default;
+TracingBackend::~TracingBackend() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/android_stats/statsd_logging_helper.cc
+// gen_amalgamated begin header: src/android_stats/statsd_logging_helper.h
+// gen_amalgamated begin header: src/android_stats/perfetto_atoms.h
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
+#define SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
+
+namespace perfetto {
+
+// This must match the values of the PerfettoUploadEvent enum in:
+// frameworks/proto_logging/stats/atoms.proto
+enum class PerfettoStatsdAtom {
+  kUndefined = 0,
+
+  // Checkpoints inside perfetto_cmd before tracing is finished.
+  kTraceBegin = 1,
+  kBackgroundTraceBegin = 2,
+  kOnConnect = 3,
+
+  // Guardrails inside perfetto_cmd before tracing is finished.
+  kOnTimeout = 16,
+  kCmdUserBuildTracingNotAllowed = 43,
+  kCmdFailedToInitGuardrailState = 44,
+  kCmdInvalidGuardrailState = 45,
+  kCmdHitUploadLimit = 46,
+
+  // Checkpoints inside traced.
+  kTracedEnableTracing = 37,
+  kTracedStartTracing = 38,
+  kTracedDisableTracing = 39,
+  kTracedNotifyTracingDisabled = 40,
+
+  // Trigger checkpoints inside traced.
+  // These atoms are special because, along with the UUID,
+  // they log the trigger name.
+  kTracedTriggerStartTracing = 41,
+  kTracedTriggerStopTracing = 42,
+  kTracedTriggerCloneSnapshot = 53,
+
+  // Guardrails inside traced.
+  kTracedEnableTracingExistingTraceSession = 18,
+  kTracedEnableTracingTooLongTrace = 19,
+  kTracedEnableTracingInvalidTriggerTimeout = 20,
+  kTracedEnableTracingDurationWithTrigger = 21,
+  kTracedEnableTracingStopTracingWriteIntoFile = 22,
+  kTracedEnableTracingDuplicateTriggerName = 23,
+  kTracedEnableTracingInvalidDeferredStart = 24,
+  kTracedEnableTracingInvalidBufferSize = 25,
+  kTracedEnableTracingBufferSizeTooLarge = 26,
+  kTracedEnableTracingTooManyBuffers = 27,
+  kTracedEnableTracingDuplicateSessionName = 28,
+  kTracedEnableTracingSessionNameTooRecent = 29,
+  kTracedEnableTracingTooManySessionsForUid = 30,
+  kTracedEnableTracingTooManyConcurrentSessions = 31,
+  kTracedEnableTracingInvalidFdOutputFile = 32,
+  kTracedEnableTracingFailedToCreateFile = 33,
+  kTracedEnableTracingOom = 34,
+  kTracedEnableTracingUnknown = 35,
+  kTracedStartTracingInvalidSessionState = 36,
+  kTracedEnableTracingInvalidFilter = 47,
+  kTracedEnableTracingOobTargetBuffer = 48,
+  kTracedEnableTracingInvalidTriggerMode = 52,
+
+  // Checkpoints inside perfetto_cmd after tracing has finished.
+  kOnTracingDisabled = 4,
+  kFinalizeTraceAndExit = 11,
+  kCmdFwReportBegin = 49,
+  // Will be removed once incidentd is no longer used.
+  kUploadIncidentBegin = 8,
+  kNotUploadingEmptyTrace = 17,
+
+  // Guardrails inside perfetto_cmd after tracing has finished.
+  kCmdFwReportEmptyTrace = 50,
+  // Will be removed once incidentd is no longer used.
+  kUploadIncidentFailure = 10,
+
+  // "Successful" terminal states inside perfetto_cmd.
+  kCmdFwReportHandoff = 51,
+
+  // Deprecated as "success" is misleading; it simply means we were
+  // able to communicate with incidentd. Will be removed once
+  // incidentd is no longer used.
+  kUploadIncidentSuccess = 9,
+
+  // Contained trigger begin/success/failure. Replaced by
+  // |PerfettoTriggerAtom| to allow aggregation using a count metric
+  // and reduce spam.
+  // reserved 12, 13, 14;
+
+  // Contained that a guardrail in perfetto_cmd was hit. Replaced with
+  // kCmd* guardrails.
+  // reserved 15;
+
+  // Contained status of Dropbox uploads. Removed as Perfetto no
+  // longer supports uploading traces using Dropbox.
+  // reserved 5, 6, 7;
+};
+
+// This must match the values of the PerfettoTrigger::TriggerType enum in:
+// frameworks/proto_logging/stats/atoms.proto
+enum PerfettoTriggerAtom {
+  kUndefined = 0,
+
+  kCmdTrigger = 1,
+  kCmdTriggerFail = 2,
+
+  kTriggerPerfettoTrigger = 3,
+  kTriggerPerfettoTriggerFail = 4,
+
+  kTracedLimitProbability = 5,
+  kTracedLimitMaxPer24h = 6,
+
+  kProbesProducerTrigger = 7,
+  kProbesProducerTriggerFail = 8,
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
+#define SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "src/android_stats/perfetto_atoms.h"
+
+namespace perfetto {
+namespace android_stats {
+
+// Functions in this file are only active on built in the Android
+// tree. On other platforms (including Android standalone and Chromium
+// on Android) these functions are a noop.
+
+// Logs the upload event to statsd if built in the Android tree.
+void MaybeLogUploadEvent(PerfettoStatsdAtom atom,
+                         int64_t uuid_lsb,
+                         int64_t uuid_msb,
+                         const std::string& trigger_name = "");
+
+// Logs the trigger events to statsd if built in the Android tree.
+void MaybeLogTriggerEvent(PerfettoTriggerAtom atom, const std::string& trigger);
+
+// Logs the trigger events to statsd if built in the Android tree.
+void MaybeLogTriggerEvents(PerfettoTriggerAtom atom,
+                           const std::vector<std::string>& triggers);
+
+}  // namespace android_stats
+}  // namespace perfetto
+
+#endif  // SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "src/android_stats/statsd_logging_helper.h"
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+// gen_amalgamated expanded: #include "src/android_internal/lazy_library_loader.h"  // nogncheck
+// gen_amalgamated expanded: #include "src/android_internal/statsd_logging.h"       // nogncheck
+#endif
+
+namespace perfetto {
+namespace android_stats {
+
+// Make sure we don't accidentally log on non-Android tree build. Note that even
+// removing this ifdef still doesn't make uploads work on OS_ANDROID.
+// PERFETTO_LAZY_LOAD will return a nullptr on non-Android and non-in-tree
+// builds as libperfetto_android_internal will not be available.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+
+void MaybeLogUploadEvent(PerfettoStatsdAtom atom,
+                         int64_t uuid_lsb,
+                         int64_t uuid_msb,
+                         const std::string& trigger_name) {
+  PERFETTO_LAZY_LOAD(android_internal::StatsdLogUploadEvent, log_event_fn);
+  if (log_event_fn) {
+    log_event_fn(atom, uuid_lsb, uuid_msb, trigger_name.c_str());
+  }
+}
+
+void MaybeLogTriggerEvent(PerfettoTriggerAtom atom,
+                          const std::string& trigger_name) {
+  PERFETTO_LAZY_LOAD(android_internal::StatsdLogTriggerEvent, log_event_fn);
+  if (log_event_fn) {
+    log_event_fn(atom, trigger_name.c_str());
+  }
+}
+
+void MaybeLogTriggerEvents(PerfettoTriggerAtom atom,
+                           const std::vector<std::string>& triggers) {
+  PERFETTO_LAZY_LOAD(android_internal::StatsdLogTriggerEvent, log_event_fn);
+  if (log_event_fn) {
+    for (const std::string& trigger_name : triggers) {
+      log_event_fn(atom, trigger_name.c_str());
+    }
+  }
+}
+
+#else
+void MaybeLogUploadEvent(PerfettoStatsdAtom,
+                         int64_t,
+                         int64_t,
+                         const std::string&) {}
+void MaybeLogTriggerEvent(PerfettoTriggerAtom, const std::string&) {}
+void MaybeLogTriggerEvents(PerfettoTriggerAtom,
+                           const std::vector<std::string>&) {}
+#endif
+
+}  // namespace android_stats
+}  // namespace perfetto
+// gen_amalgamated begin source: src/base/version.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/version.h
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
+#define INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
+
+namespace perfetto {
+namespace base {
+
+// The returned pointer is a static string is safe to pass around.
+const char* GetVersionString();
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
+// gen_amalgamated begin header: gen/perfetto_version.gen.h
+// Generated by write_version_header.py
+
+#ifndef GEN_PERFETTO_VERSION_GEN_H_
+#define GEN_PERFETTO_VERSION_GEN_H_
+
+#define PERFETTO_VERSION_STRING() "v41.0-648017d73"
+#define PERFETTO_VERSION_SCM_REVISION() "648017d734027f96fc817f98863693a679bcd390"
+
+#endif  // GEN_PERFETTO_VERSION_GEN_H_
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#include <stdio.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_VERSION_GEN)
+// gen_amalgamated expanded: #include "perfetto_version.gen.h"
+#else
+#define PERFETTO_VERSION_STRING() "v0.0"
+#define PERFETTO_VERSION_SCM_REVISION() "unknown"
+#endif
+
+namespace perfetto {
+namespace base {
+
+const char* GetVersionString() {
+  static const char* version_str = [] {
+    static constexpr size_t kMaxLen = 256;
+    char* version = new char[kMaxLen + 1];
+    snprintf(version, kMaxLen, "Perfetto %s (%s)", PERFETTO_VERSION_STRING(),
+             PERFETTO_VERSION_SCM_REVISION());
+    return version;
+  }();
+  return version_str;
+}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/protozero/filtering/filter_bytecode_parser.cc
+// gen_amalgamated begin header: src/protozero/filtering/filter_bytecode_parser.h
+/*
+ * 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.
+ */
+
+#ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
+#define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <optional>
+#include <vector>
+
+namespace protozero {
+
+// Loads the proto-encoded bytecode in memory and allows fast lookups for tuples
+// (msg_index, field_id) to tell if a given field should be allowed or not and,
+// in the case of nested fields, what is the next message index to recurse into.
+// This class does two things:
+// 1. Expands the array of varint from the proto into a vector<uint32_t>. This
+//    is to avoid performing varint decoding on every lookup, at the cost of
+//    some extra memory (2KB-4KB). Note that the expanded vector is not just a
+//    1:1 copy of the proto one (more below). This is to avoid O(Fields) linear
+//    lookup complexity.
+// 2. Creates an index of offsets to remember the start word for each message.
+//    This is so we can jump to O(1) to the N-th message when recursing into a
+//    nested fields, without having to scan and find the (N-1)-th END_OF_MESSAGE
+//    marker.
+// Overall lookups are O(1) for field ids < 128 (kDirectlyIndexLimit) and O(N),
+// with N being the number of allowed field ranges for other fields.
+// See comments around |word_| below for the structure of the word vector.
+class FilterBytecodeParser {
+ public:
+  // Result of a Query() operation
+  struct QueryResult {
+    bool allowed;  // Whether the field is allowed at all or no.
+
+    // If |allowed|==true && nested_msg_field() == true, this tells the message
+    // index of the nested field that should be used when recursing in the
+    // parser.
+    uint32_t nested_msg_index;
+
+    // If |allowed|==true, specifies if the field is of a simple type (varint,
+    // fixed32/64, string or byte).
+    bool simple_field() const { return nested_msg_index == kSimpleField; }
+
+    // If |allowed|==true, specifies if this field is a string field that needs
+    // to be filtered.
+    bool filter_string_field() const {
+      return nested_msg_index == kFilterStringField;
+    }
+
+    // If |allowed|==true, specifies if the field is a nested field that needs
+    // recursion. The caller is expected to use |nested_msg_index| for the next
+    // Query() calls.
+    bool nested_msg_field() const {
+      static_assert(kFilterStringField < kSimpleField,
+                    "kFilterStringField < kSimpleField");
+      return nested_msg_index < kFilterStringField;
+    }
+  };
+
+  // Loads a filter. The filter data consists of a sequence of varints which
+  // contains the filter opcodes and a final checksum.
+  bool Load(const void* filter_data, size_t len);
+
+  // Checks wheter a given field is allowed or not.
+  // msg_index = 0 is the index of the root message, where all queries should
+  // start from (typically perfetto.protos.Trace).
+  QueryResult Query(uint32_t msg_index, uint32_t field_id) const;
+
+  void Reset();
+  void set_suppress_logs_for_fuzzer(bool x) { suppress_logs_for_fuzzer_ = x; }
+
+ private:
+  static constexpr uint32_t kDirectlyIndexLimit = 128;
+  static constexpr uint32_t kAllowed = 1u << 31u;
+  static constexpr uint32_t kSimpleField = 0x7fffffff;
+  static constexpr uint32_t kFilterStringField = 0x7ffffffe;
+
+  bool LoadInternal(const uint8_t* filter_data, size_t len);
+
+  // The state of all fields for all messages is stored in one contiguous array.
+  // This is to avoid memory fragmentation and allocator overhead.
+  // We expect a high number of messages (hundreds), but each message is small.
+  // For each message we store two sets of uint32:
+  // 1. A set of "directly indexed" fields, for field ids < 128.
+  // 2. The remainder is a set of ranges.
+  // So each message descriptor consists of a sequence of words as follows:
+  //
+  // [0] -> how many directly indexed fields are stored next (up to 128)
+  //
+  // [1..N] -> One word per field id (See "field state" below).
+  //
+  // [N + 1] -> Start of field id range 1
+  // [N + 2] -> End of field id range 1 (exclusive, STL-style).
+  // [N + 3] -> Field state for fields in range 1 (below)
+  //
+  // [N + 4] -> Start of field id range 2
+  // [N + 5] -> End of field id range 2 (exclusive, STL-style).
+  // [N + 6] -> Field state for fields in range 2 (below)
+
+  // The "field state" word is as follows:
+  // Bit 31: 1 if the field is allowed, 0 if disallowed.
+  //         Only directly indexed fields can be 0 (it doesn't make sense to add
+  //         a range and then say "btw it's NOT allowed".. don't add it then.
+  //         0 is only used for filling gaps in the directly indexed bucket.
+  // Bits [30..0] (only when MSB == allowed):
+  //  0x7fffffff: The field is "simple" (varint, fixed32/64, string, bytes) and
+  //      can be directly passed through in output. No recursion is needed.
+  //  0x7ffffffe: The field is string field which needs to be filtered.
+  //  [0, 7ffffffd]: The field is a nested submessage. The value is the index
+  //     that must be passed as first argument to the next Query() calls.
+  //     Note that the message index is purely a monotonic counter in the
+  std::vector<uint32_t> words_;
+
+  // One entry for each message index stored in the filter plus a sentinel at
+  // the end. Maps each message index to the offset in |words_| where the
+  // Nth message start.
+  // message_offset_.size() - 2 == the max message id that can be parsed.
+  std::vector<uint32_t> message_offset_;
+
+  bool suppress_logs_for_fuzzer_ = false;
+};
+
+}  // namespace protozero
+
+#endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
+// gen_amalgamated begin header: src/protozero/filtering/filter_bytecode_common.h
+/*
+ * 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.
+ */
+
+#ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
+#define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
+
+#include <stdint.h>
+
+namespace protozero {
+
+enum FilterOpcode : uint32_t {
+  // The immediate value is 0 in this case.
+  kFilterOpcode_EndOfMessage = 0,
+
+  // The immediate value is the id of the allowed field.
+  kFilterOpcode_SimpleField = 1,
+
+  // The immediate value is the start of the range. The next word (without
+  // any shifting) is the length of the range.
+  kFilterOpcode_SimpleFieldRange = 2,
+
+  // The immediate value is the id of the allowed field. The next word
+  // (without any shifting) is the index of the filter that should be used to
+  // recurse into the nested message.
+  kFilterOpcode_NestedField = 3,
+
+  // The imediate value is the id of the allowed field. The behaviour of this
+  // opcode is the same as kFilterOpcode_SimpleField, with the further semantic
+  // that the field is a string and needs to be processed using the string
+  // filtering fules.
+  kFilterOpcode_FilterString = 4,
+};
+
+}  // namespace protozero
+
+#endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_parser.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_common.h"
+
+namespace protozero {
+
+void FilterBytecodeParser::Reset() {
+  bool suppress = suppress_logs_for_fuzzer_;
+  *this = FilterBytecodeParser();
+  suppress_logs_for_fuzzer_ = suppress;
+}
+
+bool FilterBytecodeParser::Load(const void* filter_data, size_t len) {
+  Reset();
+  bool res = LoadInternal(static_cast<const uint8_t*>(filter_data), len);
+  // If load fails, don't leave the parser in a half broken state.
+  if (!res)
+    Reset();
+  return res;
+}
+
+bool FilterBytecodeParser::LoadInternal(const uint8_t* bytecode_data,
+                                        size_t len) {
+  // First unpack the varints into a plain uint32 vector, so it's easy to
+  // iterate through them and look ahead.
+  std::vector<uint32_t> words;
+  bool packed_parse_err = false;
+  words.reserve(len);  // An overestimation, but avoids reallocations.
+  using BytecodeDecoder =
+      PackedRepeatedFieldIterator<proto_utils::ProtoWireType::kVarInt,
+                                  uint32_t>;
+  for (BytecodeDecoder it(bytecode_data, len, &packed_parse_err); it; ++it)
+    words.emplace_back(*it);
+
+  if (packed_parse_err || words.empty())
+    return false;
+
+  perfetto::base::Hasher hasher;
+  for (size_t i = 0; i < words.size() - 1; ++i)
+    hasher.Update(words[i]);
+
+  uint32_t expected_csum = static_cast<uint32_t>(hasher.digest());
+  if (expected_csum != words.back()) {
+    if (!suppress_logs_for_fuzzer_) {
+      PERFETTO_ELOG("Filter bytecode checksum failed. Expected: %x, actual: %x",
+                    expected_csum, words.back());
+    }
+    return false;
+  }
+
+  words.pop_back();  // Pop the checksum.
+
+  // Temporay storage for each message. Cleared on every END_OF_MESSAGE.
+  std::vector<uint32_t> direct_indexed_fields;
+  std::vector<uint32_t> ranges;
+  uint32_t max_msg_index = 0;
+
+  auto add_directly_indexed_field = [&](uint32_t field_id, uint32_t msg_id) {
+    PERFETTO_DCHECK(field_id > 0 && field_id < kDirectlyIndexLimit);
+    direct_indexed_fields.resize(std::max(direct_indexed_fields.size(),
+                                          static_cast<size_t>(field_id) + 1));
+    direct_indexed_fields[field_id] = kAllowed | msg_id;
+  };
+
+  auto add_range = [&](uint32_t id_start, uint32_t id_end, uint32_t msg_id) {
+    PERFETTO_DCHECK(id_end > id_start);
+    PERFETTO_DCHECK(id_start >= kDirectlyIndexLimit);
+    ranges.emplace_back(id_start);
+    ranges.emplace_back(id_end);
+    ranges.emplace_back(kAllowed | msg_id);
+  };
+
+  bool is_eom = true;
+  for (size_t i = 0; i < words.size(); ++i) {
+    const uint32_t word = words[i];
+    const bool has_next_word = i < words.size() - 1;
+    const uint32_t opcode = word & 0x7u;
+    const uint32_t field_id = word >> 3;
+
+    is_eom = opcode == kFilterOpcode_EndOfMessage;
+    if (field_id == 0 && opcode != kFilterOpcode_EndOfMessage) {
+      PERFETTO_DLOG("bytecode error @ word %zu, invalid field id (0)", i);
+      return false;
+    }
+
+    if (opcode == kFilterOpcode_SimpleField ||
+        opcode == kFilterOpcode_NestedField ||
+        opcode == kFilterOpcode_FilterString) {
+      // Field words are organized as follow:
+      // MSB: 1 if allowed, 0 if not allowed.
+      // Remaining bits:
+      //   Message index in the case of nested (non-simple) messages.
+      //   0x7f..e in the case of string fields which need filtering.
+      //   0x7f..f in the case of simple fields.
+      uint32_t msg_id;
+      if (opcode == kFilterOpcode_SimpleField) {
+        msg_id = kSimpleField;
+      } else if (opcode == kFilterOpcode_FilterString) {
+        msg_id = kFilterStringField;
+      } else {  // FILTER_OPCODE_NESTED_FIELD
+        // The next word in the bytecode contains the message index.
+        if (!has_next_word) {
+          PERFETTO_DLOG("bytecode error @ word %zu: unterminated nested field",
+                        i);
+          return false;
+        }
+        msg_id = words[++i];
+        max_msg_index = std::max(max_msg_index, msg_id);
+      }
+
+      if (field_id < kDirectlyIndexLimit) {
+        add_directly_indexed_field(field_id, msg_id);
+      } else {
+        // In the case of a large field id (rare) we waste an extra word and
+        // represent it as a range. Doesn't make sense to introduce extra
+        // complexity to deal with rare cases like this.
+        add_range(field_id, field_id + 1, msg_id);
+      }
+    } else if (opcode == kFilterOpcode_SimpleFieldRange) {
+      if (!has_next_word) {
+        PERFETTO_DLOG("bytecode error @ word %zu: unterminated range", i);
+        return false;
+      }
+      const uint32_t range_len = words[++i];
+      const uint32_t range_end = field_id + range_len;  // STL-style, excl.
+      uint32_t id = field_id;
+
+      // Here's the subtle complexity: at the bytecode level, we don't know
+      // anything about the kDirectlyIndexLimit. It is legit to define a range
+      // that spans across the direct-indexing threshold (e.g. 126-132). In that
+      // case we want to add all the elements < the indexing to the O(1) bucket
+      // and add only the remaining range as a non-indexed range.
+      for (; id < range_end && id < kDirectlyIndexLimit; ++id)
+        add_directly_indexed_field(id, kAllowed | kSimpleField);
+      PERFETTO_DCHECK(id >= kDirectlyIndexLimit || id == range_end);
+      if (id < range_end)
+        add_range(id, range_end, kSimpleField);
+    } else if (opcode == kFilterOpcode_EndOfMessage) {
+      // For each message append:
+      // 1. The "header" word telling how many directly indexed fields there
+      //    are.
+      // 2. The words for the directly indexed fields (id < 128).
+      // 3. The rest of the fields, encoded as ranges.
+      // Also update the |message_offset_| index to remember the word offset for
+      // the current message.
+      message_offset_.emplace_back(static_cast<uint32_t>(words_.size()));
+      words_.emplace_back(static_cast<uint32_t>(direct_indexed_fields.size()));
+      words_.insert(words_.end(), direct_indexed_fields.begin(),
+                    direct_indexed_fields.end());
+      words_.insert(words_.end(), ranges.begin(), ranges.end());
+      direct_indexed_fields.clear();
+      ranges.clear();
+    } else {
+      PERFETTO_DLOG("bytecode error @ word %zu: invalid opcode (%x)", i, word);
+      return false;
+    }
+  }  // (for word in bytecode).
+
+  if (!is_eom) {
+    PERFETTO_DLOG(
+        "bytecode error: end of message not the last word in the bytecode");
+    return false;
+  }
+
+  if (max_msg_index > 0 && max_msg_index >= message_offset_.size()) {
+    PERFETTO_DLOG(
+        "bytecode error: a message index (%u) is out of range "
+        "(num_messages=%zu)",
+        max_msg_index, message_offset_.size());
+    return false;
+  }
+
+  // Add a final entry to |message_offset_| so we can tell where the last
+  // message ends without an extra branch in the Query() hotpath.
+  message_offset_.emplace_back(static_cast<uint32_t>(words_.size()));
+
+  return true;
+}
+
+FilterBytecodeParser::QueryResult FilterBytecodeParser::Query(
+    uint32_t msg_index,
+    uint32_t field_id) const {
+  FilterBytecodeParser::QueryResult res{false, 0u};
+  if (static_cast<uint64_t>(msg_index) + 1 >=
+      static_cast<uint64_t>(message_offset_.size())) {
+    return res;
+  }
+  const uint32_t start_offset = message_offset_[msg_index];
+  // These are DCHECKs and not just CHECKS because the |words_| is populated
+  // by the LoadInternal call above. These cannot be violated with a malformed
+  // bytecode.
+  PERFETTO_DCHECK(start_offset < words_.size());
+  const uint32_t* word = &words_[start_offset];
+  const uint32_t end_off = message_offset_[msg_index + 1];
+  const uint32_t* const end = words_.data() + end_off;
+  PERFETTO_DCHECK(end > word && end <= words_.data() + words_.size());
+  const uint32_t num_directly_indexed = *(word++);
+  PERFETTO_DCHECK(num_directly_indexed <= kDirectlyIndexLimit);
+  PERFETTO_DCHECK(word + num_directly_indexed <= end);
+  uint32_t field_state = 0;
+  if (PERFETTO_LIKELY(field_id < num_directly_indexed)) {
+    PERFETTO_DCHECK(&word[field_id] < end);
+    field_state = word[field_id];
+  } else {
+    for (word = word + num_directly_indexed; word + 2 < end;) {
+      const uint32_t range_start = *(word++);
+      const uint32_t range_end = *(word++);
+      const uint32_t range_state = *(word++);
+      if (field_id >= range_start && field_id < range_end) {
+        field_state = range_state;
+        break;
+      }
+    }  // for (word in ranges)
+  }    // if (field_id >= num_directly_indexed)
+
+  res.allowed = (field_state & kAllowed) != 0;
+  res.nested_msg_index = field_state & ~kAllowed;
+  PERFETTO_DCHECK(!res.nested_msg_field() ||
+                  res.nested_msg_index < message_offset_.size() - 1);
+  return res;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/filtering/string_filter.cc
+// gen_amalgamated begin header: src/protozero/filtering/string_filter.h
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef SRC_PROTOZERO_FILTERING_STRING_FILTER_H_
+#define SRC_PROTOZERO_FILTERING_STRING_FILTER_H_
+
+#include <regex>
+#include <string>
+#include <string_view>
+
+namespace protozero {
+
+// Performs filtering of strings in an "iptables" style. See the comments in
+// |TraceConfig.TraceFilter| for information on how this class works.
+class StringFilter {
+ public:
+  enum class Policy {
+    kMatchRedactGroups = 1,
+    kAtraceMatchRedactGroups = 2,
+    kMatchBreak = 3,
+    kAtraceMatchBreak = 4,
+    kAtraceRepeatedSearchRedactGroups = 5,
+  };
+
+  // Adds a new rule for filtering strings.
+  void AddRule(Policy policy,
+               std::string_view pattern,
+               std::string atrace_payload_starts_with);
+
+  // Tries to filter the given string. Returns true if the string was modified
+  // in any way, false otherwise.
+  bool MaybeFilter(char* ptr, size_t len) const {
+    if (len == 0 || rules_.empty()) {
+      return false;
+    }
+    return MaybeFilterInternal(ptr, len);
+  }
+
+ private:
+  struct Rule {
+    Policy policy;
+    std::regex pattern;
+    std::string atrace_payload_starts_with;
+  };
+
+  bool MaybeFilterInternal(char* ptr, size_t len) const;
+
+  std::vector<Rule> rules_;
+};
+
+}  // namespace protozero
+
+#endif  // SRC_PROTOZERO_FILTERING_STRING_FILTER_H_
+/*
+ * Copyright (C) 2023 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.
+ */
+
+// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"
+
+#include <cstring>
+#include <regex>
+#include <string_view>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
+// gen_amalgamated expanded: #include "perfetto/public/compiler.h"
+
+namespace protozero {
+namespace {
+
+using Matches = std::match_results<char*>;
+
+static constexpr std::string_view kRedacted = "P60REDACTED";
+static constexpr char kRedactedDash = '-';
+
+// Returns a pointer to the first character after the tgid pipe character in
+// the atrace string given by [ptr, end). Returns null if no such character
+// exists.
+//
+// Examples:
+// E|1024 -> nullptr
+// foobarbaz -> nullptr
+// B|1024|x -> pointer to x
+const char* FindAtracePayloadPtr(const char* ptr, const char* end) {
+  // Don't even bother checking any strings which are so short that they could
+  // not contain a post-tgid section. This filters out strings like "E|" which
+  // emitted by Bionic.
+  //
+  // Also filter out any other strings starting with "E" as they never contain
+  // anything past the tgid: this removes >half of the strings for ~zero cost.
+  static constexpr size_t kEarliestSecondPipeIndex = 2;
+  const char* search_start = ptr + kEarliestSecondPipeIndex;
+  if (search_start >= end || *ptr == 'E') {
+    return nullptr;
+  }
+
+  // We skipped past the first '|' character by starting at the character at
+  // index 2. Just find the next pipe character (i.e. the one after tgid) using
+  // memchr.
+  const char* pipe = static_cast<const char*>(
+      memchr(search_start, '|', size_t(end - search_start)));
+  return pipe ? pipe + 1 : nullptr;
+}
+
+bool StartsWith(const char* ptr,
+                const char* end,
+                const std::string& starts_with) {
+  // Verify that the atrace string has enough characters to match against all
+  // the characters in the "starts with" string. If it does, memcmp to check if
+  // all the characters match and return true if they do.
+  return ptr + starts_with.size() <= end &&
+         memcmp(ptr, starts_with.data(), starts_with.size()) == 0;
+}
+
+void RedactMatches(const Matches& matches) {
+  // Go through every group in the matches.
+  for (size_t i = 1; i < matches.size(); ++i) {
+    const auto& match = matches[i];
+    PERFETTO_CHECK(match.second >= match.first);
+
+    // Overwrite the match with characters from |kRedacted|. If match is
+    // smaller, we will not use all of |kRedacted| but that's fine (i.e. we
+    // will overwrite with a truncated |kRedacted|).
+    size_t match_len = static_cast<size_t>(match.second - match.first);
+    size_t redacted_len = std::min(match_len, kRedacted.size());
+    memcpy(match.first, kRedacted.data(), redacted_len);
+
+    // Overwrite any characters after |kRedacted| with |kRedactedDash|.
+    memset(match.first + redacted_len, kRedactedDash, match_len - redacted_len);
+  }
+}
+
+}  // namespace
+
+void StringFilter::AddRule(Policy policy,
+                           std::string_view pattern_str,
+                           std::string atrace_payload_starts_with) {
+  rules_.emplace_back(StringFilter::Rule{
+      policy,
+      std::regex(pattern_str.begin(), pattern_str.end(),
+                 std::regex::ECMAScript | std::regex_constants::optimize),
+      std::move(atrace_payload_starts_with)});
+}
+
+bool StringFilter::MaybeFilterInternal(char* ptr, size_t len) const {
+  std::match_results<char*> matches;
+  bool atrace_find_tried = false;
+  const char* atrace_payload_ptr = nullptr;
+  for (const Rule& rule : rules_) {
+    switch (rule.policy) {
+      case Policy::kMatchRedactGroups:
+      case Policy::kMatchBreak:
+        if (std::regex_match(ptr, ptr + len, matches, rule.pattern)) {
+          if (rule.policy == Policy::kMatchBreak) {
+            return false;
+          }
+          RedactMatches(matches);
+          return true;
+        }
+        break;
+      case Policy::kAtraceMatchRedactGroups:
+      case Policy::kAtraceMatchBreak:
+        atrace_payload_ptr = atrace_find_tried
+                                 ? atrace_payload_ptr
+                                 : FindAtracePayloadPtr(ptr, ptr + len);
+        atrace_find_tried = true;
+        if (atrace_payload_ptr &&
+            StartsWith(atrace_payload_ptr, ptr + len,
+                       rule.atrace_payload_starts_with) &&
+            std::regex_match(ptr, ptr + len, matches, rule.pattern)) {
+          if (rule.policy == Policy::kAtraceMatchBreak) {
+            return false;
+          }
+          RedactMatches(matches);
+          return true;
+        }
+        break;
+      case Policy::kAtraceRepeatedSearchRedactGroups:
+        atrace_payload_ptr = atrace_find_tried
+                                 ? atrace_payload_ptr
+                                 : FindAtracePayloadPtr(ptr, ptr + len);
+        atrace_find_tried = true;
+        if (atrace_payload_ptr && StartsWith(atrace_payload_ptr, ptr + len,
+                                             rule.atrace_payload_starts_with)) {
+          auto beg = std::regex_iterator<char*>(ptr, ptr + len, rule.pattern);
+          auto end = std::regex_iterator<char*>();
+          bool has_any_matches = beg != end;
+          for (auto it = std::move(beg); it != end; ++it) {
+            RedactMatches(*it);
+          }
+          if (has_any_matches) {
+            return true;
+          }
+        }
+        break;
+    }
+  }
+  return false;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/protozero/filtering/message_filter.cc
+// gen_amalgamated begin header: src/protozero/filtering/message_filter.h
+// gen_amalgamated begin header: src/protozero/filtering/message_tokenizer.h
+/*
+ * 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.
+ */
+
+#ifndef SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
+#define SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
+
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+// A helper class for schema-less tokenizing of protobuf messages.
+// This class takes a stream of proto-encoded bytes, pushed one by one in input
+// via Push(octet), and returns a stream of tokens (each Push() call can return
+// 0 or 1 token).
+// A "token" contains metadata about a field, specifically: its ID, its wire
+// type and:
+//  - For varint and fixed32/64 fields: its payload.
+//  - For string and bytes fields: the length of its payload.
+//    In this case the caller is supposed to "eat" those N bytes before calling
+//    Push() again.
+// Note that this class cannot differentiate between a string/bytes field or
+// a submessage, because they are encoded in the same way. The caller is
+// supposed to know whether a field can be recursed into by just keep calling
+// Push() or is a string that should be skipped.
+// This is inline to allow the compiler to see through the Push method and
+// avoid a function call for each byte.
+class MessageTokenizer {
+ public:
+  struct Token {
+    uint32_t field_id;  // 0 == not valid.
+    proto_utils::ProtoWireType type;
+
+    // For kLengthDelimited, |value| represent the length of the payload.
+    uint64_t value;
+
+    inline bool valid() const { return field_id != 0; }
+    bool operator==(const Token& o) const {
+      return field_id == o.field_id && type == o.type && value == o.value;
+    }
+  };
+
+  // Pushes a byte in input and returns a token, only when getting to the last
+  // byte of each field. Specifically:
+  // - For varint and fixed32 fields, the Token is returned after the last byte
+  //   of the numeric payload is pushed.
+  // - For length-delimited fields, this returns after the last byte of the
+  //   length is pushed (i.e. right before the payload starts). The caller is
+  //   expected to either skip the next |value| bytes (in the case of a string
+  //   or bytes fields) or keep calling Push, in the case of a submessage.
+  inline Token Push(uint8_t octet) {
+    using protozero::proto_utils::ProtoWireType;
+
+    // Parsing a fixed32/64 field is the only case where we don't have to do
+    // any varint decoding. This is why this block is before the remaining
+    // switch statement below (all the rest is a varint).
+    if (PERFETTO_UNLIKELY(state_ == kFixedIntValue)) {
+      PERFETTO_DCHECK(fixed_int_bits_ == 32 || fixed_int_bits_ == 64);
+      fixed_int_value_ |= static_cast<uint64_t>(octet) << fixed_int_shift_;
+      fixed_int_shift_ += 8;
+      if (fixed_int_shift_ < fixed_int_bits_)
+        return Token{};  // Intermediate byte of a fixed32/64.
+      auto wire_type = fixed_int_bits_ == 32 ? ProtoWireType::kFixed32
+                                             : ProtoWireType::kFixed64;
+      uint64_t fixed_int_value = fixed_int_value_;
+      fixed_int_value_ = fixed_int_shift_ = fixed_int_bits_ = 0;
+      state_ = kFieldPreamble;
+      return Token{field_id_, wire_type, fixed_int_value};
+    }
+
+    // At this point either we are: (i) parsing a field preamble; (ii) parsing a
+    // varint field paylod; (iii) parsing the length of a length-delimited
+    // field. In all cases, we need to decode a varint before proceeding.
+    varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
+    if (octet & 0x80) {
+      varint_shift_ += 7;
+      if (PERFETTO_UNLIKELY(varint_shift_ >= 64)) {
+        varint_shift_ = 0;
+        state_ = kInvalidVarInt;
+      }
+      return Token{};  // Still parsing a varint.
+    }
+
+    uint64_t varint = varint_;
+    varint_ = 0;
+    varint_shift_ = 0;
+
+    switch (state_) {
+      case kFieldPreamble: {
+        auto field_type = static_cast<uint32_t>(varint & 7u);  // 7 = 0..0111
+        field_id_ = static_cast<uint32_t>(varint >> 3);
+
+        // The field type is legit, now check it's well formed and within
+        // boundaries.
+        if (field_type == static_cast<uint32_t>(ProtoWireType::kVarInt)) {
+          state_ = kVarIntValue;
+        } else if (field_type ==
+                       static_cast<uint32_t>(ProtoWireType::kFixed32) ||
+                   field_type ==
+                       static_cast<uint32_t>(ProtoWireType::kFixed64)) {
+          state_ = kFixedIntValue;
+          fixed_int_shift_ = 0;
+          fixed_int_value_ = 0;
+          fixed_int_bits_ =
+              field_type == static_cast<uint32_t>(ProtoWireType::kFixed32) ? 32
+                                                                           : 64;
+        } else if (field_type ==
+                   static_cast<uint32_t>(ProtoWireType::kLengthDelimited)) {
+          state_ = kLenDelimited;
+        } else {
+          state_ = kInvalidFieldType;
+        }
+        return Token{};
+      }
+
+      case kVarIntValue: {
+        // Return the varint field payload and go back to the next field.
+        state_ = kFieldPreamble;
+        return Token{field_id_, ProtoWireType::kVarInt, varint};
+      }
+
+      case kLenDelimited: {
+        const auto payload_len = varint;
+        if (payload_len > protozero::proto_utils::kMaxMessageLength) {
+          state_ = kMessageTooBig;
+          return Token{};
+        }
+        state_ = kFieldPreamble;
+        // At this point the caller is expected to consume the next
+        // |payload_len| bytes.
+        return Token{field_id_, ProtoWireType::kLengthDelimited, payload_len};
+      }
+
+      case kFixedIntValue:
+        // Unreacheable because of the if before the switch.
+        PERFETTO_DCHECK(false);
+        break;
+
+      // Unrecoverable error states.
+      case kInvalidFieldType:
+      case kMessageTooBig:
+      case kInvalidVarInt:
+        break;
+    }  // switch(state_)
+
+    return Token{};  // Keep GCC happy.
+  }
+
+  // Returns true if the tokenizer FSM has reached quiescence (i.e. if we are
+  // NOT in the middle of parsing a field).
+  bool idle() const {
+    return state_ == kFieldPreamble && varint_shift_ == 0 &&
+           fixed_int_shift_ == 0;
+  }
+
+  // Only for reporting parser errors in the trace.
+  uint32_t state() const { return static_cast<uint32_t>(state_); }
+
+ private:
+  enum State {
+    kFieldPreamble = 0,  // Parsing the varint for the field preamble.
+    kVarIntValue = 1,    // Parsing the payload of a varint field.
+    kFixedIntValue = 2,  // Parsing the payload of a fixed32/64 field.
+    kLenDelimited = 3,   // Parsing the length of a length-delimited field.
+
+    // Unrecoverable error states:
+    kInvalidFieldType = 4,  // Encountered an invalid field type.
+    kMessageTooBig = 5,     // Size of the length delimited message was too big.
+    kInvalidVarInt = 6,     // Varint larger than 64 bits.
+  };
+
+  State state_ = kFieldPreamble;
+  uint32_t field_id_ = 0;
+  uint64_t varint_ = 0;
+  uint32_t varint_shift_ = 0;
+  uint32_t fixed_int_shift_ = 0;
+  uint32_t fixed_int_bits_ = 0;
+  uint64_t fixed_int_value_ = 0;
+};
+
+}  // namespace protozero
+
+#endif  // SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
+/*
+ * 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.
+ */
+
+#ifndef SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
+#define SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+// gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_parser.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/message_tokenizer.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"
+
+namespace protozero {
+
+// A class to filter binary-encoded proto messages using an allow-list of field
+// ids, also known as "filter bytecode". The filter determines which fields are
+// allowed to be passed through in output and strips all the other fields.
+// See go/trace-filtering for full design.
+// This class takes in input:
+// 1) The filter bytecode, loaded once via the LoadFilterBytecode() method.
+// 2) A proto-encoded binary message. The message doesn't have to be contiguous,
+//    it can be passed as an array of arbitrarily chunked fragments.
+// The FilterMessage*() method returns in output a proto message, stripping out
+// all unknown fields. If the input is malformed (e.g., unknown proto field wire
+// types, lengths out of bound) the whole filtering failed and the |error| flag
+// of the FilteredMessage object is set to true.
+// The filtering operation is based on rewriting a copy of the message into a
+// self-allocated buffer, which is then returned in the output. The input buffer
+// is NOT altered.
+// Note also that the process of rewriting the protos gets rid of most redundant
+// varint encoding (if present). So even if all fields are allow-listed, the
+// output might NOT be bitwise identical to the input (but it will be
+// semantically equivalent).
+// Furthermore the enable_field_usage_tracking() method allows to keep track of
+// a histogram of allowed / denied fields. It slows down filtering and is
+// intended only on host tools.
+class MessageFilter {
+ public:
+  class Config {
+   public:
+    bool LoadFilterBytecode(const void* filter_data, size_t len);
+    bool SetFilterRoot(std::initializer_list<uint32_t> field_ids);
+
+    const FilterBytecodeParser& filter() const { return filter_; }
+    const StringFilter& string_filter() const { return string_filter_; }
+    StringFilter& string_filter() { return string_filter_; }
+    uint32_t root_msg_index() const { return root_msg_index_; }
+
+   private:
+    FilterBytecodeParser filter_;
+    StringFilter string_filter_;
+    uint32_t root_msg_index_ = 0;
+  };
+
+  MessageFilter();
+  explicit MessageFilter(Config);
+  ~MessageFilter();
+
+  struct InputSlice {
+    const void* data;
+    size_t len;
+  };
+
+  struct FilteredMessage {
+    FilteredMessage(std::unique_ptr<uint8_t[]> d, size_t s)
+        : data(std::move(d)), size(s) {}
+    std::unique_ptr<uint8_t[]> data;
+    size_t size;  // The used bytes in |data|. This is <= sizeof(data).
+    bool error = false;
+  };
+
+  // Loads the filter bytecode that will be used to filter any subsequent
+  // message. Must be called before the first call to FilterMessage*().
+  // |filter_data| must point to a byte buffer for a proto-encoded ProtoFilter
+  // message (see proto_filter.proto).
+  bool LoadFilterBytecode(const void* filter_data, size_t len) {
+    return config_.LoadFilterBytecode(filter_data, len);
+  }
+
+  // This affects the filter starting point of the subsequent FilterMessage*()
+  // calls. By default the filtering process starts from the message @ index 0,
+  // the root message passed to proto_filter when generating the bytecode
+  // (in typical tracing use-cases, this is perfetto.protos.Trace). However, the
+  // caller (TracingServiceImpl) might want to filter packets from the 2nd level
+  // (perfetto.protos.TracePacket) because the root level is pre-pended after
+  // the fact. This call allows to change the root message for the filter.
+  // The argument |field_ids| is an array of proto field ids and determines the
+  // path to the new root. For instance, in the case of [1,2,3] SetFilterRoot
+  // will identify the sub-message for the field "root.1.2.3" and use that.
+  // In order for this to succeed all the fields in the path must be allowed
+  // in the filter and must be a nested message type.
+  bool SetFilterRoot(std::initializer_list<uint32_t> field_ids) {
+    return config_.SetFilterRoot(field_ids);
+  }
+
+  // Takes an input message, fragmented in arbitrary slices, and returns a
+  // filtered message in output.
+  FilteredMessage FilterMessageFragments(const InputSlice*, size_t num_slices);
+
+  // Helper for tests, where the input is a contiguous buffer.
+  FilteredMessage FilterMessage(const void* data, size_t len) {
+    InputSlice slice{data, len};
+    return FilterMessageFragments(&slice, 1);
+  }
+
+  // When enabled returns a map of "field path" to "usage counter".
+  // The key (std::string) is a binary buffer (i.e. NOT an ASCII/UTF-8 string)
+  // which contains a varint for each field. Consider the following:
+  // message Root { Sub1 f1 = 1; };
+  // message Sub1 { Sub2 f2 = 7;}
+  // message Sub2 { string f3 = 5; }
+  // The field .f1.f2.f3 will be encoded as \x01\0x07\x05.
+  // The value is the number of times that field has been encountered. If the
+  // field is not allow-listed in the bytecode (the field is stripped in output)
+  // the count will be negative.
+  void enable_field_usage_tracking(bool x) { track_field_usage_ = x; }
+  const std::unordered_map<std::string, int32_t>& field_usage() const {
+    return field_usage_;
+  }
+
+  const Config& config() const { return config_; }
+
+  // Retuns the helper class used to perform string filtering.
+  StringFilter& string_filter() { return config_.string_filter(); }
+
+ private:
+  // This is called by FilterMessageFragments().
+  // Inlining allows the compiler turn the per-byte call/return into a for loop,
+  // while, at the same time, keeping the code easy to read and reason about.
+  // It gives a 20-25% speedup (265ms vs 215ms for a 25MB trace).
+  void FilterOneByte(uint8_t octet) PERFETTO_ALWAYS_INLINE;
+
+  // No-inline because this is a slowpath (only when usage tracking is enabled).
+  void IncrementCurrentFieldUsage(uint32_t field_id,
+                                  bool allowed) PERFETTO_NO_INLINE;
+
+  // Gets into an error state which swallows all the input and emits no output.
+  void SetUnrecoverableErrorState();
+
+  // We keep track of the nest of messages in a stack. Each StackState
+  // object corresponds to a level of nesting in the proto message structure.
+  // Every time a new field of type len-delimited that has a corresponding
+  // sub-message in the bytecode is encountered, a new StackState is pushed in
+  // |stack_|. stack_[0] is a sentinel to prevent over-popping without adding
+  // extra branches in the fastpath.
+  // |stack_|. stack_[1] is the state of the root message.
+  struct StackState {
+    uint32_t in_bytes = 0;  // Number of input bytes processed.
+
+    // When |in_bytes| reaches this value, the current state should be popped.
+    // This is set when recursing into nested submessages. This is 0 only for
+    // stack_[0] (we don't know the size of the root message upfront).
+    uint32_t in_bytes_limit = 0;
+
+    // This is set when a len-delimited message is encountered, either a string
+    // or a nested submessage that is NOT allow-listed in the bytecode.
+    // This causes input bytes to be consumed without being parsed from the
+    // input stream. If |passthrough_eaten_bytes| == true, they will be copied
+    // as-is in output (e.g. in the case of an allowed string/bytes field).
+    uint32_t eat_next_bytes = 0;
+
+    // Keeps tracks of the stream_writer output counter (out_.written()) then
+    // the StackState is pushed. This is used to work out, when popping, how
+    // many bytes have been written for the current submessage.
+    uint32_t out_bytes_written_at_start = 0;
+
+    uint32_t field_id = 0;   // The proto field id for the current message.
+    uint32_t msg_index = 0;  // The index of the message filter in the bytecode.
+
+    // This is a pointer to the proto preamble for the current submessage
+    // (it's nullptr for stack_[0] and non-null elsewhere). This will be filled
+    // with the actual size of the message (out_.written() -
+    // |out_bytes_written_at_start|) when finishing (popping) the message.
+    // This must be filled using WriteRedundantVarint(). Note that the
+    // |size_field_len| is variable and depends on the actual length of the
+    // input message. If the output message has roughly the same size of the
+    // input message, the length will not be redundant.
+    // In other words: the length of the field is reserved when the submessage
+    // starts. At that point we know the upper-bound for the output message
+    // (a filtered submessage can be <= the original one, but not >). So we
+    // reserve as many bytes it takes to write the input length in varint.
+    // Then, when the message is finalized and we know the actual output size
+    // we backfill the field.
+    // Consider the example of a submessage where the input size = 130 (>127,
+    // 2 varint bytes) and the output is 120 bytes. The length will be 2 bytes
+    // wide even though could have been encoded with just one byte.
+    uint8_t* size_field = nullptr;
+    uint32_t size_field_len = 0;
+
+    // The pointer to the start of the string to update the string if it is
+    // filtered.
+    uint8_t* filter_string_ptr = nullptr;
+
+    // How |eat_next_bytes| should be handled. It seems that keeping this field
+    // at the end rather than next to |eat_next_bytes| makes the filter a little
+    // (but measurably) faster. (likely something related with struct layout vs
+    // cache sizes).
+    enum FilterAction {
+      kDrop,
+      kPassthrough,
+      kFilterString,
+    };
+    FilterAction action = FilterAction::kDrop;
+  };
+
+  uint32_t out_written() { return static_cast<uint32_t>(out_ - &out_buf_[0]); }
+
+  Config config_;
+
+  std::unique_ptr<uint8_t[]> out_buf_;
+  uint8_t* out_ = nullptr;
+  uint8_t* out_end_ = nullptr;
+
+  MessageTokenizer tokenizer_;
+  std::vector<StackState> stack_;
+
+  bool error_ = false;
+  bool track_field_usage_ = false;
+  std::unordered_map<std::string, int32_t> field_usage_;
+};
+
+}  // namespace protozero
+
+#endif  // SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "src/protozero/filtering/message_filter.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"
+
+namespace protozero {
+
+namespace {
+
+// Inline helpers to append proto fields in output. They are the equivalent of
+// the protozero::Message::AppendXXX() fields but don't require building and
+// maintaining a full protozero::Message object or dealing with scattered
+// output slices.
+// All these functions assume there is enough space in the output buffer, which
+// should be always the case assuming that we don't end up generating more
+// output than input.
+
+inline void AppendVarInt(uint32_t field_id, uint64_t value, uint8_t** out) {
+  *out = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), *out);
+  *out = proto_utils::WriteVarInt(value, *out);
+}
+
+// For fixed32 / fixed64.
+template <typename INT_T /* uint32_t | uint64_t*/>
+inline void AppendFixed(uint32_t field_id, INT_T value, uint8_t** out) {
+  *out = proto_utils::WriteVarInt(proto_utils::MakeTagFixed<INT_T>(field_id),
+                                  *out);
+  memcpy(*out, &value, sizeof(value));
+  *out += sizeof(value);
+}
+
+// For length-delimited (string, bytes) fields. Note: this function appends only
+// the proto preamble and the varint field that states the length of the payload
+// not the payload itself.
+// In the case of submessages, the caller needs to re-write the length at the
+// end in the in the returned memory area.
+// The problem here is that, because of filtering, the length of a submessage
+// might be < original length (the original length is still an upper-bound).
+// Returns a pair with: (1) the pointer where the final length should be written
+// into, (2) the length of the size field.
+// The caller must write a redundant varint to match the original size (i.e.
+// needs to use WriteRedundantVarInt()).
+inline std::pair<uint8_t*, uint32_t> AppendLenDelim(uint32_t field_id,
+                                                    uint32_t len,
+                                                    uint8_t** out) {
+  *out = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
+                                  *out);
+  uint8_t* size_field_start = *out;
+  *out = proto_utils::WriteVarInt(len, *out);
+  const size_t size_field_len = static_cast<size_t>(*out - size_field_start);
+  return std::make_pair(size_field_start, size_field_len);
+}
+}  // namespace
+
+MessageFilter::MessageFilter(Config config) : config_(std::move(config)) {
+  // Push a state on the stack for the implicit root message.
+  stack_.emplace_back();
+}
+
+MessageFilter::MessageFilter() : MessageFilter(Config()) {}
+
+MessageFilter::~MessageFilter() = default;
+
+bool MessageFilter::Config::LoadFilterBytecode(const void* filter_data,
+                                               size_t len) {
+  return filter_.Load(filter_data, len);
+}
+
+bool MessageFilter::Config::SetFilterRoot(
+    std::initializer_list<uint32_t> field_ids) {
+  uint32_t root_msg_idx = 0;
+  for (uint32_t field_id : field_ids) {
+    auto res = filter_.Query(root_msg_idx, field_id);
+    if (!res.allowed || !res.nested_msg_field())
+      return false;
+    root_msg_idx = res.nested_msg_index;
+  }
+  root_msg_index_ = root_msg_idx;
+  return true;
+}
+
+MessageFilter::FilteredMessage MessageFilter::FilterMessageFragments(
+    const InputSlice* slices,
+    size_t num_slices) {
+  // First compute the upper bound for the output. The filtered message cannot
+  // be > the original message.
+  uint32_t total_len = 0;
+  for (size_t i = 0; i < num_slices; ++i)
+    total_len += slices[i].len;
+  out_buf_.reset(new uint8_t[total_len]);
+  out_ = out_buf_.get();
+  out_end_ = out_ + total_len;
+
+  // Reset the parser state.
+  tokenizer_ = MessageTokenizer();
+  error_ = false;
+  stack_.clear();
+  stack_.resize(2);
+  // stack_[0] is a sentinel and should never be hit in nominal cases. If we
+  // end up there we will just keep consuming the input stream and detecting
+  // at the end, without hurting the fastpath.
+  stack_[0].in_bytes_limit = UINT32_MAX;
+  stack_[0].eat_next_bytes = UINT32_MAX;
+  // stack_[1] is the actual root message.
+  stack_[1].in_bytes_limit = total_len;
+  stack_[1].msg_index = config_.root_msg_index();
+
+  // Process the input data and write the output.
+  for (size_t slice_idx = 0; slice_idx < num_slices; ++slice_idx) {
+    const InputSlice& slice = slices[slice_idx];
+    const uint8_t* data = static_cast<const uint8_t*>(slice.data);
+    for (size_t i = 0; i < slice.len; ++i)
+      FilterOneByte(data[i]);
+  }
+
+  // Construct the output object.
+  PERFETTO_CHECK(out_ >= out_buf_.get() && out_ <= out_end_);
+  auto used_size = static_cast<size_t>(out_ - out_buf_.get());
+  FilteredMessage res{std::move(out_buf_), used_size};
+  res.error = error_;
+  if (stack_.size() != 1 || !tokenizer_.idle() ||
+      stack_[0].in_bytes != total_len) {
+    res.error = true;
+  }
+  return res;
+}
+
+void MessageFilter::FilterOneByte(uint8_t octet) {
+  PERFETTO_DCHECK(!stack_.empty());
+
+  auto* state = &stack_.back();
+  StackState next_state{};
+  bool push_next_state = false;
+
+  if (state->eat_next_bytes > 0) {
+    // This is the case where the previous tokenizer_.Push() call returned a
+    // length delimited message which is NOT a submessage (a string or a bytes
+    // field). We just want to consume it, and pass it through/filter strings
+    // if the field was allowed.
+    --state->eat_next_bytes;
+    if (state->action == StackState::kPassthrough) {
+      *(out_++) = octet;
+    } else if (state->action == StackState::kFilterString) {
+      *(out_++) = octet;
+      if (state->eat_next_bytes == 0) {
+        config_.string_filter().MaybeFilter(
+            reinterpret_cast<char*>(state->filter_string_ptr),
+            static_cast<size_t>(out_ - state->filter_string_ptr));
+      }
+    }
+  } else {
+    MessageTokenizer::Token token = tokenizer_.Push(octet);
+    // |token| will not be valid() in most cases and this is WAI. When pushing
+    // a varint field, only the last byte yields a token, all the other bytes
+    // return an invalid token, they just update the internal tokenizer state.
+    if (token.valid()) {
+      auto filter = config_.filter().Query(state->msg_index, token.field_id);
+      switch (token.type) {
+        case proto_utils::ProtoWireType::kVarInt:
+          if (filter.allowed && filter.simple_field())
+            AppendVarInt(token.field_id, token.value, &out_);
+          break;
+        case proto_utils::ProtoWireType::kFixed32:
+          if (filter.allowed && filter.simple_field())
+            AppendFixed(token.field_id, static_cast<uint32_t>(token.value),
+                        &out_);
+          break;
+        case proto_utils::ProtoWireType::kFixed64:
+          if (filter.allowed && filter.simple_field())
+            AppendFixed(token.field_id, static_cast<uint64_t>(token.value),
+                        &out_);
+          break;
+        case proto_utils::ProtoWireType::kLengthDelimited:
+          // Here we have two cases:
+          // A. A simple string/bytes field: we just want to consume the next
+          //    bytes (the string payload), optionally passing them through in
+          //    output if the field is allowed.
+          // B. This is a nested submessage. In this case we want to recurse and
+          //    push a new state on the stack.
+          // Note that we can't tell the difference between a
+          // "non-allowed string" and a "non-allowed submessage". But it doesn't
+          // matter because in both cases we just want to skip the next N bytes.
+          const auto submessage_len = static_cast<uint32_t>(token.value);
+          auto in_bytes_left = state->in_bytes_limit - state->in_bytes - 1;
+          if (PERFETTO_UNLIKELY(submessage_len > in_bytes_left)) {
+            // This is a malicious / malformed string/bytes/submessage that
+            // claims to be larger than the outer message that contains it.
+            return SetUnrecoverableErrorState();
+          }
+
+          if (filter.allowed && filter.nested_msg_field() &&
+              submessage_len > 0) {
+            // submessage_len == 0 is the edge case of a message with a 0-len
+            // (but present) submessage. In this case, if allowed, we don't want
+            // to push any further state (doing so would desync the FSM) but we
+            // still want to emit it.
+            // At this point |submessage_len| is only an upper bound. The
+            // final message written in output can be <= the one in input,
+            // only some of its fields might be allowed (also remember that
+            // this class implicitly removes redundancy varint encoding of
+            // len-delimited field lengths). The final length varint (the
+            // return value of AppendLenDelim()) will be filled when popping
+            // from |stack_|.
+            auto size_field =
+                AppendLenDelim(token.field_id, submessage_len, &out_);
+            push_next_state = true;
+            next_state.field_id = token.field_id;
+            next_state.msg_index = filter.nested_msg_index;
+            next_state.in_bytes_limit = submessage_len;
+            next_state.size_field = size_field.first;
+            next_state.size_field_len = size_field.second;
+            next_state.out_bytes_written_at_start = out_written();
+          } else {
+            // A string or bytes field, or a 0 length submessage.
+            state->eat_next_bytes = submessage_len;
+            if (filter.allowed && filter.filter_string_field()) {
+              state->action = StackState::kFilterString;
+              AppendLenDelim(token.field_id, submessage_len, &out_);
+              state->filter_string_ptr = out_;
+            } else if (filter.allowed) {
+              state->action = StackState::kPassthrough;
+              AppendLenDelim(token.field_id, submessage_len, &out_);
+            } else {
+              state->action = StackState::kDrop;
+            }
+          }
+          break;
+      }  // switch(type)
+
+      if (PERFETTO_UNLIKELY(track_field_usage_)) {
+        IncrementCurrentFieldUsage(token.field_id, filter.allowed);
+      }
+    }  // if (token.valid)
+  }    // if (eat_next_bytes == 0)
+
+  ++state->in_bytes;
+  while (state->in_bytes >= state->in_bytes_limit) {
+    PERFETTO_DCHECK(state->in_bytes == state->in_bytes_limit);
+    push_next_state = false;
+
+    // We can't possibly write more than we read.
+    const uint32_t msg_bytes_written = static_cast<uint32_t>(
+        out_written() - state->out_bytes_written_at_start);
+    PERFETTO_DCHECK(msg_bytes_written <= state->in_bytes_limit);
+
+    // Backfill the length field of the
+    proto_utils::WriteRedundantVarInt(msg_bytes_written, state->size_field,
+                                      state->size_field_len);
+
+    const uint32_t in_bytes_processes_for_last_msg = state->in_bytes;
+    stack_.pop_back();
+    PERFETTO_CHECK(!stack_.empty());
+    state = &stack_.back();
+    state->in_bytes += in_bytes_processes_for_last_msg;
+    if (PERFETTO_UNLIKELY(!tokenizer_.idle())) {
+      // If we hit this case, it means that we got to the end of a submessage
+      // while decoding a field. We can't recover from this and we don't want to
+      // propagate a broken sub-message.
+      return SetUnrecoverableErrorState();
+    }
+  }
+
+  if (push_next_state) {
+    PERFETTO_DCHECK(tokenizer_.idle());
+    stack_.emplace_back(std::move(next_state));
+    state = &stack_.back();
+  }
+}
+
+void MessageFilter::SetUnrecoverableErrorState() {
+  error_ = true;
+  stack_.clear();
+  stack_.resize(1);
+  auto& state = stack_[0];
+  state.eat_next_bytes = UINT32_MAX;
+  state.in_bytes_limit = UINT32_MAX;
+  state.action = StackState::kDrop;
+  out_ = out_buf_.get();  // Reset the write pointer.
+}
+
+void MessageFilter::IncrementCurrentFieldUsage(uint32_t field_id,
+                                               bool allowed) {
+  // Slowpath. Used mainly in offline tools and tests to workout used fields in
+  // a proto.
+  PERFETTO_DCHECK(track_field_usage_);
+
+  // Field path contains a concatenation of varints, one for each nesting level.
+  // e.g. y in message Root { Sub x = 2; }; message Sub { SubSub y = 7; }
+  // is encoded as [varint(2) + varint(7)].
+  // We use varint to take the most out of SSO (small string opt). In most cases
+  // the path will fit in the on-stack 22 bytes, requiring no heap.
+  std::string field_path;
+
+  auto append_field_id = [&field_path](uint32_t id) {
+    uint8_t buf[10];
+    uint8_t* end = proto_utils::WriteVarInt(id, buf);
+    field_path.append(reinterpret_cast<char*>(buf),
+                      static_cast<size_t>(end - buf));
+  };
+
+  // Append all the ancestors IDs from the state stack.
+  // The first entry of the stack has always ID 0 and we skip it (we don't know
+  // the ID of the root message itself).
+  PERFETTO_DCHECK(stack_.size() >= 2 && stack_[1].field_id == 0);
+  for (size_t i = 2; i < stack_.size(); ++i)
+    append_field_id(stack_[i].field_id);
+  // Append the id of the field in the current message.
+  append_field_id(field_id);
+  field_usage_[field_path] += allowed ? 1 : -1;
+}
+
+}  // namespace protozero
+// gen_amalgamated begin source: src/tracing/core/metatrace_writer.cc
+// gen_amalgamated begin header: src/tracing/core/metatrace_writer.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef SRC_TRACING_CORE_METATRACE_WRITER_H_
+#define SRC_TRACING_CORE_METATRACE_WRITER_H_
+
+#include <functional>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+class TraceWriter;
+
+// Complements the base::metatrace infrastructure.
+// It hooks a callback to metatrace::Enable() and writes metatrace events into
+// a TraceWriter whenever the metatrace ring buffer is half full.
+// It is safe to create and attempt to start multiple instances of this class,
+// however only the first one will succeed because the metatrace framework
+// doesn't support multiple instances.
+// This class is defined here (instead of directly in src/probes/) so it can
+// be reused by other components (e.g. heapprofd).
+class MetatraceWriter {
+ public:
+  static constexpr char kDataSourceName[] = "perfetto.metatrace";
+
+  MetatraceWriter();
+  ~MetatraceWriter();
+
+  MetatraceWriter(const MetatraceWriter&) = delete;
+  MetatraceWriter& operator=(const MetatraceWriter&) = delete;
+  MetatraceWriter(MetatraceWriter&&) = delete;
+  MetatraceWriter& operator=(MetatraceWriter&&) = delete;
+
+  void Enable(base::TaskRunner*, std::unique_ptr<TraceWriter>, uint32_t tags);
+  void Disable();
+  void WriteAllAndFlushTraceWriter(std::function<void()> callback);
+
+ private:
+  void WriteAllAvailableEvents();
+
+  bool started_ = false;
+  base::TaskRunner* task_runner_ = nullptr;
+  std::unique_ptr<TraceWriter> trace_writer_;
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+  base::WeakPtrFactory<MetatraceWriter> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_METATRACE_WRITER_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/metatrace_writer.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+
+MetatraceWriter::MetatraceWriter() : weak_ptr_factory_(this) {}
+
+MetatraceWriter::~MetatraceWriter() {
+  Disable();
+}
+
+void MetatraceWriter::Enable(base::TaskRunner* task_runner,
+                             std::unique_ptr<TraceWriter> trace_writer,
+                             uint32_t tags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (started_) {
+    PERFETTO_DFATAL_OR_ELOG("Metatrace already started from this instance");
+    return;
+  }
+  task_runner_ = task_runner;
+  trace_writer_ = std::move(trace_writer);
+  auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  bool enabled = metatrace::Enable(
+      [weak_ptr] {
+        if (weak_ptr)
+          weak_ptr->WriteAllAvailableEvents();
+      },
+      task_runner, tags);
+  if (!enabled)
+    return;
+  started_ = true;
+}
+
+void MetatraceWriter::Disable() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!started_)
+    return;
+  metatrace::Disable();
+  started_ = false;
+  trace_writer_.reset();
+}
+
+void MetatraceWriter::WriteAllAvailableEvents() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!started_)
+    return;
+  for (auto it = metatrace::RingBuffer::GetReadIterator(); it; ++it) {
+    auto type_and_id = it->type_and_id.load(std::memory_order_acquire);
+    if (type_and_id == 0)
+      break;  // Stop at the first incomplete event.
+
+    auto packet = trace_writer_->NewTracePacket();
+    packet->set_timestamp(it->timestamp_ns());
+    auto* evt = packet->set_perfetto_metatrace();
+    uint16_t type = type_and_id & metatrace::Record::kTypeMask;
+    uint16_t id = type_and_id & ~metatrace::Record::kTypeMask;
+    if (type == metatrace::Record::kTypeCounter) {
+      evt->set_counter_id(id);
+      evt->set_counter_value(it->counter_value);
+    } else {
+      evt->set_event_id(id);
+      evt->set_event_duration_ns(it->duration_ns);
+    }
+
+    evt->set_thread_id(static_cast<uint32_t>(it->thread_id));
+
+    if (metatrace::RingBuffer::has_overruns())
+      evt->set_has_overruns(true);
+  }
+  // The |it| destructor will automatically update the read index position in
+  // the meta-trace ring buffer.
+}
+
+void MetatraceWriter::WriteAllAndFlushTraceWriter(
+    std::function<void()> callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!started_)
+    return;
+  WriteAllAvailableEvents();
+  trace_writer_->Flush(std::move(callback));
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/packet_stream_validator.cc
+// gen_amalgamated begin header: src/tracing/core/packet_stream_validator.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
+#define SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
+
+namespace perfetto {
+
+// Checks that the stream of trace packets sent by the producer is well formed.
+// This includes:
+//
+// - Checking that the packets are not truncated.
+// - There are no dangling bytes left over in the packets.
+// - Any trusted fields (e.g., uid) are not set.
+//
+// Note that we only validate top-level fields in the trace proto; sub-messages
+// are simply skipped.
+class PacketStreamValidator {
+ public:
+  PacketStreamValidator() = delete;
+
+  static bool Validate(const Slices&);
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/packet_stream_validator.h"
+
+#include <stddef.h>
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+
+namespace {
+
+using protozero::proto_utils::ProtoWireType;
+
+const uint32_t kReservedFieldIds[] = {
+    protos::pbzero::TracePacket::kTrustedUidFieldNumber,
+    protos::pbzero::TracePacket::kTrustedPacketSequenceIdFieldNumber,
+    protos::pbzero::TracePacket::kTraceConfigFieldNumber,
+    protos::pbzero::TracePacket::kTraceStatsFieldNumber,
+    protos::pbzero::TracePacket::kCompressedPacketsFieldNumber,
+    protos::pbzero::TracePacket::kSynchronizationMarkerFieldNumber,
+    protos::pbzero::TracePacket::kTrustedPidFieldNumber,
+    protos::pbzero::TracePacket::kMachineIdFieldNumber,
+};
+
+// This translation unit is quite subtle and perf-sensitive. Remember to check
+// BM_PacketStreamValidator in perfetto_benchmarks when making changes.
+
+// Checks that a packet, spread over several slices, is well-formed and doesn't
+// contain reserved top-level fields.
+// The checking logic is based on a state-machine that skips the fields' payload
+// and operates as follows:
+//              +-------------------------------+ <-------------------------+
+// +----------> | Read field preamble (varint)  | <----------------------+  |
+// |            +-------------------------------+                        |  |
+// |              |              |            |                          |  |
+// |       <Varint>        <Fixed 32/64>     <Length-delimited field>    |  |
+// |          V                  |                      V                |  |
+// |  +------------------+       |               +--------------+        |  |
+// |  | Read field value |       |               | Read length  |        |  |
+// |  | (another varint) |       |               |   (varint)   |        |  |
+// |  +------------------+       |               +--------------+        |  |
+// |           |                 V                      V                |  |
+// +-----------+        +----------------+     +-----------------+       |  |
+//                      | Skip 4/8 Bytes |     | Skip $len Bytes |-------+  |
+//                      +----------------+     +-----------------+          |
+//                               |                                          |
+//                               +------------------------------------------+
+class ProtoFieldParserFSM {
+ public:
+  // This method effectively continuously parses varints (either for the field
+  // preamble or the payload or the submessage length) and tells the caller
+  // (the Validate() method) how many bytes to skip until the next field.
+  size_t Push(uint8_t octet) {
+    varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
+    if (octet & 0x80) {
+      varint_shift_ += 7;
+      if (varint_shift_ >= 64) {
+        // Do not invoke UB on next call.
+        varint_shift_ = 0;
+        state_ = kInvalidVarInt;
+      }
+      return 0;
+    }
+    uint64_t varint = varint_;
+    varint_ = 0;
+    varint_shift_ = 0;
+
+    switch (state_) {
+      case kFieldPreamble: {
+        uint64_t field_type = varint & 7;  // 7 = 0..0111
+        auto field_id = static_cast<uint32_t>(varint >> 3);
+        // Check if the field id is reserved, go into an error state if it is.
+        for (size_t i = 0; i < base::ArraySize(kReservedFieldIds); ++i) {
+          if (field_id == kReservedFieldIds[i]) {
+            state_ = kWroteReservedField;
+            return 0;
+          }
+        }
+        // The field type is legit, now check it's well formed and within
+        // boundaries.
+        if (field_type == static_cast<uint64_t>(ProtoWireType::kVarInt)) {
+          state_ = kVarIntValue;
+        } else if (field_type ==
+                   static_cast<uint64_t>(ProtoWireType::kFixed32)) {
+          return 4;
+        } else if (field_type ==
+                   static_cast<uint64_t>(ProtoWireType::kFixed64)) {
+          return 8;
+        } else if (field_type ==
+                   static_cast<uint64_t>(ProtoWireType::kLengthDelimited)) {
+          state_ = kLenDelimitedLen;
+        } else {
+          state_ = kUnknownFieldType;
+        }
+        return 0;
+      }
+
+      case kVarIntValue: {
+        // Consume the int field payload and go back to the next field.
+        state_ = kFieldPreamble;
+        return 0;
+      }
+
+      case kLenDelimitedLen: {
+        if (varint > protozero::proto_utils::kMaxMessageLength) {
+          state_ = kMessageTooBig;
+          return 0;
+        }
+        state_ = kFieldPreamble;
+        return static_cast<size_t>(varint);
+      }
+
+      case kWroteReservedField:
+      case kUnknownFieldType:
+      case kMessageTooBig:
+      case kInvalidVarInt:
+        // Persistent error states.
+        return 0;
+
+    }          // switch(state_)
+    return 0;  // To keep GCC happy.
+  }
+
+  // Queried at the end of the all payload. A message is well-formed only
+  // if the FSM is back to the state where it should parse the next field and
+  // hasn't started parsing any preamble.
+  bool valid() const { return state_ == kFieldPreamble && varint_shift_ == 0; }
+  int state() const { return static_cast<int>(state_); }
+
+ private:
+  enum State {
+    kFieldPreamble = 0,  // Parsing the varint for the field preamble.
+    kVarIntValue,        // Parsing the varint value for the field payload.
+    kLenDelimitedLen,    // Parsing the length of the length-delimited field.
+
+    // Error states:
+    kWroteReservedField,  // Tried to set a reserved field id.
+    kUnknownFieldType,    // Encountered an invalid field type.
+    kMessageTooBig,       // Size of the length delimited message was too big.
+    kInvalidVarInt,       // VarInt larger than 64 bits.
+  };
+
+  State state_ = kFieldPreamble;
+  uint64_t varint_ = 0;
+  uint32_t varint_shift_ = 0;
+};
+
+}  // namespace
+
+// static
+bool PacketStreamValidator::Validate(const Slices& slices) {
+  ProtoFieldParserFSM parser;
+  size_t skip_bytes = 0;
+  for (const Slice& slice : slices) {
+    for (size_t i = 0; i < slice.size;) {
+      const size_t skip_bytes_cur_slice = std::min(skip_bytes, slice.size - i);
+      if (skip_bytes_cur_slice > 0) {
+        i += skip_bytes_cur_slice;
+        skip_bytes -= skip_bytes_cur_slice;
+      } else {
+        uint8_t octet = *(reinterpret_cast<const uint8_t*>(slice.start) + i);
+        skip_bytes = parser.Push(octet);
+        i++;
+      }
+    }
+  }
+  if (skip_bytes == 0 && parser.valid())
+    return true;
+
+  PERFETTO_DLOG("Packet validation error (state %d, skip = %zu)",
+                parser.state(), skip_bytes);
+  return false;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/trace_buffer.cc
+// gen_amalgamated begin header: src/tracing/core/trace_buffer.h
+// gen_amalgamated begin header: include/perfetto/ext/base/flat_hash_map.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
+#define INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+#include <algorithm>
+#include <functional>
+#include <limits>
+
+namespace perfetto {
+namespace base {
+
+// An open-addressing hashmap implementation.
+// Pointers are not stable, neither for keys nor values.
+// Has similar performances of a RobinHood hash (without the complications)
+// and 2x an unordered map.
+// Doc: http://go/perfetto-hashtables .
+//
+// When used to implement a string pool in TraceProcessor, the performance
+// characteristics obtained by replaying the set of strings seeen in a 4GB trace
+// (226M strings, 1M unique) are the following (see flat_hash_map_benchmark.cc):
+// This(Linear+AppendOnly)    879,383,676 ns    258.013M insertions/s
+// This(LinearProbe):         909,206,047 ns    249.546M insertions/s
+// This(QuadraticProbe):    1,083,844,388 ns    209.363M insertions/s
+// std::unordered_map:      6,203,351,870 ns    36.5811M insertions/s
+// tsl::robin_map:            931,403,397 ns    243.622M insertions/s
+// absl::flat_hash_map:       998,013,459 ns    227.379M insertions/s
+// FollyF14FastMap:         1,181,480,602 ns    192.074M insertions/s
+
+// The structs below define the probing algorithm used to probe slots upon a
+// collision. They are guaranteed to visit all slots as our table size is always
+// a power of two (see https://en.wikipedia.org/wiki/Quadratic_probing).
+
+// Linear probing can be faster if the hashing is well distributed and the load
+// is not high. For TraceProcessor's StringPool this is the fastest. It can
+// degenerate badly if the hashing doesn't spread (e.g., if using directly pids
+// as keys, with a no-op hashing function).
+struct LinearProbe {
+  static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
+    return (key_hash + step) & (capacity - 1);  // Linear probe
+  }
+};
+
+// Generates the sequence: 0, 3, 10, 21, 36, 55, ...
+// Can be a bit (~5%) slower than LinearProbe because it's less cache hot, but
+// avoids degenerating badly if the hash function is bad and causes clusters.
+// A good default choice unless benchmarks prove otherwise.
+struct QuadraticProbe {
+  static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
+    return (key_hash + 2 * step * step + step) & (capacity - 1);
+  }
+};
+
+// Tends to perform in the middle between linear and quadratic.
+// It's a bit more cache-effective than the QuadraticProbe but can create more
+// clustering if the hash function doesn't spread well.
+// Generates the sequence: 0, 1, 3, 6, 10, 15, 21, ...
+struct QuadraticHalfProbe {
+  static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
+    return (key_hash + (step * step + step) / 2) & (capacity - 1);
+  }
+};
+
+template <typename Key,
+          typename Value,
+          typename Hasher = base::Hash<Key>,
+          typename Probe = QuadraticProbe,
+          bool AppendOnly = false>
+class FlatHashMap {
+ public:
+  class Iterator {
+   public:
+    explicit Iterator(const FlatHashMap* map) : map_(map) { FindNextNonFree(); }
+    ~Iterator() = default;
+    Iterator(const Iterator&) = default;
+    Iterator& operator=(const Iterator&) = default;
+    Iterator(Iterator&&) noexcept = default;
+    Iterator& operator=(Iterator&&) noexcept = default;
+
+    Key& key() { return map_->keys_[idx_]; }
+    Value& value() { return map_->values_[idx_]; }
+    const Key& key() const { return map_->keys_[idx_]; }
+    const Value& value() const { return map_->values_[idx_]; }
+
+    explicit operator bool() const { return idx_ != kEnd; }
+    Iterator& operator++() {
+      PERFETTO_DCHECK(idx_ < map_->capacity_);
+      ++idx_;
+      FindNextNonFree();
+      return *this;
+    }
+
+   private:
+    static constexpr size_t kEnd = std::numeric_limits<size_t>::max();
+
+    void FindNextNonFree() {
+      const auto& tags = map_->tags_;
+      for (; idx_ < map_->capacity_; idx_++) {
+        if (tags[idx_] != kFreeSlot && (AppendOnly || tags[idx_] != kTombstone))
+          return;
+      }
+      idx_ = kEnd;
+    }
+
+    const FlatHashMap* map_ = nullptr;
+    size_t idx_ = 0;
+  };  // Iterator
+
+  static constexpr int kDefaultLoadLimitPct = 75;
+  explicit FlatHashMap(size_t initial_capacity = 0,
+                       int load_limit_pct = kDefaultLoadLimitPct)
+      : load_limit_percent_(load_limit_pct) {
+    if (initial_capacity > 0)
+      Reset(initial_capacity);
+  }
+
+  // We are calling Clear() so that the destructors for the inserted entries are
+  // called (unless they are trivial, in which case it will be a no-op).
+  ~FlatHashMap() { Clear(); }
+
+  FlatHashMap(FlatHashMap&& other) noexcept {
+    tags_ = std::move(other.tags_);
+    keys_ = std::move(other.keys_);
+    values_ = std::move(other.values_);
+    capacity_ = other.capacity_;
+    size_ = other.size_;
+    max_probe_length_ = other.max_probe_length_;
+    load_limit_ = other.load_limit_;
+    load_limit_percent_ = other.load_limit_percent_;
+
+    new (&other) FlatHashMap();
+  }
+
+  FlatHashMap& operator=(FlatHashMap&& other) noexcept {
+    this->~FlatHashMap();
+    new (this) FlatHashMap(std::move(other));
+    return *this;
+  }
+
+  FlatHashMap(const FlatHashMap&) = delete;
+  FlatHashMap& operator=(const FlatHashMap&) = delete;
+
+  std::pair<Value*, bool> Insert(Key key, Value value) {
+    const size_t key_hash = Hasher{}(key);
+    const uint8_t tag = HashToTag(key_hash);
+    static constexpr size_t kSlotNotFound = std::numeric_limits<size_t>::max();
+
+    // This for loop does in reality at most two attempts:
+    // The first iteration either:
+    //  - Early-returns, because the key exists already,
+    //  - Finds an insertion slot and proceeds because the load is < limit.
+    // The second iteration is only hit in the unlikely case of this insertion
+    // bringing the table beyond the target |load_limit_| (or the edge case
+    // of the HT being full, if |load_limit_pct_| = 100).
+    // We cannot simply pre-grow the table before insertion, because we must
+    // guarantee that calling Insert() with a key that already exists doesn't
+    // invalidate iterators.
+    size_t insertion_slot;
+    size_t probe_len;
+    for (;;) {
+      PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
+      insertion_slot = kSlotNotFound;
+      // Start the iteration at the desired slot (key_hash % capacity_)
+      // searching either for a free slot or a tombstone. In the worst case we
+      // might end up scanning the whole array of slots. The Probe functions are
+      // guaranteed to visit all the slots within |capacity_| steps. If we find
+      // a free slot, we can stop the search immediately (a free slot acts as an
+      // "end of chain for entries having the same hash". If we find a
+      // tombstones (a deleted slot) we remember its position, but have to keep
+      // searching until a free slot to make sure we don't insert a duplicate
+      // key.
+      for (probe_len = 0; probe_len < capacity_;) {
+        const size_t idx = Probe::Calc(key_hash, probe_len, capacity_);
+        PERFETTO_DCHECK(idx < capacity_);
+        const uint8_t tag_idx = tags_[idx];
+        ++probe_len;
+        if (tag_idx == kFreeSlot) {
+          // Rationale for "insertion_slot == kSlotNotFound": if we encountered
+          // a tombstone while iterating we should reuse that rather than
+          // taking another slot.
+          if (AppendOnly || insertion_slot == kSlotNotFound)
+            insertion_slot = idx;
+          break;
+        }
+        // We should never encounter tombstones in AppendOnly mode.
+        PERFETTO_DCHECK(!(tag_idx == kTombstone && AppendOnly));
+        if (!AppendOnly && tag_idx == kTombstone) {
+          insertion_slot = idx;
+          continue;
+        }
+        if (tag_idx == tag && keys_[idx] == key) {
+          // The key is already in the map.
+          return std::make_pair(&values_[idx], false);
+        }
+      }  // for (idx)
+
+      // If we got to this point the key does not exist (otherwise we would have
+      // hit the return above) and we are going to insert a new entry.
+      // Before doing so, ensure we stay under the target load limit.
+      if (PERFETTO_UNLIKELY(size_ >= load_limit_)) {
+        MaybeGrowAndRehash(/*grow=*/true);
+        continue;
+      }
+      PERFETTO_DCHECK(insertion_slot != kSlotNotFound);
+      break;
+    }  // for (attempt)
+
+    PERFETTO_CHECK(insertion_slot < capacity_);
+
+    // We found a free slot (or a tombstone). Proceed with the insertion.
+    Value* value_idx = &values_[insertion_slot];
+    new (&keys_[insertion_slot]) Key(std::move(key));
+    new (value_idx) Value(std::move(value));
+    tags_[insertion_slot] = tag;
+    PERFETTO_DCHECK(probe_len > 0 && probe_len <= capacity_);
+    max_probe_length_ = std::max(max_probe_length_, probe_len);
+    size_++;
+
+    return std::make_pair(value_idx, true);
+  }
+
+  Value* Find(const Key& key) const {
+    const size_t idx = FindInternal(key);
+    if (idx == kNotFound)
+      return nullptr;
+    return &values_[idx];
+  }
+
+  bool Erase(const Key& key) {
+    if (AppendOnly)
+      PERFETTO_FATAL("Erase() not supported because AppendOnly=true");
+    size_t idx = FindInternal(key);
+    if (idx == kNotFound)
+      return false;
+    EraseInternal(idx);
+    return true;
+  }
+
+  void Clear() {
+    // Avoid trivial heap operations on zero-capacity std::move()-d objects.
+    if (PERFETTO_UNLIKELY(capacity_ == 0))
+      return;
+
+    for (size_t i = 0; i < capacity_; ++i) {
+      const uint8_t tag = tags_[i];
+      if (tag != kFreeSlot && tag != kTombstone)
+        EraseInternal(i);
+    }
+    // Clear all tombstones. We really need to do this for AppendOnly.
+    MaybeGrowAndRehash(/*grow=*/false);
+  }
+
+  Value& operator[](Key key) {
+    auto it_and_inserted = Insert(std::move(key), Value{});
+    return *it_and_inserted.first;
+  }
+
+  Iterator GetIterator() { return Iterator(this); }
+  const Iterator GetIterator() const { return Iterator(this); }
+
+  size_t size() const { return size_; }
+  size_t capacity() const { return capacity_; }
+
+  // "protected" here is only for the flat_hash_map_benchmark.cc. Everything
+  // below is by all means private.
+ protected:
+  enum ReservedTags : uint8_t { kFreeSlot = 0, kTombstone = 1 };
+  static constexpr size_t kNotFound = std::numeric_limits<size_t>::max();
+
+  size_t FindInternal(const Key& key) const {
+    const size_t key_hash = Hasher{}(key);
+    const uint8_t tag = HashToTag(key_hash);
+    PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
+    PERFETTO_DCHECK(max_probe_length_ <= capacity_);
+    for (size_t i = 0; i < max_probe_length_; ++i) {
+      const size_t idx = Probe::Calc(key_hash, i, capacity_);
+      const uint8_t tag_idx = tags_[idx];
+
+      if (tag_idx == kFreeSlot)
+        return kNotFound;
+      // HashToTag() never returns kTombstone, so the tag-check below cannot
+      // possibly match. Also we just want to skip tombstones.
+      if (tag_idx == tag && keys_[idx] == key) {
+        PERFETTO_DCHECK(tag_idx > kTombstone);
+        return idx;
+      }
+    }  // for (idx)
+    return kNotFound;
+  }
+
+  void EraseInternal(size_t idx) {
+    PERFETTO_DCHECK(tags_[idx] > kTombstone);
+    PERFETTO_DCHECK(size_ > 0);
+    tags_[idx] = kTombstone;
+    keys_[idx].~Key();
+    values_[idx].~Value();
+    size_--;
+  }
+
+  PERFETTO_NO_INLINE void MaybeGrowAndRehash(bool grow) {
+    PERFETTO_DCHECK(size_ <= capacity_);
+    const size_t old_capacity = capacity_;
+
+    // Grow quickly up to 1MB, then chill.
+    const size_t old_size_bytes = old_capacity * (sizeof(Key) + sizeof(Value));
+    const size_t grow_factor = old_size_bytes < (1024u * 1024u) ? 8 : 2;
+    const size_t new_capacity =
+        grow ? std::max(old_capacity * grow_factor, size_t(1024))
+             : old_capacity;
+
+    auto old_tags(std::move(tags_));
+    auto old_keys(std::move(keys_));
+    auto old_values(std::move(values_));
+    size_t old_size = size_;
+
+    // This must be a CHECK (i.e. not just a DCHECK) to prevent UAF attacks on
+    // 32-bit archs that try to double the size of the table until wrapping.
+    PERFETTO_CHECK(new_capacity >= old_capacity);
+    Reset(new_capacity);
+
+    size_t new_size = 0;  // Recompute the size.
+    for (size_t i = 0; i < old_capacity; ++i) {
+      const uint8_t old_tag = old_tags[i];
+      if (old_tag != kFreeSlot && old_tag != kTombstone) {
+        Insert(std::move(old_keys[i]), std::move(old_values[i]));
+        old_keys[i].~Key();  // Destroy the old objects.
+        old_values[i].~Value();
+        new_size++;
+      }
+    }
+    PERFETTO_DCHECK(new_size == old_size);
+    size_ = new_size;
+  }
+
+  // Doesn't call destructors. Use Clear() for that.
+  PERFETTO_NO_INLINE void Reset(size_t n) {
+    PERFETTO_DCHECK((n & (n - 1)) == 0);  // Must be a pow2.
+
+    capacity_ = n;
+    max_probe_length_ = 0;
+    size_ = 0;
+    load_limit_ = n * static_cast<size_t>(load_limit_percent_) / 100;
+    load_limit_ = std::min(load_limit_, n);
+
+    tags_.reset(new uint8_t[n]);
+    memset(&tags_[0], 0, n);                  // Clear all tags.
+    keys_ = AlignedAllocTyped<Key[]>(n);      // Deliberately not 0-initialized.
+    values_ = AlignedAllocTyped<Value[]>(n);  // Deliberately not 0-initialized.
+  }
+
+  static inline uint8_t HashToTag(size_t full_hash) {
+    uint8_t tag = full_hash >> (sizeof(full_hash) * 8 - 8);
+    // Ensure the hash is always >= 2. We use 0, 1 for kFreeSlot and kTombstone.
+    tag += (tag <= kTombstone) << 1;
+    PERFETTO_DCHECK(tag > kTombstone);
+    return tag;
+  }
+
+  size_t capacity_ = 0;
+  size_t size_ = 0;
+  size_t max_probe_length_ = 0;
+  size_t load_limit_ = 0;  // Updated every time |capacity_| changes.
+  int load_limit_percent_ =
+      kDefaultLoadLimitPct;  // Load factor limit in % of |capacity_|.
+
+  // These arrays have always the |capacity_| elements.
+  // Note: AlignedUniquePtr just allocates memory, doesn't invoke any ctor/dtor.
+  std::unique_ptr<uint8_t[]> tags_;
+  AlignedUniquePtr<Key[]> keys_;
+  AlignedUniquePtr<Value[]> values_;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
+// gen_amalgamated begin header: include/perfetto/ext/tracing/core/client_identity.h
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_CLIENT_IDENTITY_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_CORE_CLIENT_IDENTITY_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+
+namespace perfetto {
+
+// This class groups data fields of a connected client that can get passed in
+// the tracing core to be emitted to trace packets.
+class ClientIdentity {
+ public:
+  ClientIdentity() = default;
+  ClientIdentity(uid_t uid, pid_t pid, MachineID machine_id = kDefaultMachineID)
+      : uid_(uid), pid_(pid), machine_id_(machine_id) {}
+
+  bool has_uid() const { return uid_ != base::kInvalidUid; }
+  uid_t uid() const { return uid_; }
+
+  bool has_pid() const { return pid_ != base::kInvalidPid; }
+  pid_t pid() const { return pid_; }
+
+  bool has_non_default_machine_id() const {
+    return machine_id_ != kDefaultMachineID;
+  }
+  base::MachineID machine_id() const { return machine_id_; }
+
+ private:
+  uid_t uid_ = base::kInvalidUid;
+  pid_t pid_ = base::kInvalidPid;
+  MachineID machine_id_ = kDefaultMachineID;
+};
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_CLIENT_IDENTITY_H_
+// gen_amalgamated begin header: src/tracing/core/histogram.h
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef SRC_TRACING_CORE_HISTOGRAM_H_
+#define SRC_TRACING_CORE_HISTOGRAM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <limits>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+
+using HistValue = int64_t;
+
+// Usage:
+// Histogram<10, 100, 1000> h;  // A histogram with 3 + 1 (overflow) bucket.
+// h.Add(value);
+// h.GetBucketSum(0);  // Returns SUM(x) for 0 < x <= 10
+// h.GetBucketSum(1);  // Returns SUM(x) for 10 < x <= 100
+// h.GetBucketSum(2);  // Returns SUM(x) for 100 < x <= 1000
+// h.GetBucketSum(3);  // Returns SUM(x) for x > 1000
+// Likewise h.GetBucketCount(x) returns the COUNT(x).
+template <HistValue... thresholds>
+class Histogram {
+ public:
+  // 1+ is for the overflow bucket (anything > the last threshold).
+  static constexpr size_t kNumBuckets = 1 + sizeof...(thresholds);
+
+  void Add(HistValue value) {
+    size_t bucket = BucketForValue(value);
+    bucket_sum_[bucket] += value;
+    ++bucket_count_[bucket];
+  }
+
+  static constexpr size_t num_buckets() { return kNumBuckets; }
+
+  HistValue GetBucketThres(size_t n) const {
+    PERFETTO_DCHECK(n < kNumBuckets);
+    return bucket_thres_[n];
+  }
+
+  uint64_t GetBucketCount(size_t n) const {
+    PERFETTO_DCHECK(n < kNumBuckets);
+    return bucket_count_[n];
+  }
+
+  HistValue GetBucketSum(size_t n) const {
+    PERFETTO_DCHECK(n < kNumBuckets);
+    return bucket_sum_[n];
+  }
+
+  void Merge(const Histogram& other) {
+    for (size_t i = 0; i < kNumBuckets; ++i) {
+      bucket_sum_[i] += other.bucket_sum_[i];
+      bucket_count_[i] += other.bucket_count_[i];
+    }
+  }
+
+ private:
+  static size_t BucketForValue(HistValue value) {
+    for (size_t i = 0; i < kNumBuckets - 1; i++) {
+      if (value <= bucket_thres_[i])
+        return i;
+    }
+    return kNumBuckets - 1;
+  }
+
+  static constexpr HistValue bucket_thres_[kNumBuckets]{
+      thresholds..., std::numeric_limits<HistValue>::max()};
+
+  HistValue bucket_sum_[kNumBuckets]{};
+  uint64_t bucket_count_[kNumBuckets]{};
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_HISTOGRAM_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef SRC_TRACING_CORE_TRACE_BUFFER_H_
+#define SRC_TRACING_CORE_TRACE_BUFFER_H_
+
+#include <stdint.h>
+#include <string.h>
+
+#include <array>
+#include <limits>
+#include <map>
+#include <tuple>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/flat_hash_map.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
+// gen_amalgamated expanded: #include "src/tracing/core/histogram.h"
+
+namespace perfetto {
+
+class TracePacket;
+
+// The main buffer, owned by the tracing service, where all the trace data is
+// ultimately stored into. The service will own several instances of this class,
+// at least one per active consumer (as defined in the |buffers| section of
+// trace_config.proto) and will copy chunks from the producer's shared memory
+// buffers into here when a CommitData IPC is received.
+//
+// Writing into the buffer
+// -----------------------
+// Data is copied from the SMB(s) using CopyChunkUntrusted(). The buffer will
+// hence contain data coming from different producers and different writer
+// sequences, more specifically:
+// - The service receives data by several producer(s), identified by their ID.
+// - Each producer writes several sequences identified by the same WriterID.
+//   (they correspond to TraceWriter instances in the producer).
+// - Each Writer writes, in order, several chunks.
+// - Each chunk contains zero, one, or more TracePacket(s), or even just
+//   fragments of packets (when they span across several chunks).
+//
+// So at any point in time, the buffer will contain a variable number of logical
+// sequences identified by the {ProducerID, WriterID} tuple. Any given chunk
+// will only contain packets (or fragments) belonging to the same sequence.
+//
+// The buffer operates by default as a ring buffer.
+// It has two overwrite policies:
+//  1. kOverwrite (default): if the write pointer reaches the read pointer, old
+//     unread chunks will be overwritten by new chunks.
+//  2. kDiscard: if the write pointer reaches the read pointer, unread chunks
+//     are preserved and the new chunks are discarded. Any future write becomes
+//     a no-op, even if the reader manages to fully catch up. This is because
+//     once a chunk is discarded, the sequence of packets is broken and trying
+//     to recover would be too hard (also due to the fact that, at the same
+//     time, we allow out-of-order commits and chunk re-writes).
+//
+// Chunks are (over)written in the same order of the CopyChunkUntrusted() calls.
+// When overwriting old content, entire chunks are overwritten or clobbered.
+// The buffer never leaves a partial chunk around. Chunks' payload is copied
+// as-is, but their header is not and is repacked in order to keep the
+// ProducerID around.
+//
+// Chunks are stored in the buffer next to each other. Each chunk is prefixed by
+// an inline header (ChunkRecord), which contains most of the fields of the
+// SharedMemoryABI ChunkHeader + the ProducerID + the size of the payload.
+// It's a conventional binary object stream essentially, where each ChunkRecord
+// tells where it ends and hence where to find the next one, like this:
+//
+//          .-------------------------. 16 byte boundary
+//          | ChunkRecord:   16 bytes |
+//          | - chunk id:     4 bytes |
+//          | - producer id:  2 bytes |
+//          | - writer id:    2 bytes |
+//          | - #fragments:   2 bytes |
+//    +-----+ - record size:  2 bytes |
+//    |     | - flags+pad:    4 bytes |
+//    |     +-------------------------+
+//    |     |                         |
+//    |     :     Chunk payload       :
+//    |     |                         |
+//    |     +-------------------------+
+//    |     |    Optional padding     |
+//    +---> +-------------------------+ 16 byte boundary
+//          |      ChunkRecord        |
+//          :                         :
+// Chunks stored in the buffer are always rounded up to 16 bytes (that is
+// sizeof(ChunkRecord)), in order to avoid further inner fragmentation.
+// Special "padding" chunks can be put in the buffer, e.g. in the case when we
+// try to write a chunk of size N while the write pointer is at the end of the
+// buffer, but the write pointer is < N bytes from the end (and hence needs to
+// wrap over).
+// Because of this, the buffer is self-describing: the contents of the buffer
+// can be reconstructed by just looking at the buffer content (this will be
+// quite useful in future to recover the buffer from crash reports).
+//
+// However, in order to keep some operations (patching and reading) fast, a
+// lookaside index is maintained (in |index_|), keeping each chunk in the buffer
+// indexed by their {ProducerID, WriterID, ChunkID} tuple.
+//
+// Patching data out-of-band
+// -------------------------
+// This buffer also supports patching chunks' payload out-of-band, after they
+// have been stored. This is to allow producers to backfill the "size" fields
+// of the protos that spawn across several chunks, when the previous chunks are
+// returned to the service. The MaybePatchChunkContents() deals with the fact
+// that a chunk might have been lost (because of wrapping) by the time the OOB
+// IPC comes.
+//
+// Reading from the buffer
+// -----------------------
+// This class supports one reader only (the consumer). Reads are NOT idempotent
+// as they move the read cursors around. Reading back the buffer is the most
+// conceptually complex part. The ReadNextTracePacket() method operates with
+// whole packet granularity. Packets are returned only when all their fragments
+// are available.
+// This class takes care of:
+// - Gluing packets within the same sequence, even if they are not stored
+//   adjacently in the buffer.
+// - Re-ordering chunks within a sequence (using the ChunkID, which wraps).
+// - Detecting holes in packet fragments (because of loss of chunks).
+// Reads guarantee that packets for the same sequence are read in FIFO order
+// (according to their ChunkID), but don't give any guarantee about the read
+// order of packets from different sequences, see comments in
+// ReadNextTracePacket() below.
+class TraceBuffer {
+ public:
+  static const size_t InlineChunkHeaderSize;  // For test/fake_packet.{cc,h}.
+
+  // See comment in the header above.
+  enum OverwritePolicy { kOverwrite, kDiscard };
+
+  // Argument for out-of-band patches applied through TryPatchChunkContents().
+  struct Patch {
+    // From SharedMemoryABI::kPacketHeaderSize.
+    static constexpr size_t kSize = 4;
+
+    size_t offset_untrusted;
+    std::array<uint8_t, kSize> data;
+  };
+
+  // Identifiers that are constant for a packet sequence.
+  struct PacketSequenceProperties {
+    ProducerID producer_id_trusted;
+    ClientIdentity client_identity_trusted;
+    WriterID writer_id;
+
+    uid_t producer_uid_trusted() const { return client_identity_trusted.uid(); }
+    pid_t producer_pid_trusted() const { return client_identity_trusted.pid(); }
+  };
+
+  // Holds the "used chunk" stats for each <Producer, Writer> tuple.
+  struct WriterStats {
+    Histogram<8, 32, 128, 512, 1024, 2048, 4096, 8192, 12288, 16384>
+        used_chunk_hist;
+  };
+
+  using WriterStatsMap = base::FlatHashMap<ProducerAndWriterID,
+                                           WriterStats,
+                                           std::hash<ProducerAndWriterID>,
+                                           base::QuadraticProbe,
+                                           /*AppendOnly=*/true>;
+
+  // Can return nullptr if the memory allocation fails.
+  static std::unique_ptr<TraceBuffer> Create(size_t size_in_bytes,
+                                             OverwritePolicy = kOverwrite);
+
+  ~TraceBuffer();
+
+  // Copies a Chunk from a producer Shared Memory Buffer into the trace buffer.
+  // |src| points to the first packet in the SharedMemoryABI's chunk shared with
+  // an untrusted producer. "untrusted" here means: the producer might be
+  // malicious and might change |src| concurrently while we read it (internally
+  // this method memcpy()-s first the chunk before processing it). None of the
+  // arguments should be trusted, unless otherwise stated. We can trust that
+  // |src| points to a valid memory area, but not its contents.
+  //
+  // This method may be called multiple times for the same chunk. In this case,
+  // the original chunk's payload will be overridden and its number of fragments
+  // and flags adjusted to match |num_fragments| and |chunk_flags|. The service
+  // may use this to insert partial chunks (|chunk_complete = false|) before the
+  // producer has committed them.
+  //
+  // If |chunk_complete| is |false|, the TraceBuffer will only consider the
+  // first |num_fragments - 1| packets to be complete, since the producer may
+  // not have finished writing the latest packet. Reading from a sequence will
+  // also not progress past any incomplete chunks until they were rewritten with
+  // |chunk_complete = true|, e.g. after a producer's commit.
+  //
+  // TODO(eseckler): Pass in a PacketStreamProperties instead of individual IDs.
+  void CopyChunkUntrusted(ProducerID producer_id_trusted,
+                          const ClientIdentity& client_identity_trusted,
+
+                          WriterID writer_id,
+                          ChunkID chunk_id,
+                          uint16_t num_fragments,
+                          uint8_t chunk_flags,
+                          bool chunk_complete,
+                          const uint8_t* src,
+                          size_t size);
+
+  // Applies a batch of |patches| to the given chunk, if the given chunk is
+  // still in the buffer. Does nothing if the given ChunkID is gone.
+  // Returns true if the chunk has been found and patched, false otherwise.
+  // |other_patches_pending| is used to determine whether this is the only
+  // batch of patches for the chunk or there is more.
+  // If |other_patches_pending| == false, the chunk is marked as ready to be
+  // consumed. If true, the state of the chunk is not altered.
+  //
+  // Note: If the producer is batching commits (see shared_memory_arbiter.h), it
+  // will also attempt to do patching locally. Namely, if nested messages are
+  // completed while the chunk on which they started is being batched (i.e.
+  // before it has been committed to the service), the producer will apply the
+  // respective patches to the batched chunk. These patches will not be sent to
+  // the service - i.e. only the patches that the producer did not manage to
+  // apply before committing the chunk will be applied here.
+  bool TryPatchChunkContents(ProducerID,
+                             WriterID,
+                             ChunkID,
+                             const Patch* patches,
+                             size_t patches_size,
+                             bool other_patches_pending);
+
+  // To read the contents of the buffer the caller needs to:
+  //   BeginRead()
+  //   while (ReadNextTracePacket(packet_fragments)) { ... }
+  // No other calls to any other method should be interleaved between
+  // BeginRead() and ReadNextTracePacket().
+  // Reads in the TraceBuffer are NOT idempotent.
+  void BeginRead();
+
+  // Returns the next packet in the buffer, if any, and the producer_id,
+  // producer_uid, and writer_id of the producer/writer that wrote it (as passed
+  // in the CopyChunkUntrusted() call). Returns false if no packets can be read
+  // at this point. If a packet was read successfully,
+  // |previous_packet_on_sequence_dropped| is set to |true| if the previous
+  // packet on the sequence was dropped from the buffer before it could be read
+  // (e.g. because its chunk was overridden due to the ring buffer wrapping or
+  // due to an ABI violation), and to |false| otherwise.
+  //
+  // This function returns only complete packets. Specifically:
+  // When there is at least one complete packet in the buffer, this function
+  // returns true and populates the TracePacket argument with the boundaries of
+  // each fragment for one packet.
+  // TracePacket will have at least one slice when this function returns true.
+  // When there are no whole packets eligible to read (e.g. we are still missing
+  // fragments) this function returns false.
+  // This function guarantees also that packets for a given
+  // {ProducerID, WriterID} are read in FIFO order.
+  // This function does not guarantee any ordering w.r.t. packets belonging to
+  // different WriterID(s). For instance, given the following packets copied
+  // into the buffer:
+  //   {ProducerID: 1, WriterID: 1}: P1 P2 P3
+  //   {ProducerID: 1, WriterID: 2}: P4 P5 P6
+  //   {ProducerID: 2, WriterID: 1}: P7 P8 P9
+  // The following read sequence is possible:
+  //   P1, P4, P7, P2, P3, P5, P8, P9, P6
+  // But the following is guaranteed to NOT happen:
+  //   P1, P5, P7, P4 (P4 cannot come after P5)
+  bool ReadNextTracePacket(TracePacket*,
+                           PacketSequenceProperties* sequence_properties,
+                           bool* previous_packet_on_sequence_dropped);
+
+  // Creates a read-only clone of the trace buffer. The read iterators of the
+  // new buffer will be reset, as if no Read() had been called. Calls to
+  // CopyChunkUntrusted() and TryPatchChunkContents() on the returned cloned
+  // TraceBuffer will CHECK().
+  std::unique_ptr<TraceBuffer> CloneReadOnly() const;
+
+  void set_read_only() { read_only_ = true; }
+  const WriterStatsMap& writer_stats() const { return writer_stats_; }
+  const TraceStats::BufferStats& stats() const { return stats_; }
+  size_t size() const { return size_; }
+  size_t used_size() const { return used_size_; }
+  OverwritePolicy overwrite_policy() const { return overwrite_policy_; }
+  bool has_data() const { return has_data_; }
+
+ private:
+  friend class TraceBufferTest;
+
+  // ChunkRecord is a Chunk header stored inline in the |data_| buffer, before
+  // the chunk payload (the packets' data). The |data_| buffer looks like this:
+  // +---------------+------------------++---------------+-----------------+
+  // | ChunkRecord 1 | Chunk payload 1  || ChunkRecord 2 | Chunk payload 2 | ...
+  // +---------------+------------------++---------------+-----------------+
+  // Most of the ChunkRecord fields are copied from SharedMemoryABI::ChunkHeader
+  // (the chunk header used in the shared memory buffers).
+  // A ChunkRecord can be a special "padding" record. In this case its payload
+  // should be ignored and the record should be just skipped.
+  //
+  // Full page move optimization:
+  // This struct has to be exactly (sizeof(PageHeader) + sizeof(ChunkHeader))
+  // (from shared_memory_abi.h) to allow full page move optimizations
+  // (TODO(primiano): not implemented yet). In the special case of moving a full
+  // 4k page that contains only one chunk, in fact, we can just ask the kernel
+  // to move the full SHM page (see SPLICE_F_{GIFT,MOVE}) and overlay the
+  // ChunkRecord on top of the moved SMB's header (page + chunk header).
+  // This special requirement is covered by static_assert(s) in the .cc file.
+  struct ChunkRecord {
+    explicit ChunkRecord(size_t sz) : flags{0}, is_padding{0} {
+      PERFETTO_DCHECK(sz >= sizeof(ChunkRecord) &&
+                      sz % sizeof(ChunkRecord) == 0 && sz <= kMaxSize);
+      size = static_cast<decltype(size)>(sz);
+    }
+
+    bool is_valid() const { return size != 0; }
+
+    // Keep this structure packed and exactly 16 bytes (128 bits) big.
+
+    // [32 bits] Monotonic counter within the same writer_id.
+    ChunkID chunk_id = 0;
+
+    // [16 bits] ID of the Producer from which the Chunk was copied from.
+    ProducerID producer_id = 0;
+
+    // [16 bits] Unique per Producer (but not within the service).
+    // If writer_id == kWriterIdPadding the record should just be skipped.
+    WriterID writer_id = 0;
+
+    // Number of fragments contained in the chunk.
+    uint16_t num_fragments = 0;
+
+    // Size in bytes, including sizeof(ChunkRecord) itself.
+    uint16_t size;
+
+    uint8_t flags : 6;  // See SharedMemoryABI::ChunkHeader::flags.
+    static constexpr size_t kFlagsBitMask = (1 << 6) - 1;
+
+    uint8_t is_padding : 1;
+    uint8_t unused_flag : 1;
+
+    // Not strictly needed, can be reused for more fields in the future. But
+    // right now helps to spot chunks in hex dumps.
+    char unused[3] = {'C', 'H', 'U'};
+
+    static constexpr size_t kMaxSize =
+        std::numeric_limits<decltype(size)>::max();
+  };
+
+  // Lookaside index entry. This serves two purposes:
+  // 1) Allow a fast lookup of ChunkRecord by their ID (the tuple
+  //   {ProducerID, WriterID, ChunkID}). This is used when applying out-of-band
+  //   patches to the contents of the chunks after they have been copied into
+  //   the TraceBuffer.
+  // 2) keep the chunks ordered by their ID. This is used when reading back.
+  // 3) Keep metadata about the status of the chunk, e.g. whether the contents
+  //    have been read already and should be skipped in a future read pass.
+  // This struct should not have any field that is essential for reconstructing
+  // the contents of the buffer from a crash dump.
+  struct ChunkMeta {
+    // Key used for sorting in the map.
+    struct Key {
+      Key(ProducerID p, WriterID w, ChunkID c)
+          : producer_id{p}, writer_id{w}, chunk_id{c} {}
+
+      Key(const Key&) noexcept = default;
+      Key& operator=(const Key&) = default;
+
+      explicit Key(const ChunkRecord& cr)
+          : Key(cr.producer_id, cr.writer_id, cr.chunk_id) {}
+
+      // Note that this sorting doesn't keep into account the fact that ChunkID
+      // will wrap over at some point. The extra logic in SequenceIterator deals
+      // with that.
+      bool operator<(const Key& other) const {
+        return std::tie(producer_id, writer_id, chunk_id) <
+               std::tie(other.producer_id, other.writer_id, other.chunk_id);
+      }
+
+      bool operator==(const Key& other) const {
+        return std::tie(producer_id, writer_id, chunk_id) ==
+               std::tie(other.producer_id, other.writer_id, other.chunk_id);
+      }
+
+      bool operator!=(const Key& other) const { return !(*this == other); }
+
+      // These fields should match at all times the corresponding fields in
+      // the |chunk_record|. They are copied here purely for efficiency to avoid
+      // dereferencing the buffer all the time.
+      ProducerID producer_id;
+      WriterID writer_id;
+      ChunkID chunk_id;
+    };
+
+    enum IndexFlags : uint8_t {
+      // If set, the chunk state was kChunkComplete at the time it was copied.
+      // If unset, the chunk was still kChunkBeingWritten while copied. When
+      // reading from the chunk's sequence, the sequence will not advance past
+      // this chunk until this flag is set.
+      kComplete = 1 << 0,
+
+      // If set, we skipped the last packet that we read from this chunk e.g.
+      // because we it was a continuation from a previous chunk that was dropped
+      // or due to an ABI violation.
+      kLastReadPacketSkipped = 1 << 1
+    };
+
+    ChunkMeta(uint32_t _record_off,
+              uint16_t _num_fragments,
+              bool complete,
+              uint8_t _flags,
+              const ClientIdentity& client_identity)
+        : record_off{_record_off},
+          client_identity_trusted(client_identity),
+          flags{_flags},
+          num_fragments{_num_fragments} {
+      if (complete)
+        index_flags = kComplete;
+    }
+
+    ChunkMeta(const ChunkMeta&) noexcept = default;
+
+    bool is_complete() const { return index_flags & kComplete; }
+
+    void set_complete(bool complete) {
+      if (complete) {
+        index_flags |= kComplete;
+      } else {
+        index_flags &= ~kComplete;
+      }
+    }
+
+    bool last_read_packet_skipped() const {
+      return index_flags & kLastReadPacketSkipped;
+    }
+
+    void set_last_read_packet_skipped(bool skipped) {
+      if (skipped) {
+        index_flags |= kLastReadPacketSkipped;
+      } else {
+        index_flags &= ~kLastReadPacketSkipped;
+      }
+    }
+
+    const uint32_t record_off;  // Offset of ChunkRecord within |data_|.
+    const ClientIdentity client_identity_trusted;
+    // Flags set by TraceBuffer to track the state of the chunk in the index.
+    uint8_t index_flags = 0;
+
+    // Correspond to |chunk_record->flags| and |chunk_record->num_fragments|.
+    // Copied here for performance reasons (avoids having to dereference
+    // |chunk_record| while iterating over ChunkMeta) and to aid debugging in
+    // case the buffer gets corrupted.
+    uint8_t flags = 0;           // See SharedMemoryABI::ChunkHeader::flags.
+    uint16_t num_fragments = 0;  // Total number of packet fragments.
+
+    uint16_t num_fragments_read = 0;  // Number of fragments already read.
+
+    // The start offset of the next fragment (the |num_fragments_read|-th) to be
+    // read. This is the offset in bytes from the beginning of the ChunkRecord's
+    // payload (the 1st fragment starts at |chunk_record| +
+    // sizeof(ChunkRecord)).
+    uint16_t cur_fragment_offset = 0;
+  };
+
+  using ChunkMap = std::map<ChunkMeta::Key, ChunkMeta>;
+
+  // Allows to iterate over a sub-sequence of |index_| for all keys belonging to
+  // the same {ProducerID,WriterID}. Furthermore takes into account the wrapping
+  // of ChunkID. Instances are valid only as long as the |index_| is not altered
+  // (can be used safely only between adjacent ReadNextTracePacket() calls).
+  // The order of the iteration will proceed in the following order:
+  // |wrapping_id| + 1 -> |seq_end|, |seq_begin| -> |wrapping_id|.
+  // Practical example:
+  // - Assume that kMaxChunkID == 7
+  // - Assume that we have all 8 chunks in the range (0..7).
+  // - Hence, |seq_begin| == c0, |seq_end| == c7
+  // - Assume |wrapping_id| = 4 (c4 is the last chunk copied over
+  //   through a CopyChunkUntrusted()).
+  // The resulting iteration order will be: c5, c6, c7, c0, c1, c2, c3, c4.
+  struct SequenceIterator {
+    // Points to the 1st key (the one with the numerically min ChunkID).
+    ChunkMap::iterator seq_begin;
+
+    // Points one past the last key (the one with the numerically max ChunkID).
+    ChunkMap::iterator seq_end;
+
+    // Current iterator, always >= seq_begin && <= seq_end.
+    ChunkMap::iterator cur;
+
+    // The latest ChunkID written. Determines the start/end of the sequence.
+    ChunkID wrapping_id;
+
+    bool is_valid() const { return cur != seq_end; }
+
+    ProducerID producer_id() const {
+      PERFETTO_DCHECK(is_valid());
+      return cur->first.producer_id;
+    }
+
+    WriterID writer_id() const {
+      PERFETTO_DCHECK(is_valid());
+      return cur->first.writer_id;
+    }
+
+    ChunkID chunk_id() const {
+      PERFETTO_DCHECK(is_valid());
+      return cur->first.chunk_id;
+    }
+
+    ChunkMeta& operator*() {
+      PERFETTO_DCHECK(is_valid());
+      return cur->second;
+    }
+
+    // Moves |cur| to the next chunk in the index.
+    // is_valid() will become false after calling this, if this was the last
+    // entry of the sequence.
+    void MoveNext();
+
+    void MoveToEnd() { cur = seq_end; }
+  };
+
+  enum class ReadAheadResult {
+    kSucceededReturnSlices,
+    kFailedMoveToNextSequence,
+    kFailedStayOnSameSequence,
+  };
+
+  enum class ReadPacketResult {
+    kSucceeded,
+    kFailedInvalidPacket,
+    kFailedEmptyPacket,
+  };
+
+  explicit TraceBuffer(OverwritePolicy);
+  TraceBuffer(const TraceBuffer&) = delete;
+  TraceBuffer& operator=(const TraceBuffer&) = delete;
+
+  // Not using the implicit copy ctor to avoid unintended copies.
+  // This tagged ctor should be used only for Clone().
+  struct CloneCtor {};
+  TraceBuffer(CloneCtor, const TraceBuffer&);
+
+  bool Initialize(size_t size);
+
+  // Returns an object that allows to iterate over chunks in the |index_| that
+  // have the same {ProducerID, WriterID} of
+  // |seq_begin.first.{producer,writer}_id|. |seq_begin| must be an iterator to
+  // the first entry in the |index_| that has a different {ProducerID, WriterID}
+  // from the previous one. It is valid for |seq_begin| to be == index_.end()
+  // (i.e. if the index is empty). The iteration takes care of ChunkID wrapping,
+  // by using |last_chunk_id_|.
+  SequenceIterator GetReadIterForSequence(ChunkMap::iterator seq_begin);
+
+  // Used as a last resort when a buffer corruption is detected.
+  void ClearContentsAndResetRWCursors();
+
+  // Adds a padding record of the given size (must be a multiple of
+  // sizeof(ChunkRecord)).
+  void AddPaddingRecord(size_t);
+
+  // Look for contiguous fragment of the same packet starting from |read_iter_|.
+  // If a contiguous packet is found, all the fragments are pushed into
+  // TracePacket and the function returns kSucceededReturnSlices. If not, the
+  // function returns either kFailedMoveToNextSequence or
+  // kFailedStayOnSameSequence, telling the caller to continue looking for
+  // packets.
+  ReadAheadResult ReadAhead(TracePacket*);
+
+  // Deletes (by marking the record invalid and removing form the index) all
+  // chunks from |wptr_| to |wptr_| + |bytes_to_clear|.
+  // Returns:
+  //   * The size of the gap left between the next valid Chunk and the end of
+  //     the deletion range.
+  //   * 0 if no next valid chunk exists (if the buffer is still zeroed).
+  //   * -1 if the buffer |overwrite_policy_| == kDiscard and the deletion would
+  //     cause unread chunks to be overwritten. In this case the buffer is left
+  //     untouched.
+  // Graphically, assume the initial situation is the following (|wptr_| = 10).
+  // |0        |10 (wptr_)       |30       |40                 |60
+  // +---------+-----------------+---------+-------------------+---------+
+  // | Chunk 1 | Chunk 2         | Chunk 3 | Chunk 4           | Chunk 5 |
+  // +---------+-----------------+---------+-------------------+---------+
+  //           |_________Deletion range_______|~~return value~~|
+  //
+  // A call to DeleteNextChunksFor(32) will remove chunks 2,3,4 and return 18
+  // (60 - 42), the distance between chunk 5 and the end of the deletion range.
+  ssize_t DeleteNextChunksFor(size_t bytes_to_clear);
+
+  // Decodes the boundaries of the next packet (or a fragment) pointed by
+  // ChunkMeta and pushes that into |TracePacket|. It also increments the
+  // |num_fragments_read| counter.
+  // TracePacket can be nullptr, in which case the read state is still advanced.
+  // When TracePacket is not nullptr, ProducerID must also be not null and will
+  // be updated with the ProducerID that originally wrote the chunk.
+  ReadPacketResult ReadNextPacketInChunk(ProducerAndWriterID,
+                                         ChunkMeta*,
+                                         TracePacket*);
+
+  void DcheckIsAlignedAndWithinBounds(const uint8_t* ptr) const {
+    PERFETTO_DCHECK(ptr >= begin() && ptr <= end() - sizeof(ChunkRecord));
+    PERFETTO_DCHECK(
+        (reinterpret_cast<uintptr_t>(ptr) & (alignof(ChunkRecord) - 1)) == 0);
+  }
+
+  ChunkRecord* GetChunkRecordAt(uint8_t* ptr) {
+    DcheckIsAlignedAndWithinBounds(ptr);
+    // We may be accessing a new (empty) record.
+    EnsureCommitted(static_cast<size_t>(ptr + sizeof(ChunkRecord) - begin()));
+    return reinterpret_cast<ChunkRecord*>(ptr);
+  }
+
+  void EnsureCommitted(size_t size) {
+    PERFETTO_DCHECK(size <= size_);
+    data_.EnsureCommitted(size);
+    used_size_ = std::max(used_size_, size);
+  }
+
+  void DiscardWrite();
+
+  // |src| can be nullptr (in which case |size| must be ==
+  // record.size - sizeof(ChunkRecord)), for the case of writing a padding
+  // record. |wptr_| is NOT advanced by this function, the caller must do that.
+  void WriteChunkRecord(uint8_t* wptr,
+                        const ChunkRecord& record,
+                        const uint8_t* src,
+                        size_t size) {
+    // Note: |record.size| will be slightly bigger than |size| because of the
+    // ChunkRecord header and rounding, to ensure that all ChunkRecord(s) are
+    // multiple of sizeof(ChunkRecord). The invariant is:
+    // record.size >= |size| + sizeof(ChunkRecord) (== if no rounding).
+    PERFETTO_DCHECK(size <= ChunkRecord::kMaxSize);
+    PERFETTO_DCHECK(record.size >= sizeof(record));
+    PERFETTO_DCHECK(record.size % sizeof(record) == 0);
+    PERFETTO_DCHECK(record.size >= size + sizeof(record));
+    DcheckIsAlignedAndWithinBounds(wptr);
+
+    // We may be writing to this area for the first time.
+    EnsureCommitted(static_cast<size_t>(wptr + record.size - begin()));
+
+    // Deliberately not a *D*CHECK.
+    PERFETTO_CHECK(wptr + sizeof(record) + size <= end());
+    memcpy(wptr, &record, sizeof(record));
+    if (PERFETTO_LIKELY(src)) {
+      // If the producer modifies the data in the shared memory buffer while we
+      // are copying it to the central buffer, TSAN will (rightfully) flag that
+      // as a race. However the entire purpose of copying the data into the
+      // central buffer is that we can validate it without worrying that the
+      // producer changes it from under our feet, so this race is benign. The
+      // alternative would be to try computing which part of the buffer is safe
+      // to read (assuming a well-behaving client), but the risk of introducing
+      // a bug that way outweighs the benefit.
+      PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(
+          src, size, "Benign race when copying chunk from shared memory.")
+      memcpy(wptr + sizeof(record), src, size);
+    } else {
+      PERFETTO_DCHECK(size == record.size - sizeof(record));
+    }
+    const size_t rounding_size = record.size - sizeof(record) - size;
+    memset(wptr + sizeof(record) + size, 0, rounding_size);
+  }
+
+  uint32_t GetOffset(const void* _addr) {
+    const uintptr_t addr = reinterpret_cast<uintptr_t>(_addr);
+    const uintptr_t buf_start = reinterpret_cast<uintptr_t>(begin());
+    PERFETTO_DCHECK(addr >= buf_start && addr < buf_start + size_);
+    return static_cast<uint32_t>(addr - buf_start);
+  }
+
+  uint8_t* begin() const { return reinterpret_cast<uint8_t*>(data_.Get()); }
+  uint8_t* end() const { return begin() + size_; }
+  size_t size_to_end() const { return static_cast<size_t>(end() - wptr_); }
+
+  base::PagedMemory data_;
+  size_t size_ = 0;            // Size in bytes of |data_|.
+
+  // High watermark. The number of bytes (<= |size_|) written into the buffer
+  // before the first wraparound. This increases as data is written into the
+  // buffer and then saturates at |size_|. Used for CloneReadOnly().
+  size_t used_size_ = 0;
+
+  size_t max_chunk_size_ = 0;  // Max size in bytes allowed for a chunk.
+  uint8_t* wptr_ = nullptr;    // Write pointer.
+
+  // An index that keeps track of the positions and metadata of each
+  // ChunkRecord.
+  ChunkMap index_;
+
+  // Read iterator used for ReadNext(). It is reset by calling BeginRead().
+  // It becomes invalid after any call to methods that alters the |index_|.
+  SequenceIterator read_iter_;
+
+  // See comments at the top of the file.
+  OverwritePolicy overwrite_policy_ = kOverwrite;
+
+  // This buffer is a read-only snapshot obtained via Clone(). If this is true
+  // calls to CopyChunkUntrusted() and TryPatchChunkContents() will CHECK().
+  bool read_only_ = false;
+
+  // Only used when |overwrite_policy_ == kDiscard|. This is set the first time
+  // a write fails because it would overwrite unread chunks.
+  bool discard_writes_ = false;
+
+  // Keeps track of the highest ChunkID written for a given sequence, taking
+  // into account a potential overflow of ChunkIDs. In the case of overflow,
+  // stores the highest ChunkID written since the overflow.
+  //
+  // TODO(primiano): should clean up keys from this map. Right now it grows
+  // without bounds (although realistically is not a problem unless we have too
+  // many producers/writers within the same trace session).
+  std::map<std::pair<ProducerID, WriterID>, ChunkID> last_chunk_id_written_;
+
+  // Statistics about buffer usage.
+  TraceStats::BufferStats stats_;
+
+  // Per-{Producer, Writer} statistics.
+  WriterStatsMap writer_stats_;
+
+  // Set to true upon the very first call to CopyChunkUntrusted() and never
+  // cleared. This is used to tell if the buffer has never been used since its
+  // creation (which in turn is used to optimize `clear_before_clone`).
+  bool has_data_ = false;
+
+#if PERFETTO_DCHECK_IS_ON()
+  bool changed_since_last_read_ = false;
+#endif
+
+  // When true disable some DCHECKs that have been put in place to detect
+  // bugs in the producers. This is for tests that feed malicious inputs and
+  // hence mimic a buggy producer.
+  bool suppress_client_dchecks_for_testing_ = false;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_TRACE_BUFFER_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/trace_buffer.h"
+
+#include <limits>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+#define TRACE_BUFFER_VERBOSE_LOGGING() 0  // Set to 1 when debugging unittests.
+#if TRACE_BUFFER_VERBOSE_LOGGING()
+#define TRACE_BUFFER_DLOG PERFETTO_DLOG
+#else
+#define TRACE_BUFFER_DLOG(...) void()
+#endif
+
+namespace perfetto {
+
+namespace {
+constexpr uint8_t kFirstPacketContinuesFromPrevChunk =
+    SharedMemoryABI::ChunkHeader::kFirstPacketContinuesFromPrevChunk;
+constexpr uint8_t kLastPacketContinuesOnNextChunk =
+    SharedMemoryABI::ChunkHeader::kLastPacketContinuesOnNextChunk;
+constexpr uint8_t kChunkNeedsPatching =
+    SharedMemoryABI::ChunkHeader::kChunkNeedsPatching;
+}  // namespace.
+
+const size_t TraceBuffer::InlineChunkHeaderSize = sizeof(ChunkRecord);
+
+// static
+std::unique_ptr<TraceBuffer> TraceBuffer::Create(size_t size_in_bytes,
+                                                 OverwritePolicy pol) {
+  std::unique_ptr<TraceBuffer> trace_buffer(new TraceBuffer(pol));
+  if (!trace_buffer->Initialize(size_in_bytes))
+    return nullptr;
+  return trace_buffer;
+}
+
+TraceBuffer::TraceBuffer(OverwritePolicy pol) : overwrite_policy_(pol) {
+  // See comments in ChunkRecord for the rationale of this.
+  static_assert(sizeof(ChunkRecord) == sizeof(SharedMemoryABI::PageHeader) +
+                                           sizeof(SharedMemoryABI::ChunkHeader),
+                "ChunkRecord out of sync with the layout of SharedMemoryABI");
+}
+
+TraceBuffer::~TraceBuffer() = default;
+
+bool TraceBuffer::Initialize(size_t size) {
+  static_assert(
+      SharedMemoryABI::kMinPageSize % sizeof(ChunkRecord) == 0,
+      "sizeof(ChunkRecord) must be an integer divider of a page size");
+  auto max_size = std::numeric_limits<decltype(ChunkMeta::record_off)>::max();
+  PERFETTO_CHECK(size <= static_cast<size_t>(max_size));
+  data_ = base::PagedMemory::Allocate(
+      size, base::PagedMemory::kMayFail | base::PagedMemory::kDontCommit);
+  if (!data_.IsValid()) {
+    PERFETTO_ELOG("Trace buffer allocation failed (size: %zu)", size);
+    return false;
+  }
+  size_ = size;
+  used_size_ = 0;
+  stats_.set_buffer_size(size);
+  max_chunk_size_ = std::min(size, ChunkRecord::kMaxSize);
+  wptr_ = begin();
+  index_.clear();
+  last_chunk_id_written_.clear();
+  read_iter_ = GetReadIterForSequence(index_.end());
+  return true;
+}
+
+// Note: |src| points to a shmem region that is shared with the producer. Assume
+// that the producer is malicious and will change the content of |src|
+// while we execute here. Don't do any processing on it other than memcpy().
+void TraceBuffer::CopyChunkUntrusted(
+    ProducerID producer_id_trusted,
+    const ClientIdentity& client_identity_trusted,
+    WriterID writer_id,
+    ChunkID chunk_id,
+    uint16_t num_fragments,
+    uint8_t chunk_flags,
+    bool chunk_complete,
+    const uint8_t* src,
+    size_t size) {
+  PERFETTO_CHECK(!read_only_);
+
+  // |record_size| = |size| + sizeof(ChunkRecord), rounded up to avoid to end
+  // up in a fragmented state where size_to_end() < sizeof(ChunkRecord).
+  const size_t record_size =
+      base::AlignUp<sizeof(ChunkRecord)>(size + sizeof(ChunkRecord));
+  TRACE_BUFFER_DLOG("CopyChunk @ %" PRIdPTR ", size=%zu", wptr_ - begin(), record_size);
+  if (PERFETTO_UNLIKELY(record_size > max_chunk_size_)) {
+    stats_.set_abi_violations(stats_.abi_violations() + 1);
+    PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+    return;
+  }
+
+  has_data_ = true;
+#if PERFETTO_DCHECK_IS_ON()
+  changed_since_last_read_ = true;
+#endif
+
+  // If the chunk hasn't been completed, we should only consider the first
+  // |num_fragments - 1| packets complete. For simplicity, we simply disregard
+  // the last one when we copy the chunk.
+  if (PERFETTO_UNLIKELY(!chunk_complete)) {
+    if (num_fragments > 0) {
+      num_fragments--;
+      // These flags should only affect the last packet in the chunk. We clear
+      // them, so that TraceBuffer is able to look at the remaining packets in
+      // this chunk.
+      chunk_flags &= ~kLastPacketContinuesOnNextChunk;
+      chunk_flags &= ~kChunkNeedsPatching;
+    }
+  }
+
+  ChunkRecord record(record_size);
+  record.producer_id = producer_id_trusted;
+  record.chunk_id = chunk_id;
+  record.writer_id = writer_id;
+  record.num_fragments = num_fragments;
+  record.flags = chunk_flags & ChunkRecord::kFlagsBitMask;
+  ChunkMeta::Key key(record);
+
+  // Check whether we have already copied the same chunk previously. This may
+  // happen if the service scrapes chunks in a potentially incomplete state
+  // before receiving commit requests for them from the producer. Note that the
+  // service may scrape and thus override chunks in arbitrary order since the
+  // chunks aren't ordered in the SMB.
+  const auto it = index_.find(key);
+  if (PERFETTO_UNLIKELY(it != index_.end())) {
+    ChunkMeta* record_meta = &it->second;
+    ChunkRecord* prev = GetChunkRecordAt(begin() + record_meta->record_off);
+
+    // Verify that the old chunk's metadata corresponds to the new one.
+    // Overridden chunks should never change size, since the page layout is
+    // fixed per writer. The number of fragments should also never decrease and
+    // flags should not be removed.
+    if (PERFETTO_UNLIKELY(ChunkMeta::Key(*prev) != key ||
+                          prev->size != record_size ||
+                          prev->num_fragments > num_fragments ||
+                          (prev->flags & chunk_flags) != prev->flags)) {
+      stats_.set_abi_violations(stats_.abi_violations() + 1);
+      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+      return;
+    }
+
+    // If this chunk was previously copied with the same number of fragments and
+    // the number didn't change, there's no need to copy it again. If the
+    // previous chunk was complete already, this should always be the case.
+    PERFETTO_DCHECK(suppress_client_dchecks_for_testing_ ||
+                    !record_meta->is_complete() ||
+                    (chunk_complete && prev->num_fragments == num_fragments));
+    if (prev->num_fragments == num_fragments) {
+      TRACE_BUFFER_DLOG("  skipping recommit of identical chunk");
+      return;
+    }
+
+    // If we've already started reading from chunk N+1 following this chunk N,
+    // don't override chunk N. Otherwise we may end up reading a packet from
+    // chunk N after having read from chunk N+1, thereby violating sequential
+    // read of packets. This shouldn't happen if the producer is well-behaved,
+    // because it shouldn't start chunk N+1 before completing chunk N.
+    ChunkMeta::Key subsequent_key = key;
+    static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
+                  "ChunkID wraps");
+    subsequent_key.chunk_id++;
+    const auto subsequent_it = index_.find(subsequent_key);
+    if (subsequent_it != index_.end() &&
+        subsequent_it->second.num_fragments_read > 0) {
+      stats_.set_abi_violations(stats_.abi_violations() + 1);
+      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+      return;
+    }
+
+    // We should not have read past the last packet.
+    if (record_meta->num_fragments_read > prev->num_fragments) {
+      PERFETTO_ELOG(
+          "TraceBuffer read too many fragments from an incomplete chunk");
+      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+      return;
+    }
+
+    uint8_t* wptr = reinterpret_cast<uint8_t*>(prev);
+    TRACE_BUFFER_DLOG("  overriding chunk @ %" PRIdPTR ", size=%zu", wptr - begin(),
+                      record_size);
+
+    // Update chunk meta data stored in the index, as it may have changed.
+    record_meta->num_fragments = num_fragments;
+    record_meta->flags = chunk_flags;
+    record_meta->set_complete(chunk_complete);
+
+    // Override the ChunkRecord contents at the original |wptr|.
+    TRACE_BUFFER_DLOG("  copying @ [%" PRIdPTR " - %" PRIdPTR "] %zu", wptr - begin(),
+                      uintptr_t(wptr - begin()) + record_size, record_size);
+    WriteChunkRecord(wptr, record, src, size);
+    TRACE_BUFFER_DLOG("Chunk raw: %s",
+                      base::HexDump(wptr, record_size).c_str());
+    stats_.set_chunks_rewritten(stats_.chunks_rewritten() + 1);
+    return;
+  }
+
+  if (PERFETTO_UNLIKELY(discard_writes_))
+    return DiscardWrite();
+
+  // If there isn't enough room from the given write position. Write a padding
+  // record to clear the end of the buffer and wrap back.
+  const size_t cached_size_to_end = size_to_end();
+  if (PERFETTO_UNLIKELY(record_size > cached_size_to_end)) {
+    ssize_t res = DeleteNextChunksFor(cached_size_to_end);
+    if (res == -1)
+      return DiscardWrite();
+    PERFETTO_DCHECK(static_cast<size_t>(res) <= cached_size_to_end);
+    AddPaddingRecord(cached_size_to_end);
+    wptr_ = begin();
+    stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
+    PERFETTO_DCHECK(size_to_end() >= record_size);
+  }
+
+  // At this point either |wptr_| points to an untouched part of the buffer
+  // (i.e. *wptr_ == 0) or we are about to overwrite one or more ChunkRecord(s).
+  // In the latter case we need to first figure out where the next valid
+  // ChunkRecord is (if it exists) and add padding between the new record.
+  // Example ((w) == write cursor):
+  //
+  // Initial state (wtpr_ == 0):
+  // |0 (w)    |10               |30                  |50
+  // +---------+-----------------+--------------------+--------------------+
+  // | Chunk 1 | Chunk 2         | Chunk 3            | Chunk 4            |
+  // +---------+-----------------+--------------------+--------------------+
+  //
+  // Let's assume we now want now write a 5th Chunk of size == 35. The final
+  // state should look like this:
+  // |0                                |35 (w)         |50
+  // +---------------------------------+---------------+--------------------+
+  // | Chunk 5                         | Padding Chunk | Chunk 4            |
+  // +---------------------------------+---------------+--------------------+
+
+  // Deletes all chunks from |wptr_| to |wptr_| + |record_size|.
+  ssize_t del_res = DeleteNextChunksFor(record_size);
+  if (del_res == -1)
+    return DiscardWrite();
+  size_t padding_size = static_cast<size_t>(del_res);
+
+  // Now first insert the new chunk. At the end, if necessary, add the padding.
+  stats_.set_chunks_written(stats_.chunks_written() + 1);
+  stats_.set_bytes_written(stats_.bytes_written() + record_size);
+
+  uint32_t chunk_off = GetOffset(GetChunkRecordAt(wptr_));
+  auto it_and_inserted =
+      index_.emplace(key, ChunkMeta(chunk_off, num_fragments, chunk_complete,
+                                    chunk_flags, client_identity_trusted));
+  PERFETTO_DCHECK(it_and_inserted.second);
+  TRACE_BUFFER_DLOG("  copying @ [%" PRIdPTR " - %" PRIdPTR "] %zu", wptr_ - begin(),
+                    uintptr_t(wptr_ - begin()) + record_size, record_size);
+  WriteChunkRecord(wptr_, record, src, size);
+  TRACE_BUFFER_DLOG("Chunk raw: %s", base::HexDump(wptr_, record_size).c_str());
+  wptr_ += record_size;
+  if (wptr_ >= end()) {
+    PERFETTO_DCHECK(padding_size == 0);
+    wptr_ = begin();
+    stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
+  }
+  DcheckIsAlignedAndWithinBounds(wptr_);
+
+  // Chunks may be received out of order, so only update last_chunk_id if the
+  // new chunk_id is larger. But take into account overflows by only selecting
+  // the new ID if its distance to the latest ID is smaller than half the number
+  // space.
+  //
+  // This accounts for both the case where the new ID has just overflown and
+  // last_chunk_id be updated even though it's smaller (e.g. |chunk_id| = 1 and
+  // |last_chunk_id| = kMaxChunkId; chunk_id - last_chunk_id = 0) and the case
+  // where the new ID is an out-of-order ID right after an overflow and
+  // last_chunk_id shouldn't be updated even though it's larger (e.g. |chunk_id|
+  // = kMaxChunkId and |last_chunk_id| = 1; chunk_id - last_chunk_id =
+  // kMaxChunkId - 1).
+  auto producer_and_writer_id = std::make_pair(producer_id_trusted, writer_id);
+  ChunkID& last_chunk_id = last_chunk_id_written_[producer_and_writer_id];
+  static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
+                "This code assumes that ChunkID wraps at kMaxChunkID");
+  if (chunk_id - last_chunk_id < kMaxChunkID / 2) {
+    last_chunk_id = chunk_id;
+  } else {
+    stats_.set_chunks_committed_out_of_order(
+        stats_.chunks_committed_out_of_order() + 1);
+  }
+
+  if (padding_size)
+    AddPaddingRecord(padding_size);
+}
+
+ssize_t TraceBuffer::DeleteNextChunksFor(size_t bytes_to_clear) {
+  PERFETTO_CHECK(!discard_writes_);
+
+  // Find the position of the first chunk which begins at or after
+  // (|wptr_| + |bytes|). Note that such a chunk might not exist and we might
+  // either reach the end of the buffer or a zeroed region of the buffer.
+  uint8_t* next_chunk_ptr = wptr_;
+  uint8_t* search_end = wptr_ + bytes_to_clear;
+  TRACE_BUFFER_DLOG("Delete [%zu %zu]", wptr_ - begin(), search_end - begin());
+  DcheckIsAlignedAndWithinBounds(wptr_);
+  PERFETTO_DCHECK(search_end <= end());
+  std::vector<ChunkMap::iterator> index_delete;
+  uint64_t chunks_overwritten = stats_.chunks_overwritten();
+  uint64_t bytes_overwritten = stats_.bytes_overwritten();
+  uint64_t padding_bytes_cleared = stats_.padding_bytes_cleared();
+  while (next_chunk_ptr < search_end) {
+    const ChunkRecord& next_chunk = *GetChunkRecordAt(next_chunk_ptr);
+    TRACE_BUFFER_DLOG(
+        "  scanning chunk [%zu %zu] (valid=%d)", next_chunk_ptr - begin(),
+        next_chunk_ptr - begin() + next_chunk.size, next_chunk.is_valid());
+
+    // We just reached the untouched part of the buffer, it's going to be all
+    // zeroes from here to end().
+    // Optimization: if during Initialize() we fill the buffer with padding
+    // records we could get rid of this branch.
+    if (PERFETTO_UNLIKELY(!next_chunk.is_valid())) {
+      // This should happen only at the first iteration. The zeroed area can
+      // only begin precisely at the |wptr_|, not after. Otherwise it means that
+      // we wrapped but screwed up the ChunkRecord chain.
+      PERFETTO_DCHECK(next_chunk_ptr == wptr_);
+      return 0;
+    }
+
+    // Remove |next_chunk| from the index, unless it's a padding record (padding
+    // records are not part of the index).
+    if (PERFETTO_LIKELY(!next_chunk.is_padding)) {
+      ChunkMeta::Key key(next_chunk);
+      auto it = index_.find(key);
+      bool will_remove = false;
+      if (PERFETTO_LIKELY(it != index_.end())) {
+        const ChunkMeta& meta = it->second;
+        if (PERFETTO_UNLIKELY(meta.num_fragments_read < meta.num_fragments)) {
+          if (overwrite_policy_ == kDiscard)
+            return -1;
+          chunks_overwritten++;
+          bytes_overwritten += next_chunk.size;
+        }
+        index_delete.push_back(it);
+        will_remove = true;
+      }
+      TRACE_BUFFER_DLOG(
+          "  del index {%" PRIu32 ",%" PRIu32 ",%u} @ [%" PRIdPTR " - %" PRIdPTR "] %d",
+          key.producer_id, key.writer_id, key.chunk_id,
+          next_chunk_ptr - begin(), next_chunk_ptr - begin() + next_chunk.size,
+          will_remove);
+      PERFETTO_DCHECK(will_remove);
+    } else {
+      padding_bytes_cleared += next_chunk.size;
+    }
+
+    next_chunk_ptr += next_chunk.size;
+
+    // We should never hit this, unless we managed to screw up while writing
+    // to the buffer and breaking the ChunkRecord(s) chain.
+    // TODO(primiano): Write more meaningful logging with the status of the
+    // buffer, to get more actionable bugs in case we hit this.
+    PERFETTO_CHECK(next_chunk_ptr <= end());
+  }
+
+  // Remove from the index.
+  for (auto it : index_delete) {
+    index_.erase(it);
+  }
+  stats_.set_chunks_overwritten(chunks_overwritten);
+  stats_.set_bytes_overwritten(bytes_overwritten);
+  stats_.set_padding_bytes_cleared(padding_bytes_cleared);
+
+  PERFETTO_DCHECK(next_chunk_ptr >= search_end && next_chunk_ptr <= end());
+  return static_cast<ssize_t>(next_chunk_ptr - search_end);
+}
+
+void TraceBuffer::AddPaddingRecord(size_t size) {
+  PERFETTO_DCHECK(size >= sizeof(ChunkRecord) && size <= ChunkRecord::kMaxSize);
+  ChunkRecord record(size);
+  record.is_padding = 1;
+  TRACE_BUFFER_DLOG("AddPaddingRecord @ [%" PRIdPTR " - %" PRIdPTR "] %zu", wptr_ - begin(),
+                    uintptr_t(wptr_ - begin()) + size, size);
+  WriteChunkRecord(wptr_, record, nullptr, size - sizeof(ChunkRecord));
+  stats_.set_padding_bytes_written(stats_.padding_bytes_written() + size);
+  // |wptr_| is deliberately not advanced when writing a padding record.
+}
+
+bool TraceBuffer::TryPatchChunkContents(ProducerID producer_id,
+                                        WriterID writer_id,
+                                        ChunkID chunk_id,
+                                        const Patch* patches,
+                                        size_t patches_size,
+                                        bool other_patches_pending) {
+  PERFETTO_CHECK(!read_only_);
+  ChunkMeta::Key key(producer_id, writer_id, chunk_id);
+  auto it = index_.find(key);
+  if (it == index_.end()) {
+    stats_.set_patches_failed(stats_.patches_failed() + 1);
+    return false;
+  }
+  ChunkMeta& chunk_meta = it->second;
+
+  // Check that the index is consistent with the actual ProducerID/WriterID
+  // stored in the ChunkRecord.
+
+  ChunkRecord* chunk_record = GetChunkRecordAt(begin() + chunk_meta.record_off);
+  PERFETTO_DCHECK(ChunkMeta::Key(*chunk_record) == key);
+  uint8_t* chunk_begin = reinterpret_cast<uint8_t*>(chunk_record);
+  PERFETTO_DCHECK(chunk_begin >= begin());
+  uint8_t* chunk_end = chunk_begin + chunk_record->size;
+  PERFETTO_DCHECK(chunk_end <= end());
+
+  static_assert(Patch::kSize == SharedMemoryABI::kPacketHeaderSize,
+                "Patch::kSize out of sync with SharedMemoryABI");
+
+  for (size_t i = 0; i < patches_size; i++) {
+    uint8_t* ptr =
+        chunk_begin + sizeof(ChunkRecord) + patches[i].offset_untrusted;
+    TRACE_BUFFER_DLOG("PatchChunk {%" PRIu32 ",%" PRIu32
+                      ",%u} size=%zu @ %zu with {%02x %02x %02x %02x} cur "
+                      "{%02x %02x %02x %02x}",
+                      producer_id, writer_id, chunk_id, chunk_end - chunk_begin,
+                      patches[i].offset_untrusted, patches[i].data[0],
+                      patches[i].data[1], patches[i].data[2],
+                      patches[i].data[3], ptr[0], ptr[1], ptr[2], ptr[3]);
+    if (ptr < chunk_begin + sizeof(ChunkRecord) ||
+        ptr > chunk_end - Patch::kSize) {
+      // Either the IPC was so slow and in the meantime the writer managed to
+      // wrap over |chunk_id| or the producer sent a malicious IPC.
+      stats_.set_patches_failed(stats_.patches_failed() + 1);
+      return false;
+    }
+
+    memcpy(ptr, &patches[i].data[0], Patch::kSize);
+  }
+  TRACE_BUFFER_DLOG("Chunk raw (after patch): %s",
+                    base::HexDump(chunk_begin, chunk_record->size).c_str());
+
+  stats_.set_patches_succeeded(stats_.patches_succeeded() + patches_size);
+  if (!other_patches_pending) {
+    chunk_meta.flags &= ~kChunkNeedsPatching;
+    chunk_record->flags = chunk_meta.flags & ChunkRecord::kFlagsBitMask;
+  }
+  return true;
+}
+
+void TraceBuffer::BeginRead() {
+  read_iter_ = GetReadIterForSequence(index_.begin());
+#if PERFETTO_DCHECK_IS_ON()
+  changed_since_last_read_ = false;
+#endif
+}
+
+TraceBuffer::SequenceIterator TraceBuffer::GetReadIterForSequence(
+    ChunkMap::iterator seq_begin) {
+  SequenceIterator iter;
+  iter.seq_begin = seq_begin;
+  if (seq_begin == index_.end()) {
+    iter.cur = iter.seq_end = index_.end();
+    return iter;
+  }
+
+#if PERFETTO_DCHECK_IS_ON()
+  // Either |seq_begin| is == index_.begin() or the item immediately before must
+  // belong to a different {ProducerID, WriterID} sequence.
+  if (seq_begin != index_.begin() && seq_begin != index_.end()) {
+    auto prev_it = seq_begin;
+    prev_it--;
+    PERFETTO_DCHECK(
+        seq_begin == index_.begin() ||
+        std::tie(prev_it->first.producer_id, prev_it->first.writer_id) <
+            std::tie(seq_begin->first.producer_id, seq_begin->first.writer_id));
+  }
+#endif
+
+  // Find the first entry that has a greater {ProducerID, WriterID} (or just
+  // index_.end() if we reached the end).
+  ChunkMeta::Key key = seq_begin->first;  // Deliberate copy.
+  key.chunk_id = kMaxChunkID;
+  iter.seq_end = index_.upper_bound(key);
+  PERFETTO_DCHECK(iter.seq_begin != iter.seq_end);
+
+  // Now find the first entry between [seq_begin, seq_end) that is
+  // > last_chunk_id_written_. This is where we the sequence will start (see
+  // notes about wrapping of IDs in the header).
+  auto producer_and_writer_id = std::make_pair(key.producer_id, key.writer_id);
+  PERFETTO_DCHECK(last_chunk_id_written_.count(producer_and_writer_id));
+  iter.wrapping_id = last_chunk_id_written_[producer_and_writer_id];
+  key.chunk_id = iter.wrapping_id;
+  iter.cur = index_.upper_bound(key);
+  if (iter.cur == iter.seq_end)
+    iter.cur = iter.seq_begin;
+  return iter;
+}
+
+void TraceBuffer::SequenceIterator::MoveNext() {
+  // Stop iterating when we reach the end of the sequence.
+  // Note: |seq_begin| might be == |seq_end|.
+  if (cur == seq_end || cur->first.chunk_id == wrapping_id) {
+    cur = seq_end;
+    return;
+  }
+
+  // If the current chunk wasn't completed yet, we shouldn't advance past it as
+  // it may be rewritten with additional packets.
+  if (!cur->second.is_complete()) {
+    cur = seq_end;
+    return;
+  }
+
+  ChunkID last_chunk_id = cur->first.chunk_id;
+  if (++cur == seq_end)
+    cur = seq_begin;
+
+  // There may be a missing chunk in the sequence of chunks, in which case the
+  // next chunk's ID won't follow the last one's. If so, skip the rest of the
+  // sequence. We'll return to it later once the hole is filled.
+  if (last_chunk_id + 1 != cur->first.chunk_id)
+    cur = seq_end;
+}
+
+bool TraceBuffer::ReadNextTracePacket(
+    TracePacket* packet,
+    PacketSequenceProperties* sequence_properties,
+    bool* previous_packet_on_sequence_dropped) {
+  // Note: MoveNext() moves only within the next chunk within the same
+  // {ProducerID, WriterID} sequence. Here we want to:
+  // - return the next patched+complete packet in the current sequence, if any.
+  // - return the first patched+complete packet in the next sequence, if any.
+  // - return false if none of the above is found.
+  TRACE_BUFFER_DLOG("ReadNextTracePacket()");
+
+  // Just in case we forget to initialize these below.
+  *sequence_properties = {0, ClientIdentity(), 0};
+  *previous_packet_on_sequence_dropped = false;
+
+  // At the start of each sequence iteration, we consider the last read packet
+  // dropped. While iterating over the chunks in the sequence, we update this
+  // flag based on our knowledge about the last packet that was read from each
+  // chunk (|last_read_packet_skipped| in ChunkMeta).
+  bool previous_packet_dropped = true;
+
+#if PERFETTO_DCHECK_IS_ON()
+  PERFETTO_DCHECK(!changed_since_last_read_);
+#endif
+  for (;; read_iter_.MoveNext()) {
+    if (PERFETTO_UNLIKELY(!read_iter_.is_valid())) {
+      // We ran out of chunks in the current {ProducerID, WriterID} sequence or
+      // we just reached the index_.end().
+
+      if (PERFETTO_UNLIKELY(read_iter_.seq_end == index_.end()))
+        return false;
+
+      // We reached the end of sequence, move to the next one.
+      // Note: ++read_iter_.seq_end might become index_.end(), but
+      // GetReadIterForSequence() knows how to deal with that.
+      read_iter_ = GetReadIterForSequence(read_iter_.seq_end);
+      PERFETTO_DCHECK(read_iter_.is_valid() && read_iter_.cur != index_.end());
+      previous_packet_dropped = true;
+    }
+
+    ChunkMeta* chunk_meta = &*read_iter_;
+
+    // If the chunk has holes that are awaiting to be patched out-of-band,
+    // skip the current sequence and move to the next one.
+    if (chunk_meta->flags & kChunkNeedsPatching) {
+      read_iter_.MoveToEnd();
+      continue;
+    }
+
+    const ProducerID trusted_producer_id = read_iter_.producer_id();
+    const WriterID writer_id = read_iter_.writer_id();
+    const ProducerAndWriterID producer_and_writer_id =
+        MkProducerAndWriterID(trusted_producer_id, writer_id);
+    const ClientIdentity& client_identity = chunk_meta->client_identity_trusted;
+
+    // At this point we have a chunk in |chunk_meta| that has not been fully
+    // read. We don't know yet whether we have enough data to read the full
+    // packet (in the case it's fragmented over several chunks) and we are about
+    // to find that out. Specifically:
+    // A) If the first fragment is unread and is a fragment continuing from a
+    //    previous chunk, it means we have missed the previous ChunkID. In
+    //    fact, if this wasn't the case, a previous call to ReadNext() shouldn't
+    //    have moved the cursor to this chunk.
+    // B) Any fragment > 0 && < last is always readable. By definition an inner
+    //    packet is never fragmented and hence doesn't require neither stitching
+    //    nor any out-of-band patching. The same applies to the last packet
+    //    iff it doesn't continue on the next chunk.
+    // C) If the last packet (which might be also the only packet in the chunk)
+    //    is a fragment and continues on the next chunk, we peek at the next
+    //    chunks and, if we have all of them, mark as read and move the cursor.
+    //
+    // +---------------+   +-------------------+  +---------------+
+    // | ChunkID: 1    |   | ChunkID: 2        |  | ChunkID: 3    |
+    // |---------------+   +-------------------+  +---------------+
+    // | Packet 1      |   |                   |  | ... Packet 3  |
+    // | Packet 2      |   | ... Packet 3  ... |  | Packet 4      |
+    // | Packet 3  ... |   |                   |  | Packet 5 ...  |
+    // +---------------+   +-------------------+  +---------------+
+
+    PERFETTO_DCHECK(chunk_meta->num_fragments_read <=
+                    chunk_meta->num_fragments);
+
+    // If we didn't read any packets from this chunk, the last packet was from
+    // the previous chunk we iterated over; so don't update
+    // |previous_packet_dropped| in this case.
+    if (chunk_meta->num_fragments_read > 0)
+      previous_packet_dropped = chunk_meta->last_read_packet_skipped();
+
+    while (chunk_meta->num_fragments_read < chunk_meta->num_fragments) {
+      enum { kSkip = 0, kReadOnePacket, kTryReadAhead } action;
+      if (chunk_meta->num_fragments_read == 0) {
+        if (chunk_meta->flags & kFirstPacketContinuesFromPrevChunk) {
+          action = kSkip;  // Case A.
+        } else if (chunk_meta->num_fragments == 1 &&
+                   (chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
+          action = kTryReadAhead;  // Case C.
+        } else {
+          action = kReadOnePacket;  // Case B.
+        }
+      } else if (chunk_meta->num_fragments_read <
+                     chunk_meta->num_fragments - 1 ||
+                 !(chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
+        action = kReadOnePacket;  // Case B.
+      } else {
+        action = kTryReadAhead;  // Case C.
+      }
+
+      TRACE_BUFFER_DLOG("  chunk %u, packet %hu of %hu, action=%d",
+                        read_iter_.chunk_id(), chunk_meta->num_fragments_read,
+                        chunk_meta->num_fragments, action);
+
+      if (action == kSkip) {
+        // This fragment will be skipped forever, not just in this ReadPacket()
+        // iteration. This happens by virtue of ReadNextPacketInChunk()
+        // incrementing the |num_fragments_read| and marking the fragment as
+        // read even if we didn't really.
+        ReadNextPacketInChunk(producer_and_writer_id, chunk_meta, nullptr);
+        chunk_meta->set_last_read_packet_skipped(true);
+        previous_packet_dropped = true;
+        continue;
+      }
+
+      if (action == kReadOnePacket) {
+        // The easy peasy case B.
+        ReadPacketResult result =
+            ReadNextPacketInChunk(producer_and_writer_id, chunk_meta, packet);
+
+        if (PERFETTO_LIKELY(result == ReadPacketResult::kSucceeded)) {
+          *sequence_properties = {trusted_producer_id, client_identity,
+                                  writer_id};
+          *previous_packet_on_sequence_dropped = previous_packet_dropped;
+          return true;
+        } else if (result == ReadPacketResult::kFailedEmptyPacket) {
+          // We can ignore and skip empty packets.
+          PERFETTO_DCHECK(packet->slices().empty());
+          continue;
+        }
+
+        // In extremely rare cases (producer bugged / malicious) the chunk might
+        // contain an invalid fragment. In such case we don't want to stall the
+        // sequence but just skip the chunk and move on. ReadNextPacketInChunk()
+        // marks the chunk as fully read, so we don't attempt to read from it
+        // again in a future call to ReadBuffers(). It also already records an
+        // abi violation for this.
+        PERFETTO_DCHECK(result == ReadPacketResult::kFailedInvalidPacket);
+        chunk_meta->set_last_read_packet_skipped(true);
+        previous_packet_dropped = true;
+        break;
+      }
+
+      PERFETTO_DCHECK(action == kTryReadAhead);
+      ReadAheadResult ra_res = ReadAhead(packet);
+      if (ra_res == ReadAheadResult::kSucceededReturnSlices) {
+        stats_.set_readaheads_succeeded(stats_.readaheads_succeeded() + 1);
+        *sequence_properties = {trusted_producer_id, client_identity,
+                                writer_id};
+        *previous_packet_on_sequence_dropped = previous_packet_dropped;
+        return true;
+      }
+
+      if (ra_res == ReadAheadResult::kFailedMoveToNextSequence) {
+        // readahead didn't find a contiguous packet sequence. We'll try again
+        // on the next ReadPacket() call.
+        stats_.set_readaheads_failed(stats_.readaheads_failed() + 1);
+
+        // TODO(primiano): optimization: this MoveToEnd() is the reason why
+        // MoveNext() (that is called in the outer for(;;MoveNext)) needs to
+        // deal gracefully with the case of |cur|==|seq_end|. Maybe we can do
+        // something to avoid that check by reshuffling the code here?
+        read_iter_.MoveToEnd();
+
+        // This break will go back to beginning of the for(;;MoveNext()). That
+        // will move to the next sequence because we set the read iterator to
+        // its end.
+        break;
+      }
+
+      PERFETTO_DCHECK(ra_res == ReadAheadResult::kFailedStayOnSameSequence);
+
+      // In this case ReadAhead() might advance |read_iter_|, so we need to
+      // re-cache the |chunk_meta| pointer to point to the current chunk.
+      chunk_meta = &*read_iter_;
+      chunk_meta->set_last_read_packet_skipped(true);
+      previous_packet_dropped = true;
+    }  // while(...)  [iterate over packet fragments for the current chunk].
+  }    // for(;;MoveNext()) [iterate over chunks].
+}
+
+TraceBuffer::ReadAheadResult TraceBuffer::ReadAhead(TracePacket* packet) {
+  static_assert(static_cast<ChunkID>(kMaxChunkID + 1) == 0,
+                "relying on kMaxChunkID to wrap naturally");
+  TRACE_BUFFER_DLOG(" readahead start @ chunk %u", read_iter_.chunk_id());
+  ChunkID next_chunk_id = read_iter_.chunk_id() + 1;
+  SequenceIterator it = read_iter_;
+  for (it.MoveNext(); it.is_valid(); it.MoveNext(), next_chunk_id++) {
+    // We should stay within the same sequence while iterating here.
+    PERFETTO_DCHECK(it.producer_id() == read_iter_.producer_id() &&
+                    it.writer_id() == read_iter_.writer_id());
+
+    TRACE_BUFFER_DLOG("   expected chunk ID: %u, actual ID: %u", next_chunk_id,
+                      it.chunk_id());
+
+    if (PERFETTO_UNLIKELY((*it).num_fragments == 0))
+      continue;
+
+    // If we miss the next chunk, stop looking in the current sequence and
+    // try another sequence. This chunk might come in the near future.
+    // The second condition is the edge case of a buggy/malicious
+    // producer. The ChunkID is contiguous but its flags don't make sense.
+    if (it.chunk_id() != next_chunk_id ||
+        PERFETTO_UNLIKELY(
+            !((*it).flags & kFirstPacketContinuesFromPrevChunk))) {
+      return ReadAheadResult::kFailedMoveToNextSequence;
+    }
+
+    // If the chunk is contiguous but has not been patched yet move to the next
+    // sequence and try coming back here on the next ReadNextTracePacket() call.
+    // TODO(primiano): add a test to cover this, it's a subtle case.
+    if ((*it).flags & kChunkNeedsPatching)
+      return ReadAheadResult::kFailedMoveToNextSequence;
+
+    // This is the case of an intermediate chunk which contains only one
+    // fragment which continues on the next chunk. This is the case for large
+    // packets, e.g.: [Packet0, Packet1(0)] [Packet1(1)] [Packet1(2), ...]
+    // (Packet1(X) := fragment X of Packet1).
+    if ((*it).num_fragments == 1 &&
+        ((*it).flags & kLastPacketContinuesOnNextChunk)) {
+      continue;
+    }
+
+    // We made it! We got all fragments for the packet without holes.
+    TRACE_BUFFER_DLOG("  readahead success @ chunk %u", it.chunk_id());
+    PERFETTO_DCHECK(((*it).num_fragments == 1 &&
+                     !((*it).flags & kLastPacketContinuesOnNextChunk)) ||
+                    (*it).num_fragments > 1);
+
+    // Now let's re-iterate over the [read_iter_, it] sequence and mark
+    // all the fragments as read.
+    bool packet_corruption = false;
+    for (;;) {
+      PERFETTO_DCHECK(read_iter_.is_valid());
+      TRACE_BUFFER_DLOG("    commit chunk %u", read_iter_.chunk_id());
+      if (PERFETTO_LIKELY((*read_iter_).num_fragments > 0)) {
+        // In the unlikely case of a corrupted packet (corrupted or empty
+        // fragment), invalidate the all stitching and move on to the next chunk
+        // in the same sequence, if any.
+        auto pw_id = MkProducerAndWriterID(it.producer_id(), it.writer_id());
+        packet_corruption |=
+            ReadNextPacketInChunk(pw_id, &*read_iter_, packet) ==
+            ReadPacketResult::kFailedInvalidPacket;
+      }
+      if (read_iter_.cur == it.cur)
+        break;
+      read_iter_.MoveNext();
+    }  // for(;;)
+    PERFETTO_DCHECK(read_iter_.cur == it.cur);
+
+    if (PERFETTO_UNLIKELY(packet_corruption)) {
+      // ReadNextPacketInChunk() already records an abi violation for this case.
+      *packet = TracePacket();  // clear.
+      return ReadAheadResult::kFailedStayOnSameSequence;
+    }
+
+    return ReadAheadResult::kSucceededReturnSlices;
+  }  // for(it...)  [readahead loop]
+  return ReadAheadResult::kFailedMoveToNextSequence;
+}
+
+TraceBuffer::ReadPacketResult TraceBuffer::ReadNextPacketInChunk(
+    ProducerAndWriterID producer_and_writer_id,
+    ChunkMeta* const chunk_meta,
+    TracePacket* packet) {
+  PERFETTO_DCHECK(chunk_meta->num_fragments_read < chunk_meta->num_fragments);
+  PERFETTO_DCHECK(!(chunk_meta->flags & kChunkNeedsPatching));
+
+  const uint8_t* record_begin = begin() + chunk_meta->record_off;
+  DcheckIsAlignedAndWithinBounds(record_begin);
+  auto* chunk_record = reinterpret_cast<const ChunkRecord*>(record_begin);
+  const uint8_t* record_end = record_begin + chunk_record->size;
+  const uint8_t* packets_begin = record_begin + sizeof(ChunkRecord);
+  const uint8_t* packet_begin = packets_begin + chunk_meta->cur_fragment_offset;
+
+  if (PERFETTO_UNLIKELY(packet_begin < packets_begin ||
+                        packet_begin >= record_end)) {
+    // The producer has a bug or is malicious and did declare that the chunk
+    // contains more packets beyond its boundaries.
+    stats_.set_abi_violations(stats_.abi_violations() + 1);
+    PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+    chunk_meta->cur_fragment_offset = 0;
+    chunk_meta->num_fragments_read = chunk_meta->num_fragments;
+    if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
+      stats_.set_chunks_read(stats_.chunks_read() + 1);
+      stats_.set_bytes_read(stats_.bytes_read() + chunk_record->size);
+    }
+    return ReadPacketResult::kFailedInvalidPacket;
+  }
+
+  // A packet (or a fragment) starts with a varint stating its size, followed
+  // by its content. The varint shouldn't be larger than 4 bytes (just in case
+  // the producer is using a redundant encoding)
+  uint64_t packet_size = 0;
+  const uint8_t* header_end =
+      std::min(packet_begin + protozero::proto_utils::kMessageLengthFieldSize,
+               record_end);
+  const uint8_t* packet_data = protozero::proto_utils::ParseVarInt(
+      packet_begin, header_end, &packet_size);
+
+  const uint8_t* next_packet = packet_data + packet_size;
+  if (PERFETTO_UNLIKELY(next_packet <= packet_begin ||
+                        next_packet > record_end)) {
+    // In BufferExhaustedPolicy::kDrop mode, TraceWriter may abort a fragmented
+    // packet by writing an invalid size in the last fragment's header. We
+    // should handle this case without recording an ABI violation (since Android
+    // R).
+    if (packet_size != SharedMemoryABI::kPacketSizeDropPacket) {
+      stats_.set_abi_violations(stats_.abi_violations() + 1);
+      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+    } else {
+      stats_.set_trace_writer_packet_loss(stats_.trace_writer_packet_loss() +
+                                          1);
+    }
+    chunk_meta->cur_fragment_offset = 0;
+    chunk_meta->num_fragments_read = chunk_meta->num_fragments;
+    if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
+      stats_.set_chunks_read(stats_.chunks_read() + 1);
+      stats_.set_bytes_read(stats_.bytes_read() + chunk_record->size);
+    }
+    return ReadPacketResult::kFailedInvalidPacket;
+  }
+
+  chunk_meta->cur_fragment_offset =
+      static_cast<uint16_t>(next_packet - packets_begin);
+  chunk_meta->num_fragments_read++;
+
+  if (PERFETTO_UNLIKELY(chunk_meta->num_fragments_read ==
+                            chunk_meta->num_fragments &&
+                        chunk_meta->is_complete())) {
+    stats_.set_chunks_read(stats_.chunks_read() + 1);
+    stats_.set_bytes_read(stats_.bytes_read() + chunk_record->size);
+    auto* writer_stats = writer_stats_.Insert(producer_and_writer_id, {}).first;
+    writer_stats->used_chunk_hist.Add(chunk_meta->cur_fragment_offset);
+  } else {
+    // We have at least one more packet to parse. It should be within the chunk.
+    if (chunk_meta->cur_fragment_offset + sizeof(ChunkRecord) >=
+        chunk_record->size) {
+      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
+    }
+  }
+
+  chunk_meta->set_last_read_packet_skipped(false);
+
+  if (PERFETTO_UNLIKELY(packet_size == 0))
+    return ReadPacketResult::kFailedEmptyPacket;
+
+  if (PERFETTO_LIKELY(packet))
+    packet->AddSlice(packet_data, static_cast<size_t>(packet_size));
+
+  return ReadPacketResult::kSucceeded;
+}
+
+void TraceBuffer::DiscardWrite() {
+  PERFETTO_DCHECK(overwrite_policy_ == kDiscard);
+  discard_writes_ = true;
+  stats_.set_chunks_discarded(stats_.chunks_discarded() + 1);
+  TRACE_BUFFER_DLOG("  discarding write");
+}
+
+std::unique_ptr<TraceBuffer> TraceBuffer::CloneReadOnly() const {
+  std::unique_ptr<TraceBuffer> buf(new TraceBuffer(CloneCtor(), *this));
+  if (!buf->data_.IsValid())
+    return nullptr;  // PagedMemory::Allocate() failed. We are out of memory.
+  return buf;
+}
+
+TraceBuffer::TraceBuffer(CloneCtor, const TraceBuffer& src)
+    : overwrite_policy_(src.overwrite_policy_),
+      read_only_(true),
+      discard_writes_(src.discard_writes_) {
+  if (!Initialize(src.data_.size()))
+    return;  // TraceBuffer::Clone() will check |data_| and return nullptr.
+
+  // The assignments below must be done after Initialize().
+
+  EnsureCommitted(src.used_size_);
+  memcpy(data_.Get(), src.data_.Get(), src.used_size_);
+  last_chunk_id_written_ = src.last_chunk_id_written_;
+
+  stats_ = src.stats_;
+  stats_.set_bytes_read(0);
+  stats_.set_chunks_read(0);
+  stats_.set_readaheads_failed(0);
+  stats_.set_readaheads_succeeded(0);
+
+  // Copy the index of chunk metadata and reset the read states.
+  index_ = ChunkMap(src.index_);
+  for (auto& kv : index_) {
+    ChunkMeta& chunk_meta = kv.second;
+    chunk_meta.num_fragments_read = 0;
+    chunk_meta.cur_fragment_offset = 0;
+    chunk_meta.set_last_read_packet_skipped(false);
+  }
+  read_iter_ = SequenceIterator();
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/core/tracing_service_impl.cc
+// gen_amalgamated begin header: src/tracing/core/tracing_service_impl.h
+// gen_amalgamated begin header: include/perfetto/ext/base/circular_queue.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
+#define INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <cstddef>
+#include <iterator>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace base {
+
+// CircularQueue is a push-back-only / pop-front-only queue with the following
+// characteristics:
+// - The storage is based on a flat circular buffer. Beginning and end wrap
+//   as necessary, to keep pushes and pops O(1) as long as capacity expansion is
+//   not required.
+// - Capacity is automatically expanded like in a std::vector. Expansion has a
+//   O(N) cost.
+// - It allows random access, allowing in-place std::sort.
+// - Iterators are not stable. Mutating the container invalidates all iterators.
+// - It doesn't bother with const-correctness.
+//
+// Implementation details:
+// Internally, |begin|, |end| and iterators use 64-bit monotonic indexes, which
+// are incremented as if the queue was backed by unlimited storage.
+// Even assuming that elements are inserted and removed every nanosecond, 64 bit
+// is enough for 584 years.
+// Wrapping happens only when addressing elements in the underlying circular
+// storage. This limits the complexity and avoiding dealing with modular
+// arithmetic all over the places.
+template <class T>
+class CircularQueue {
+ public:
+  class Iterator {
+   public:
+    using difference_type = ptrdiff_t;
+    using value_type = T;
+    using pointer = T*;
+    using reference = T&;
+    using iterator_category = std::random_access_iterator_tag;
+
+    Iterator(CircularQueue* queue, uint64_t pos, uint32_t generation)
+        : queue_(queue),
+          pos_(pos)
+#if PERFETTO_DCHECK_IS_ON()
+          ,
+          generation_(generation)
+#endif
+    {
+      ignore_result(generation);
+    }
+
+    Iterator(const Iterator&) noexcept = default;
+    Iterator& operator=(const Iterator&) noexcept = default;
+    Iterator(Iterator&&) noexcept = default;
+    Iterator& operator=(Iterator&&) noexcept = default;
+
+    T* operator->() const {
+#if PERFETTO_DCHECK_IS_ON()
+      PERFETTO_DCHECK(generation_ == queue_->generation());
+#endif
+      return queue_->Get(pos_);
+    }
+
+    T& operator*() const { return *(operator->()); }
+
+    value_type& operator[](difference_type i) { return *(*this + i); }
+
+    Iterator& operator++() {
+      Add(1);
+      return *this;
+    }
+
+    Iterator operator++(int) {
+      Iterator ret = *this;
+      Add(1);
+      return ret;
+    }
+
+    Iterator& operator--() {
+      Add(-1);
+      return *this;
+    }
+
+    Iterator operator--(int) {
+      Iterator ret = *this;
+      Add(-1);
+      return ret;
+    }
+
+    friend Iterator operator+(const Iterator& iter, difference_type offset) {
+      Iterator ret = iter;
+      ret.Add(offset);
+      return ret;
+    }
+
+    Iterator& operator+=(difference_type offset) {
+      Add(offset);
+      return *this;
+    }
+
+    friend Iterator operator-(const Iterator& iter, difference_type offset) {
+      Iterator ret = iter;
+      ret.Add(-offset);
+      return ret;
+    }
+
+    Iterator& operator-=(difference_type offset) {
+      Add(-offset);
+      return *this;
+    }
+
+    friend ptrdiff_t operator-(const Iterator& lhs, const Iterator& rhs) {
+      return static_cast<ptrdiff_t>(lhs.pos_) -
+             static_cast<ptrdiff_t>(rhs.pos_);
+    }
+
+    friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ == rhs.pos_;
+    }
+
+    friend bool operator!=(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ != rhs.pos_;
+    }
+
+    friend bool operator<(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ < rhs.pos_;
+    }
+
+    friend bool operator<=(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ <= rhs.pos_;
+    }
+
+    friend bool operator>(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ > rhs.pos_;
+    }
+
+    friend bool operator>=(const Iterator& lhs, const Iterator& rhs) {
+      return lhs.pos_ >= rhs.pos_;
+    }
+
+   private:
+    inline void Add(difference_type offset) {
+      pos_ = static_cast<uint64_t>(static_cast<difference_type>(pos_) + offset);
+      PERFETTO_DCHECK(pos_ <= queue_->end_);
+    }
+
+    CircularQueue* queue_;
+    uint64_t pos_;
+
+#if PERFETTO_DCHECK_IS_ON()
+    uint32_t generation_;
+#endif
+  };
+
+  explicit CircularQueue(size_t initial_capacity = 1024) {
+    Grow(initial_capacity);
+  }
+
+  CircularQueue(CircularQueue&& other) noexcept
+      : entries_(std::move(other.entries_)),
+        capacity_(other.capacity_),
+        begin_(other.begin_),
+        end_(other.end_) {
+    increment_generation();
+    new (&other) CircularQueue();  // Reset the old queue so it's still usable.
+  }
+
+  CircularQueue& operator=(CircularQueue&& other) noexcept {
+    this->~CircularQueue();                      // Destroy the current state.
+    new (this) CircularQueue(std::move(other));  // Use the move ctor above.
+    return *this;
+  }
+
+  explicit CircularQueue(const CircularQueue& other) noexcept {
+    Grow(other.capacity());
+    for (const auto& e : const_cast<CircularQueue&>(other))
+      emplace_back(e);
+    PERFETTO_DCHECK(size() == other.size());
+  }
+
+  CircularQueue& operator=(const CircularQueue& other) noexcept {
+    this->~CircularQueue();           // Destroy the current state.
+    new (this) CircularQueue(other);  // Use the copy ctor above.
+    return *this;
+  }
+
+  ~CircularQueue() {
+    if (!entries_) {
+      PERFETTO_DCHECK(empty());
+      return;
+    }
+    clear();  // Invoke destructors on all alive entries.
+    PERFETTO_DCHECK(empty());
+  }
+
+  template <typename... Args>
+  void emplace_back(Args&&... args) {
+    increment_generation();
+    if (PERFETTO_UNLIKELY(size() >= capacity_))
+      Grow();
+    T* slot = Get(end_++);
+    new (slot) T(std::forward<Args>(args)...);
+  }
+
+  void erase_front(size_t n) {
+    increment_generation();
+    for (; n && (begin_ < end_); --n) {
+      Get(begin_)->~T();
+      begin_++;  // This needs to be its own statement, Get() checks begin_.
+    }
+  }
+
+  void pop_front() { erase_front(1); }
+
+  void clear() { erase_front(size()); }
+
+  void shrink_to_fit() {
+    // We only bother shrinking if we can fit in quarter of the capacity we are
+    // currently using. Moreover, don't bother shrinking below 4096 elements as
+    // that will cause a lot of reallocations for little benefit.
+    if (size() > capacity() / 2 || capacity() <= 4096) {
+      return;
+    }
+    ChangeCapacity(capacity() / 2);
+  }
+
+  T& at(size_t idx) {
+    PERFETTO_DCHECK(idx < size());
+    return *Get(begin_ + idx);
+  }
+
+  Iterator begin() { return Iterator(this, begin_, generation()); }
+  Iterator end() { return Iterator(this, end_, generation()); }
+  T& front() { return *begin(); }
+  T& back() { return *(end() - 1); }
+
+  bool empty() const { return size() == 0; }
+
+  size_t size() const {
+    PERFETTO_DCHECK(end_ - begin_ <= capacity_);
+    return static_cast<size_t>(end_ - begin_);
+  }
+
+  size_t capacity() const { return capacity_; }
+
+#if PERFETTO_DCHECK_IS_ON()
+  uint32_t generation() const { return generation_; }
+  void increment_generation() { ++generation_; }
+#else
+  uint32_t generation() const { return 0; }
+  void increment_generation() {}
+#endif
+
+ private:
+  void Grow(size_t new_capacity = 0) {
+    // Capacity must be always a power of two. This allows Get() to use a simple
+    // bitwise-AND for handling the wrapping instead of a full division.
+    new_capacity = new_capacity ? new_capacity : capacity_ * 2;
+    PERFETTO_CHECK((new_capacity & (new_capacity - 1)) == 0);  // Must be pow2.
+
+    // On 32-bit systems this might hit the 4GB wall and overflow. We can't do
+    // anything other than crash in this case.
+    PERFETTO_CHECK(new_capacity > capacity_);
+
+    ChangeCapacity(new_capacity);
+  }
+
+  void ChangeCapacity(size_t new_capacity) {
+    // We should still have enough space to fit all the elements in the queue.
+    PERFETTO_CHECK(new_capacity >= size());
+
+    AlignedUniquePtr<T[]> new_vec = AlignedAllocTyped<T[]>(new_capacity);
+
+    // Move all elements in the expanded array.
+    size_t new_size = 0;
+    for (uint64_t i = begin_; i < end_; i++)
+      new (&new_vec[new_size++]) T(std::move(*Get(i)));  // Placement move ctor.
+
+    // Even if all the elements are std::move()-d and likely empty, we are still
+    // required to call the dtor for them.
+    for (uint64_t i = begin_; i < end_; i++)
+      Get(i)->~T();
+
+    begin_ = 0;
+    end_ = new_size;
+    capacity_ = new_capacity;
+    entries_ = std::move(new_vec);
+  }
+
+  inline T* Get(uint64_t pos) {
+    PERFETTO_DCHECK(pos >= begin_ && pos < end_);
+    PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
+    auto index = static_cast<size_t>(pos & (capacity_ - 1));
+    return &entries_[index];
+  }
+
+  // Underlying storage. It's raw malloc-ed rather than being a unique_ptr<T[]>
+  // to allow having uninitialized entries inside it.
+  AlignedUniquePtr<T[]> entries_;
+  size_t capacity_ = 0;  // Number of allocated slots (NOT bytes) in |entries_|.
+
+  // The |begin_| and |end_| indexes are monotonic and never wrap. Modular arith
+  // is used only when dereferencing entries in the vector.
+  uint64_t begin_ = 0;
+  uint64_t end_ = 0;
+
+// Generation is used in debug builds only for checking iterator validity.
+#if PERFETTO_DCHECK_IS_ON()
+  uint32_t generation_ = 0;
+#endif
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
+#define SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
+
+#include <algorithm>
+#include <functional>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <optional>
+#include <random>
+#include <set>
+#include <utility>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/status.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/circular_queue.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "src/android_stats/perfetto_atoms.h"
+// gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
+
+namespace protozero {
+class MessageFilter;
+}
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace protos {
+namespace gen {
+enum TraceStats_FinalFlushOutcome : int;
+}
+}  // namespace protos
+
+class Consumer;
+class Producer;
+class SharedMemory;
+class SharedMemoryArbiterImpl;
+class TraceBuffer;
+class TracePacket;
+
+// The tracing service business logic.
+class TracingServiceImpl : public TracingService {
+ private:
+  struct DataSourceInstance;
+
+ public:
+  static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
+  static constexpr uint32_t kDataSourceStopTimeoutMs = 5000;
+  static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d,
+                                            0x42, 0xba, 0x81, 0xdc, 0x33, 0x32,
+                                            0x6d, 0x57, 0xa0, 0x79};
+  static constexpr size_t kMaxTracePacketSliceSize =
+      128 * 1024 - 512;  // This is ipc::kIPCBufferSize - 512, see assertion in
+                         // tracing_integration_test.cc and b/195065199
+
+  // This is a rough threshold to determine how many bytes to read from the
+  // buffers on each iteration when writing into a file. Since filtering and
+  // compression allocate memory, this effectively limits the amount of memory
+  // allocated.
+  static constexpr size_t kWriteIntoFileChunkSize = 1024 * 1024ul;
+
+  // The implementation behind the service endpoint exposed to each producer.
+  class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
+   public:
+    ProducerEndpointImpl(ProducerID,
+                         const ClientIdentity& client_identity,
+                         TracingServiceImpl*,
+                         base::TaskRunner*,
+                         Producer*,
+                         const std::string& producer_name,
+                         const std::string& sdk_version,
+                         bool in_process,
+                         bool smb_scraping_enabled);
+    ~ProducerEndpointImpl() override;
+
+    // TracingService::ProducerEndpoint implementation.
+    void Disconnect() override;
+    void RegisterDataSource(const DataSourceDescriptor&) override;
+    void UpdateDataSource(const DataSourceDescriptor&) override;
+    void UnregisterDataSource(const std::string& name) override;
+    void RegisterTraceWriter(uint32_t writer_id,
+                             uint32_t target_buffer) override;
+    void UnregisterTraceWriter(uint32_t writer_id) override;
+    void CommitData(const CommitDataRequest&, CommitDataCallback) override;
+    void SetupSharedMemory(std::unique_ptr<SharedMemory>,
+                           size_t page_size_bytes,
+                           bool provided_by_producer);
+    std::unique_ptr<TraceWriter> CreateTraceWriter(
+        BufferID,
+        BufferExhaustedPolicy) override;
+    SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
+    bool IsShmemProvidedByProducer() const override;
+    void NotifyFlushComplete(FlushRequestID) override;
+    void NotifyDataSourceStarted(DataSourceInstanceID) override;
+    void NotifyDataSourceStopped(DataSourceInstanceID) override;
+    SharedMemory* shared_memory() const override;
+    size_t shared_buffer_page_size_kb() const override;
+    void ActivateTriggers(const std::vector<std::string>&) override;
+    void Sync(std::function<void()> callback) override;
+
+    void OnTracingSetup();
+    void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&);
+    void StartDataSource(DataSourceInstanceID, const DataSourceConfig&);
+    void StopDataSource(DataSourceInstanceID);
+    void Flush(FlushRequestID,
+               const std::vector<DataSourceInstanceID>&,
+               FlushFlags);
+    void OnFreeBuffers(const std::vector<BufferID>& target_buffers);
+    void ClearIncrementalState(const std::vector<DataSourceInstanceID>&);
+
+    bool is_allowed_target_buffer(BufferID buffer_id) const {
+      return allowed_target_buffers_.count(buffer_id);
+    }
+
+    std::optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
+      const auto it = writers_.find(writer_id);
+      if (it != writers_.end())
+        return it->second;
+      return std::nullopt;
+    }
+
+    uid_t uid() const { return client_identity_.uid(); }
+    pid_t pid() const { return client_identity_.pid(); }
+    const ClientIdentity& client_identity() const { return client_identity_; }
+
+   private:
+    friend class TracingServiceImpl;
+    friend class TracingServiceImplTest;
+    friend class TracingIntegrationTest;
+    ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
+    ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
+
+    ProducerID const id_;
+    ClientIdentity const client_identity_;
+    TracingServiceImpl* const service_;
+    base::TaskRunner* const task_runner_;
+    Producer* producer_;
+    std::unique_ptr<SharedMemory> shared_memory_;
+    size_t shared_buffer_page_size_kb_ = 0;
+    SharedMemoryABI shmem_abi_;
+    size_t shmem_size_hint_bytes_ = 0;
+    size_t shmem_page_size_hint_bytes_ = 0;
+    bool is_shmem_provided_by_producer_ = false;
+    const std::string name_;
+    std::string sdk_version_;
+    bool in_process_;
+    bool smb_scraping_enabled_;
+
+    // Set of the global target_buffer IDs that the producer is configured to
+    // write into in any active tracing session.
+    std::set<BufferID> allowed_target_buffers_;
+
+    // Maps registered TraceWriter IDs to their target buffers as registered by
+    // the producer. Note that producers aren't required to register their
+    // writers, so we may see commits of chunks with WriterIDs that aren't
+    // contained in this map. However, if a producer does register a writer, the
+    // service will prevent the writer from writing into any other buffer than
+    // the one associated with it here. The BufferIDs stored in this map are
+    // untrusted, so need to be verified against |allowed_target_buffers_|
+    // before use.
+    std::map<WriterID, BufferID> writers_;
+
+    // This is used only in in-process configurations.
+    // SharedMemoryArbiterImpl methods themselves are thread-safe.
+    std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;
+
+    PERFETTO_THREAD_CHECKER(thread_checker_)
+    base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_;  // Keep last.
+  };
+
+  // The implementation behind the service endpoint exposed to each consumer.
+  class ConsumerEndpointImpl : public TracingService::ConsumerEndpoint {
+   public:
+    ConsumerEndpointImpl(TracingServiceImpl*,
+                         base::TaskRunner*,
+                         Consumer*,
+                         uid_t uid);
+    ~ConsumerEndpointImpl() override;
+
+    void NotifyOnTracingDisabled(const std::string& error);
+    void NotifyCloneSnapshotTrigger();
+
+    // TracingService::ConsumerEndpoint implementation.
+    void EnableTracing(const TraceConfig&, base::ScopedFile) override;
+    void ChangeTraceConfig(const TraceConfig& cfg) override;
+    void StartTracing() override;
+    void DisableTracing() override;
+    void ReadBuffers() override;
+    void FreeBuffers() override;
+    void Flush(uint32_t timeout_ms, FlushCallback, FlushFlags) override;
+    void Detach(const std::string& key) override;
+    void Attach(const std::string& key) override;
+    void GetTraceStats() override;
+    void ObserveEvents(uint32_t enabled_event_types) override;
+    void QueryServiceState(QueryServiceStateCallback) override;
+    void QueryCapabilities(QueryCapabilitiesCallback) override;
+    void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
+    void CloneSession(TracingSessionID) override;
+
+    // Will queue a task to notify the consumer about the state change.
+    void OnDataSourceInstanceStateChange(const ProducerEndpointImpl&,
+                                         const DataSourceInstance&);
+    void OnAllDataSourcesStarted();
+
+    base::WeakPtr<ConsumerEndpointImpl> GetWeakPtr() {
+      return weak_ptr_factory_.GetWeakPtr();
+    }
+
+   private:
+    friend class TracingServiceImpl;
+    ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
+    ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
+
+    // Returns a pointer to an ObservableEvents object that the caller can fill
+    // and schedules a task to send the ObservableEvents to the consumer.
+    ObservableEvents* AddObservableEvents();
+
+    base::TaskRunner* const task_runner_;
+    TracingServiceImpl* const service_;
+    Consumer* const consumer_;
+    uid_t const uid_;
+    TracingSessionID tracing_session_id_ = 0;
+
+    // Whether the consumer is interested in DataSourceInstance state change
+    // events.
+    uint32_t observable_events_mask_ = 0;
+
+    // ObservableEvents that will be sent to the consumer. If set, a task to
+    // flush the events to the consumer has been queued.
+    std::unique_ptr<ObservableEvents> observable_events_;
+
+    PERFETTO_THREAD_CHECKER(thread_checker_)
+    base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_;  // Keep last.
+  };
+
+  explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>,
+                              base::TaskRunner*,
+                              InitOpts = {});
+  ~TracingServiceImpl() override;
+
+  // Called by ProducerEndpointImpl.
+  void DisconnectProducer(ProducerID);
+  void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
+  void UpdateDataSource(ProducerID, const DataSourceDescriptor&);
+  void UnregisterDataSource(ProducerID, const std::string& name);
+  void CopyProducerPageIntoLogBuffer(ProducerID,
+                                     const ClientIdentity&,
+                                     WriterID,
+                                     ChunkID,
+                                     BufferID,
+                                     uint16_t num_fragments,
+                                     uint8_t chunk_flags,
+                                     bool chunk_complete,
+                                     const uint8_t* src,
+                                     size_t size);
+  void ApplyChunkPatches(ProducerID,
+                         const std::vector<CommitDataRequest::ChunkToPatch>&);
+  void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
+  void NotifyDataSourceStarted(ProducerID, const DataSourceInstanceID);
+  void NotifyDataSourceStopped(ProducerID, const DataSourceInstanceID);
+  void ActivateTriggers(ProducerID, const std::vector<std::string>& triggers);
+
+  // Called by ConsumerEndpointImpl.
+  bool DetachConsumer(ConsumerEndpointImpl*, const std::string& key);
+  bool AttachConsumer(ConsumerEndpointImpl*, const std::string& key);
+  void DisconnectConsumer(ConsumerEndpointImpl*);
+  base::Status EnableTracing(ConsumerEndpointImpl*,
+                             const TraceConfig&,
+                             base::ScopedFile);
+  void ChangeTraceConfig(ConsumerEndpointImpl*, const TraceConfig&);
+
+  base::Status StartTracing(TracingSessionID);
+  void DisableTracing(TracingSessionID, bool disable_immediately = false);
+  void Flush(TracingSessionID tsid,
+             uint32_t timeout_ms,
+             ConsumerEndpoint::FlushCallback,
+             FlushFlags);
+  void FlushAndDisableTracing(TracingSessionID);
+  void FlushAndCloneSession(ConsumerEndpointImpl*, TracingSessionID);
+
+  // Starts reading the internal tracing buffers from the tracing session `tsid`
+  // and sends them to `*consumer` (which must be != nullptr).
+  //
+  // Only reads a limited amount of data in one call. If there's more data,
+  // immediately schedules itself on a PostTask.
+  //
+  // Returns false in case of error.
+  bool ReadBuffersIntoConsumer(TracingSessionID tsid,
+                               ConsumerEndpointImpl* consumer);
+
+  // Reads all the tracing buffers from the tracing session `tsid` and writes
+  // them into the associated file.
+  //
+  // Reads all the data in the buffers (or until the file is full) before
+  // returning.
+  //
+  // If the tracing session write_period_ms is 0, the file is full or there has
+  // been an error, flushes the file and closes it. Otherwise, schedules itself
+  // to be executed after write_period_ms.
+  //
+  // Returns false in case of error.
+  bool ReadBuffersIntoFile(TracingSessionID);
+
+  void FreeBuffers(TracingSessionID);
+
+  // Service implementation.
+  std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
+      Producer*,
+      const ClientIdentity& client_identity,
+      const std::string& producer_name,
+      size_t shared_memory_size_hint_bytes = 0,
+      bool in_process = false,
+      ProducerSMBScrapingMode smb_scraping_mode =
+          ProducerSMBScrapingMode::kDefault,
+      size_t shared_memory_page_size_hint_bytes = 0,
+      std::unique_ptr<SharedMemory> shm = nullptr,
+      const std::string& sdk_version = {}) override;
+
+  std::unique_ptr<TracingService::ConsumerEndpoint> ConnectConsumer(
+      Consumer*,
+      uid_t) override;
+
+  // Set whether SMB scraping should be enabled by default or not. Producers can
+  // override this setting for their own SMBs.
+  void SetSMBScrapingEnabled(bool enabled) override {
+    smb_scraping_enabled_ = enabled;
+  }
+
+  // Exposed mainly for testing.
+  size_t num_producers() const { return producers_.size(); }
+  ProducerEndpointImpl* GetProducer(ProducerID) const;
+
+ private:
+  friend class TracingServiceImplTest;
+  friend class TracingIntegrationTest;
+
+  static constexpr int64_t kOneDayInNs = 24ll * 60 * 60 * 1000 * 1000 * 1000;
+
+  struct TriggerHistory {
+    int64_t timestamp_ns;
+    uint64_t name_hash;
+
+    bool operator<(const TriggerHistory& other) const {
+      return timestamp_ns < other.timestamp_ns;
+    }
+  };
+
+  struct RegisteredDataSource {
+    ProducerID producer_id;
+    DataSourceDescriptor descriptor;
+  };
+
+  // Represents an active data source for a tracing session.
+  struct DataSourceInstance {
+    DataSourceInstance(DataSourceInstanceID id,
+                       const DataSourceConfig& cfg,
+                       const std::string& ds_name,
+                       bool notify_on_start,
+                       bool notify_on_stop,
+                       bool handles_incremental_state_invalidation,
+                       bool no_flush_)
+        : instance_id(id),
+          config(cfg),
+          data_source_name(ds_name),
+          will_notify_on_start(notify_on_start),
+          will_notify_on_stop(notify_on_stop),
+          handles_incremental_state_clear(
+              handles_incremental_state_invalidation),
+          no_flush(no_flush_) {}
+    DataSourceInstance(const DataSourceInstance&) = delete;
+    DataSourceInstance& operator=(const DataSourceInstance&) = delete;
+
+    DataSourceInstanceID instance_id;
+    DataSourceConfig config;
+    std::string data_source_name;
+    bool will_notify_on_start;
+    bool will_notify_on_stop;
+    bool handles_incremental_state_clear;
+    bool no_flush;
+
+    enum DataSourceInstanceState {
+      CONFIGURED,
+      STARTING,
+      STARTED,
+      STOPPING,
+      STOPPED
+    };
+    DataSourceInstanceState state = CONFIGURED;
+  };
+
+  struct PendingFlush {
+    std::set<ProducerID> producers;
+    ConsumerEndpoint::FlushCallback callback;
+    explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
+  };
+
+  // Holds the state of a tracing session. A tracing session is uniquely bound
+  // a specific Consumer. Each Consumer can own one or more sessions.
+  struct TracingSession {
+    enum State {
+      DISABLED = 0,
+      CONFIGURED,
+      STARTED,
+      DISABLING_WAITING_STOP_ACKS,
+      CLONED_READ_ONLY,
+    };
+
+    TracingSession(TracingSessionID,
+                   ConsumerEndpointImpl*,
+                   const TraceConfig&,
+                   base::TaskRunner*);
+    TracingSession(TracingSession&&) = delete;
+    TracingSession& operator=(TracingSession&&) = delete;
+
+    size_t num_buffers() const { return buffers_index.size(); }
+
+    uint32_t delay_to_next_write_period_ms() const {
+      PERFETTO_DCHECK(write_period_ms > 0);
+      return write_period_ms -
+             static_cast<uint32_t>(base::GetWallTimeMs().count() %
+                                   write_period_ms);
+    }
+
+    uint32_t flush_timeout_ms() {
+      uint32_t timeout_ms = config.flush_timeout_ms();
+      return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs;
+    }
+
+    uint32_t data_source_stop_timeout_ms() {
+      uint32_t timeout_ms = config.data_source_stop_timeout_ms();
+      return timeout_ms ? timeout_ms : kDataSourceStopTimeoutMs;
+    }
+
+    PacketSequenceID GetPacketSequenceID(MachineID machine_id,
+                                         ProducerID producer_id,
+                                         WriterID writer_id) {
+      auto key = std::make_tuple(machine_id, producer_id, writer_id);
+      auto it = packet_sequence_ids.find(key);
+      if (it != packet_sequence_ids.end())
+        return it->second;
+      // We shouldn't run out of sequence IDs (producer ID is 16 bit, writer IDs
+      // are limited to 1024).
+      static_assert(kMaxPacketSequenceID > kMaxProducerID * kMaxWriterID,
+                    "PacketSequenceID value space doesn't cover service "
+                    "sequence ID and all producer/writer ID combinations!");
+      PERFETTO_DCHECK(last_packet_sequence_id < kMaxPacketSequenceID);
+      PacketSequenceID sequence_id = ++last_packet_sequence_id;
+      packet_sequence_ids[key] = sequence_id;
+      return sequence_id;
+    }
+
+    DataSourceInstance* GetDataSourceInstance(
+        ProducerID producer_id,
+        DataSourceInstanceID instance_id) {
+      for (auto& inst_kv : data_source_instances) {
+        if (inst_kv.first != producer_id ||
+            inst_kv.second.instance_id != instance_id) {
+          continue;
+        }
+        return &inst_kv.second;
+      }
+      return nullptr;
+    }
+
+    bool AllDataSourceInstancesStarted() {
+      return std::all_of(
+          data_source_instances.begin(), data_source_instances.end(),
+          [](decltype(data_source_instances)::const_reference x) {
+            return x.second.state == DataSourceInstance::STARTED;
+          });
+    }
+
+    bool AllDataSourceInstancesStopped() {
+      return std::all_of(
+          data_source_instances.begin(), data_source_instances.end(),
+          [](decltype(data_source_instances)::const_reference x) {
+            return x.second.state == DataSourceInstance::STOPPED;
+          });
+    }
+
+    const TracingSessionID id;
+
+    // The consumer that started the session.
+    // Can be nullptr if the consumer detached from the session.
+    ConsumerEndpointImpl* consumer_maybe_null;
+
+    // Unix uid of the consumer. This is valid even after the consumer detaches
+    // and does not change for the entire duration of the session. It is used to
+    // prevent that a consumer re-attaches to a session from a different uid.
+    uid_t const consumer_uid;
+
+    // The list of triggers this session received while alive and the time they
+    // were received at. This is used to insert 'fake' packets back to the
+    // consumer so they can tell when some event happened. The order matches the
+    // order they were received.
+    struct TriggerInfo {
+      uint64_t boot_time_ns;
+      std::string trigger_name;
+      std::string producer_name;
+      uid_t producer_uid;
+    };
+    std::vector<TriggerInfo> received_triggers;
+
+    // The trace config provided by the Consumer when calling
+    // EnableTracing(), plus any updates performed by ChangeTraceConfig.
+    TraceConfig config;
+
+    // List of data source instances that have been enabled on the various
+    // producers for this tracing session.
+    std::multimap<ProducerID, DataSourceInstance> data_source_instances;
+
+    // For each Flush(N) request, keeps track of the set of producers for which
+    // we are still awaiting a NotifyFlushComplete(N) ack.
+    std::map<FlushRequestID, PendingFlush> pending_flushes;
+
+    // Maps a per-trace-session buffer index into the corresponding global
+    // BufferID (shared namespace amongst all consumers). This vector has as
+    // many entries as |config.buffers_size()|.
+    std::vector<BufferID> buffers_index;
+
+    std::map<std::tuple<MachineID, ProducerID, WriterID>, PacketSequenceID>
+        packet_sequence_ids;
+    PacketSequenceID last_packet_sequence_id = kServicePacketSequenceID;
+
+    // Whether we should emit the trace stats next time we reach EOF while
+    // performing ReadBuffers.
+    bool should_emit_stats = false;
+
+    // Whether we should emit the sync marker the next time ReadBuffers() is
+    // called.
+    bool should_emit_sync_marker = false;
+
+    // Whether we put the initial packets (trace config, system info,
+    // etc.) into the trace output yet.
+    bool did_emit_initial_packets = false;
+
+    // Whether we should compress TracePackets after reading them.
+    bool compress_deflate = false;
+
+    // The number of received triggers we've emitted into the trace output.
+    size_t num_triggers_emitted_into_trace = 0;
+
+    // Packets that failed validation of the TrustedPacket.
+    uint64_t invalid_packets = 0;
+
+    // Flush() stats. See comments in trace_stats.proto for more.
+    uint64_t flushes_requested = 0;
+    uint64_t flushes_succeeded = 0;
+    uint64_t flushes_failed = 0;
+
+    // Outcome of the final Flush() done by FlushAndDisableTracing().
+    protos::gen::TraceStats_FinalFlushOutcome final_flush_outcome{};
+
+    // Set to true on the first call to MaybeNotifyAllDataSourcesStarted().
+    bool did_notify_all_data_source_started = false;
+
+    // Stores all lifecycle events of a particular type (i.e. associated with a
+    // single field id in the TracingServiceEvent proto).
+    struct LifecycleEvent {
+      LifecycleEvent(uint32_t f_id, uint32_t m_size = 1)
+          : field_id(f_id), max_size(m_size), timestamps(m_size) {}
+
+      // The field id of the event in the TracingServiceEvent proto.
+      uint32_t field_id;
+
+      // Stores the max size of |timestamps|. Set to 1 by default (in
+      // the constructor) but can be overriden in TraceSession constructor
+      // if a larger size is required.
+      uint32_t max_size;
+
+      // Stores the timestamps emitted for each event type (in nanoseconds).
+      // Emitted into the trace and cleared when the consumer next calls
+      // ReadBuffers.
+      base::CircularQueue<int64_t> timestamps;
+    };
+    std::vector<LifecycleEvent> lifecycle_events;
+
+    using ClockSnapshotData =
+        std::vector<std::pair<uint32_t /*clock_id*/, uint64_t /*ts*/>>;
+
+    // Initial clock snapshot, captured at trace start time (when state goes to
+    // TracingSession::STARTED). Emitted into the trace when the consumer first
+    // calls ReadBuffers().
+    ClockSnapshotData initial_clock_snapshot;
+
+    // Stores clock snapshots to emit into the trace as a ring buffer. This
+    // buffer is populated both periodically and when lifecycle events happen
+    // but only when significant clock drift is detected. Emitted into the trace
+    // and cleared when the consumer next calls ReadBuffers().
+    base::CircularQueue<ClockSnapshotData> clock_snapshot_ring_buffer;
+
+    State state = DISABLED;
+
+    // If the consumer detached the session, this variable defines the key used
+    // for identifying the session later when reattaching.
+    std::string detach_key;
+
+    // This is set when the Consumer calls sets |write_into_file| == true in the
+    // TraceConfig. In this case this represents the file we should stream the
+    // trace packets into, rather than returning it to the consumer via
+    // OnTraceData().
+    base::ScopedFile write_into_file;
+    uint32_t write_period_ms = 0;
+    uint64_t max_file_size_bytes = 0;
+    uint64_t bytes_written_into_file = 0;
+
+    // Periodic task for snapshotting service events (e.g. clocks, sync markers
+    // etc)
+    base::PeriodicTask snapshot_periodic_task;
+
+    // Deferred task that stops the trace when |duration_ms| expires. This is
+    // to handle the case of |prefer_suspend_clock_for_duration| which cannot
+    // use PostDelayedTask.
+    base::PeriodicTask timed_stop_task;
+
+    // When non-NULL the packets should be post-processed using the filter.
+    std::unique_ptr<protozero::MessageFilter> trace_filter;
+    uint64_t filter_input_packets = 0;
+    uint64_t filter_input_bytes = 0;
+    uint64_t filter_output_bytes = 0;
+    uint64_t filter_errors = 0;
+    uint64_t filter_time_taken_ns = 0;
+    std::vector<uint64_t> filter_bytes_discarded_per_buffer;
+
+    // A randomly generated trace identifier. Note that this does NOT always
+    // match the requested TraceConfig.trace_uuid_msb/lsb. Spcifically, it does
+    // until a gap-less snapshot is requested. Each snapshot re-generates the
+    // uuid to avoid emitting two different traces with the same uuid.
+    base::Uuid trace_uuid;
+
+    // NOTE: when adding new fields here consider whether that state should be
+    // copied over in DoCloneSession() or not. Ask yourself: is this a
+    // "runtime state" (e.g. active data sources) or a "trace (meta)data state"?
+    // If the latter, it should be handled by DoCloneSession()).
+  };
+
+  TracingServiceImpl(const TracingServiceImpl&) = delete;
+  TracingServiceImpl& operator=(const TracingServiceImpl&) = delete;
+
+  DataSourceInstance* SetupDataSource(const TraceConfig::DataSource&,
+                                      const TraceConfig::ProducerConfig&,
+                                      const RegisteredDataSource&,
+                                      TracingSession*);
+
+  // Returns the next available ProducerID that is not in |producers_|.
+  ProducerID GetNextProducerID();
+
+  // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
+  // session doesn't exists.
+  TracingSession* GetTracingSession(TracingSessionID);
+
+  // Returns a pointer to the tracing session that has the highest
+  // TraceConfig.bugreport_score, if any, or nullptr.
+  TracingSession* FindTracingSessionWithMaxBugreportScore();
+
+  // Returns a pointer to the |tracing_sessions_| entry, matching the given
+  // uid and detach key, or nullptr if no such session exists.
+  TracingSession* GetDetachedSession(uid_t, const std::string& key);
+
+  // Update the memory guard rail by using the latest information from the
+  // shared memory and trace buffers.
+  void UpdateMemoryGuardrail();
+
+  void StartDataSourceInstance(ProducerEndpointImpl*,
+                               TracingSession*,
+                               DataSourceInstance*);
+  void StopDataSourceInstance(ProducerEndpointImpl*,
+                              TracingSession*,
+                              DataSourceInstance*,
+                              bool disable_immediately);
+  void PeriodicSnapshotTask(TracingSessionID);
+  void MaybeSnapshotClocksIntoRingBuffer(TracingSession*);
+  bool SnapshotClocks(TracingSession::ClockSnapshotData*);
+  void SnapshotLifecyleEvent(TracingSession*,
+                             uint32_t field_id,
+                             bool snapshot_clocks);
+  void EmitClockSnapshot(TracingSession*,
+                         TracingSession::ClockSnapshotData,
+                         std::vector<TracePacket>*);
+  void EmitSyncMarker(std::vector<TracePacket>*);
+  void EmitStats(TracingSession*, std::vector<TracePacket>*);
+  TraceStats GetTraceStats(TracingSession*);
+  void EmitLifecycleEvents(TracingSession*, std::vector<TracePacket>*);
+  void EmitUuid(TracingSession*, std::vector<TracePacket>*);
+  void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
+  void EmitSystemInfo(std::vector<TracePacket>*);
+  void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*);
+  void MaybeNotifyAllDataSourcesStarted(TracingSession*);
+  void OnFlushTimeout(TracingSessionID, FlushRequestID);
+  void OnDisableTracingTimeout(TracingSessionID);
+  void DisableTracingNotifyConsumerAndFlushFile(TracingSession*);
+  void PeriodicFlushTask(TracingSessionID, bool post_next_only);
+  void CompleteFlush(TracingSessionID tsid,
+                     ConsumerEndpoint::FlushCallback callback,
+                     bool success);
+  void ScrapeSharedMemoryBuffers(TracingSession*, ProducerEndpointImpl*);
+  void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only);
+  TraceBuffer* GetBufferByID(BufferID);
+  base::Status DoCloneSession(ConsumerEndpointImpl*,
+                              TracingSessionID,
+                              bool for_bugreport,
+                              bool final_flush_outcome,
+                              base::Uuid*);
+
+  // Returns true if `*tracing_session` is waiting for a trigger that hasn't
+  // happened.
+  static bool IsWaitingForTrigger(TracingSession* tracing_session);
+
+  // Reads the buffers from `*tracing_session` and returns them (along with some
+  // metadata packets).
+  //
+  // The function stops when the cumulative size of the return packets exceeds
+  // `threshold` (so it's not a strict upper bound) and sets `*has_more` to
+  // true, or when there are no more packets (and sets `*has_more` to false).
+  std::vector<TracePacket> ReadBuffers(TracingSession* tracing_session,
+                                       size_t threshold,
+                                       bool* has_more);
+
+  // If `*tracing_session` has a filter, applies it to `*packets`. Doesn't
+  // change the number of `*packets`, only their content.
+  void MaybeFilterPackets(TracingSession* tracing_session,
+                          std::vector<TracePacket>* packets);
+
+  // If `*tracing_session` has compression enabled, compress `*packets`.
+  void MaybeCompressPackets(TracingSession* tracing_session,
+                            std::vector<TracePacket>* packets);
+
+  // If `*tracing_session` is configured to write into a file, writes `packets`
+  // into the file.
+  //
+  // Returns true if the file should be closed (because it's full or there has
+  // been an error), false otherwise.
+  bool WriteIntoFile(TracingSession* tracing_session,
+                     std::vector<TracePacket> packets);
+  void OnStartTriggersTimeout(TracingSessionID tsid);
+  void MaybeLogUploadEvent(const TraceConfig&,
+                           const base::Uuid&,
+                           PerfettoStatsdAtom atom,
+                           const std::string& trigger_name = "");
+  void MaybeLogTriggerEvent(const TraceConfig&,
+                            PerfettoTriggerAtom atom,
+                            const std::string& trigger_name);
+  size_t PurgeExpiredAndCountTriggerInWindow(int64_t now_ns,
+                                             uint64_t trigger_name_hash);
+  static void StopOnDurationMsExpiry(base::WeakPtr<TracingServiceImpl>,
+                                     TracingSessionID);
+
+  base::TaskRunner* const task_runner_;
+  const InitOpts init_opts_;
+  std::unique_ptr<SharedMemory::Factory> shm_factory_;
+  ProducerID last_producer_id_ = 0;
+  DataSourceInstanceID last_data_source_instance_id_ = 0;
+  TracingSessionID last_tracing_session_id_ = 0;
+  FlushRequestID last_flush_request_id_ = 0;
+  uid_t uid_ = 0;
+
+  // Buffer IDs are global across all consumers (because a Producer can produce
+  // data for more than one trace session, hence more than one consumer).
+  IdAllocator<BufferID> buffer_ids_;
+
+  std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
+  std::map<ProducerID, ProducerEndpointImpl*> producers_;
+  std::set<ConsumerEndpointImpl*> consumers_;
+  std::map<TracingSessionID, TracingSession> tracing_sessions_;
+  std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
+  std::map<std::string, int64_t> session_to_last_trace_s_;
+
+  // Contains timestamps of triggers.
+  // The queue is sorted by timestamp and invocations older than
+  // |trigger_window_ns_| are purged when a trigger happens.
+  base::CircularQueue<TriggerHistory> trigger_history_;
+
+  bool smb_scraping_enabled_ = false;
+  bool lockdown_mode_ = false;
+  uint32_t min_write_period_ms_ = 100;       // Overridable for testing.
+  int64_t trigger_window_ns_ = kOneDayInNs;  // Overridable for testing.
+
+  std::minstd_rand trigger_probability_rand_;
+  std::uniform_real_distribution<> trigger_probability_dist_;
+  double trigger_rnd_override_for_testing_ = 0;  // Overridable for testing.
+
+  uint8_t sync_marker_packet_[32];  // Lazily initialized.
+  size_t sync_marker_packet_size_ = 0;
+
+  // Stats.
+  uint64_t chunks_discarded_ = 0;
+  uint64_t patches_discarded_ = 0;
+
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+
+  base::WeakPtrFactory<TracingServiceImpl>
+      weak_ptr_factory_;  // Keep at the end.
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
+// gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_capabilities.h
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/core/tracing_service_impl.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+
+#include <cinttypes>
+#include <limits>
+#include <optional>
+#include <regex>
+#include <unordered_set>
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+#include <sys/uio.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+// gen_amalgamated expanded: #include "src/android_internal/lazy_library_loader.h"    // nogncheck
+// gen_amalgamated expanded: #include "src/android_internal/tracing_service_proxy.h"  // nogncheck
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#define PERFETTO_HAS_CHMOD
+#include <sys/stat.h>
+#endif
+
+#include <algorithm>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/status.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/android_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
+// gen_amalgamated expanded: #include "src/android_stats/statsd_logging_helper.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/message_filter.h"
+// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"
+// gen_amalgamated expanded: #include "src/tracing/core/packet_stream_validator.h"
+// gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
+// gen_amalgamated expanded: #include "src/tracing/core/trace_buffer.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/system_info.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_uuid.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trigger.pbzero.h"
+
+// General note: this class must assume that Producers are malicious and will
+// try to crash / exploit this class. We can trust pointers because they come
+// from the IPC layer, but we should never assume that that the producer calls
+// come in the right order or their arguments are sane / within bounds.
+
+// This is a macro because we want the call-site line number for the ELOG.
+#define PERFETTO_SVC_ERR(...) \
+  (PERFETTO_ELOG(__VA_ARGS__), ::perfetto::base::ErrStatus(__VA_ARGS__))
+
+namespace perfetto {
+
+namespace {
+constexpr int kMaxBuffersPerConsumer = 128;
+constexpr uint32_t kDefaultSnapshotsIntervalMs = 10 * 1000;
+constexpr int kDefaultWriteIntoFilePeriodMs = 5000;
+constexpr int kMaxConcurrentTracingSessions = 15;
+constexpr int kMaxConcurrentTracingSessionsPerUid = 5;
+constexpr int kMaxConcurrentTracingSessionsForStatsdUid = 10;
+constexpr int64_t kMinSecondsBetweenTracesGuardrail = 5 * 60;
+
+constexpr uint32_t kMillisPerHour = 3600000;
+constexpr uint32_t kMillisPerDay = kMillisPerHour * 24;
+constexpr uint32_t kMaxTracingDurationMillis = 7 * 24 * kMillisPerHour;
+
+// These apply only if enable_extra_guardrails is true.
+constexpr uint32_t kGuardrailsMaxTracingBufferSizeKb = 128 * 1024;
+constexpr uint32_t kGuardrailsMaxTracingDurationMillis = 24 * kMillisPerHour;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+struct iovec {
+  void* iov_base;  // Address
+  size_t iov_len;  // Block size
+};
+
+// Simple implementation of writev. Note that this does not give the atomicity
+// guarantees of a real writev, but we don't depend on these (we aren't writing
+// to the same file from another thread).
+ssize_t writev(int fd, const struct iovec* iov, int iovcnt) {
+  ssize_t total_size = 0;
+  for (int i = 0; i < iovcnt; ++i) {
+    ssize_t current_size = base::WriteAll(fd, iov[i].iov_base, iov[i].iov_len);
+    if (current_size != static_cast<ssize_t>(iov[i].iov_len))
+      return -1;
+    total_size += current_size;
+  }
+  return total_size;
+}
+
+#define IOV_MAX 1024  // Linux compatible limit.
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
+        // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+
+// Partially encodes a CommitDataRequest in an int32 for the purposes of
+// metatracing. Note that it encodes only the bottom 10 bits of the producer id
+// (which is technically 16 bits wide).
+//
+// Format (by bit range):
+// [   31 ][         30 ][             29:20 ][            19:10 ][        9:0]
+// [unused][has flush id][num chunks to patch][num chunks to move][producer id]
+static int32_t EncodeCommitDataRequest(ProducerID producer_id,
+                                       const CommitDataRequest& req_untrusted) {
+  uint32_t cmov = static_cast<uint32_t>(req_untrusted.chunks_to_move_size());
+  uint32_t cpatch = static_cast<uint32_t>(req_untrusted.chunks_to_patch_size());
+  uint32_t has_flush_id = req_untrusted.flush_request_id() != 0;
+
+  uint32_t mask = (1 << 10) - 1;
+  uint32_t acc = 0;
+  acc |= has_flush_id << 30;
+  acc |= (cpatch & mask) << 20;
+  acc |= (cmov & mask) << 10;
+  acc |= (producer_id & mask);
+  return static_cast<int32_t>(acc);
+}
+
+void SerializeAndAppendPacket(std::vector<TracePacket>* packets,
+                              std::vector<uint8_t> packet) {
+  Slice slice = Slice::Allocate(packet.size());
+  memcpy(slice.own_data(), packet.data(), packet.size());
+  packets->emplace_back();
+  packets->back().AddSlice(std::move(slice));
+}
+
+std::tuple<size_t /*shm_size*/, size_t /*page_size*/> EnsureValidShmSizes(
+    size_t shm_size,
+    size_t page_size) {
+  // Theoretically the max page size supported by the ABI is 64KB.
+  // However, the current implementation of TraceBuffer (the non-shared
+  // userspace buffer where the service copies data) supports at most
+  // 32K. Setting 64K "works" from the producer<>consumer viewpoint
+  // but then causes the data to be discarded when copying it into
+  // TraceBuffer.
+  constexpr size_t kMaxPageSize = 32 * 1024;
+  static_assert(kMaxPageSize <= SharedMemoryABI::kMaxPageSize, "");
+
+  if (page_size == 0)
+    page_size = TracingServiceImpl::kDefaultShmPageSize;
+  if (shm_size == 0)
+    shm_size = TracingServiceImpl::kDefaultShmSize;
+
+  page_size = std::min<size_t>(page_size, kMaxPageSize);
+  shm_size = std::min<size_t>(shm_size, TracingServiceImpl::kMaxShmSize);
+
+  // The tracing page size has to be multiple of 4K. On some systems (e.g. Mac
+  // on Arm64) the system page size can be larger (e.g., 16K). That doesn't
+  // matter here, because the tracing page size is just a logical partitioning
+  // and does not have any dependencies on kernel mm syscalls (read: it's fine
+  // to have trace page sizes of 4K on a system where the kernel page size is
+  // 16K).
+  bool page_size_is_valid = page_size >= SharedMemoryABI::kMinPageSize;
+  page_size_is_valid &= page_size % SharedMemoryABI::kMinPageSize == 0;
+
+  // Only allow power of two numbers of pages, i.e. 1, 2, 4, 8 pages.
+  size_t num_pages = page_size / SharedMemoryABI::kMinPageSize;
+  page_size_is_valid &= (num_pages & (num_pages - 1)) == 0;
+
+  if (!page_size_is_valid || shm_size < page_size ||
+      shm_size % page_size != 0) {
+    return std::make_tuple(TracingServiceImpl::kDefaultShmSize,
+                           TracingServiceImpl::kDefaultShmPageSize);
+  }
+  return std::make_tuple(shm_size, page_size);
+}
+
+bool NameMatchesFilter(const std::string& name,
+                       const std::vector<std::string>& name_filter,
+                       const std::vector<std::string>& name_regex_filter) {
+  bool filter_is_set = !name_filter.empty() || !name_regex_filter.empty();
+  if (!filter_is_set)
+    return true;
+  bool filter_matches = std::find(name_filter.begin(), name_filter.end(),
+                                  name) != name_filter.end();
+  bool filter_regex_matches =
+      std::find_if(name_regex_filter.begin(), name_regex_filter.end(),
+                   [&](const std::string& regex) {
+                     return std::regex_match(
+                         name, std::regex(regex, std::regex::extended));
+                   }) != name_regex_filter.end();
+  return filter_matches || filter_regex_matches;
+}
+
+// Used when TraceConfig.write_into_file == true and output_path is not empty.
+base::ScopedFile CreateTraceFile(const std::string& path, bool overwrite) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
+    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+  // This is NOT trying to preserve any security property, SELinux does that.
+  // It just improves the actionability of the error when people try to save the
+  // trace in a location that is not SELinux-allowed (a generic "permission
+  // denied" vs "don't put it here, put it there").
+  // These are the only SELinux approved dir for trace files that are created
+  // directly by traced.
+  static const char* kTraceDirBasePath = "/data/misc/perfetto-traces/";
+  if (!base::StartsWith(path, kTraceDirBasePath)) {
+    PERFETTO_ELOG("Invalid output_path %s. On Android it must be within %s.",
+                  path.c_str(), kTraceDirBasePath);
+    return base::ScopedFile();
+  }
+#endif
+  // O_CREAT | O_EXCL will fail if the file exists already.
+  const int flags = O_RDWR | O_CREAT | (overwrite ? O_TRUNC : O_EXCL);
+  auto fd = base::OpenFile(path, flags, 0600);
+  if (fd) {
+#if defined(PERFETTO_HAS_CHMOD)
+    // Passing 0644 directly above won't work because of umask.
+    PERFETTO_CHECK(fchmod(*fd, 0644) == 0);
+#endif
+  } else {
+    PERFETTO_PLOG("Failed to create %s", path.c_str());
+  }
+  return fd;
+}
+
+bool ShouldLogEvent(const TraceConfig& cfg) {
+  switch (cfg.statsd_logging()) {
+    case TraceConfig::STATSD_LOGGING_ENABLED:
+      return true;
+    case TraceConfig::STATSD_LOGGING_DISABLED:
+      return false;
+    case TraceConfig::STATSD_LOGGING_UNSPECIFIED:
+      break;
+  }
+  // For backward compatibility with older versions of perfetto_cmd.
+  return cfg.enable_extra_guardrails();
+}
+
+// Appends `data` (which has `size` bytes), to `*packet`. Splits the data in
+// slices no larger than `max_slice_size`.
+void AppendOwnedSlicesToPacket(std::unique_ptr<uint8_t[]> data,
+                               size_t size,
+                               size_t max_slice_size,
+                               perfetto::TracePacket* packet) {
+  if (size <= max_slice_size) {
+    packet->AddSlice(Slice::TakeOwnership(std::move(data), size));
+    return;
+  }
+  uint8_t* src_ptr = data.get();
+  for (size_t size_left = size; size_left > 0;) {
+    const size_t slice_size = std::min(size_left, max_slice_size);
+
+    Slice slice = Slice::Allocate(slice_size);
+    memcpy(slice.own_data(), src_ptr, slice_size);
+    packet->AddSlice(std::move(slice));
+
+    src_ptr += slice_size;
+    size_left -= slice_size;
+  }
+}
+
+using TraceFilter = protos::gen::TraceConfig::TraceFilter;
+std::optional<protozero::StringFilter::Policy> ConvertPolicy(
+    TraceFilter::StringFilterPolicy policy) {
+  switch (policy) {
+    case TraceFilter::SFP_UNSPECIFIED:
+      return std::nullopt;
+    case TraceFilter::SFP_MATCH_REDACT_GROUPS:
+      return protozero::StringFilter::Policy::kMatchRedactGroups;
+    case TraceFilter::SFP_ATRACE_MATCH_REDACT_GROUPS:
+      return protozero::StringFilter::Policy::kAtraceMatchRedactGroups;
+    case TraceFilter::SFP_MATCH_BREAK:
+      return protozero::StringFilter::Policy::kMatchBreak;
+    case TraceFilter::SFP_ATRACE_MATCH_BREAK:
+      return protozero::StringFilter::Policy::kAtraceMatchBreak;
+    case TraceFilter::SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS:
+      return protozero::StringFilter::Policy::kAtraceRepeatedSearchRedactGroups;
+  }
+  return std::nullopt;
+}
+
+}  // namespace
+
+// static
+std::unique_ptr<TracingService> TracingService::CreateInstance(
+    std::unique_ptr<SharedMemory::Factory> shm_factory,
+    base::TaskRunner* task_runner,
+    InitOpts init_opts) {
+  return std::unique_ptr<TracingService>(
+      new TracingServiceImpl(std::move(shm_factory), task_runner, init_opts));
+}
+
+TracingServiceImpl::TracingServiceImpl(
+    std::unique_ptr<SharedMemory::Factory> shm_factory,
+    base::TaskRunner* task_runner,
+    InitOpts init_opts)
+    : task_runner_(task_runner),
+      init_opts_(init_opts),
+      shm_factory_(std::move(shm_factory)),
+      uid_(base::GetCurrentUserId()),
+      buffer_ids_(kMaxTraceBufferID),
+      trigger_probability_rand_(
+          static_cast<uint32_t>(base::GetWallTimeNs().count())),
+      weak_ptr_factory_(this) {
+  PERFETTO_DCHECK(task_runner_);
+}
+
+TracingServiceImpl::~TracingServiceImpl() {
+  // TODO(fmayer): handle teardown of all Producer.
+}
+
+std::unique_ptr<TracingService::ProducerEndpoint>
+TracingServiceImpl::ConnectProducer(Producer* producer,
+                                    const ClientIdentity& client_identity,
+                                    const std::string& producer_name,
+                                    size_t shared_memory_size_hint_bytes,
+                                    bool in_process,
+                                    ProducerSMBScrapingMode smb_scraping_mode,
+                                    size_t shared_memory_page_size_hint_bytes,
+                                    std::unique_ptr<SharedMemory> shm,
+                                    const std::string& sdk_version) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto uid = client_identity.uid();
+  if (lockdown_mode_ && uid != base::GetCurrentUserId()) {
+    PERFETTO_DLOG("Lockdown mode. Rejecting producer with UID %ld",
+                  static_cast<unsigned long>(uid));
+    return nullptr;
+  }
+
+  if (producers_.size() >= kMaxProducerID) {
+    PERFETTO_DFATAL("Too many producers.");
+    return nullptr;
+  }
+  const ProducerID id = GetNextProducerID();
+  PERFETTO_DLOG("Producer %" PRIu16 " connected, uid=%d", id,
+                static_cast<int>(uid));
+  bool smb_scraping_enabled = smb_scraping_enabled_;
+  switch (smb_scraping_mode) {
+    case ProducerSMBScrapingMode::kDefault:
+      break;
+    case ProducerSMBScrapingMode::kEnabled:
+      smb_scraping_enabled = true;
+      break;
+    case ProducerSMBScrapingMode::kDisabled:
+      smb_scraping_enabled = false;
+      break;
+  }
+
+  std::unique_ptr<ProducerEndpointImpl> endpoint(new ProducerEndpointImpl(
+      id, client_identity, this, task_runner_, producer, producer_name,
+      sdk_version, in_process, smb_scraping_enabled));
+  auto it_and_inserted = producers_.emplace(id, endpoint.get());
+  PERFETTO_DCHECK(it_and_inserted.second);
+  endpoint->shmem_size_hint_bytes_ = shared_memory_size_hint_bytes;
+  endpoint->shmem_page_size_hint_bytes_ = shared_memory_page_size_hint_bytes;
+
+  // Producer::OnConnect() should run before Producer::OnTracingSetup(). The
+  // latter may be posted by SetupSharedMemory() below, so post OnConnect() now.
+  auto weak_ptr = endpoint->weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_ptr] {
+    if (weak_ptr)
+      weak_ptr->producer_->OnConnect();
+  });
+
+  if (shm) {
+    // The producer supplied an SMB. This is used only by Chrome; in the most
+    // common cases the SMB is created by the service and passed via
+    // OnTracingSetup(). Verify that it is correctly sized before we attempt to
+    // use it. The transport layer has to verify the integrity of the SMB (e.g.
+    // ensure that the producer can't resize if after the fact).
+    size_t shm_size, page_size;
+    std::tie(shm_size, page_size) =
+        EnsureValidShmSizes(shm->size(), endpoint->shmem_page_size_hint_bytes_);
+    if (shm_size == shm->size() &&
+        page_size == endpoint->shmem_page_size_hint_bytes_) {
+      PERFETTO_DLOG(
+          "Adopting producer-provided SMB of %zu kB for producer \"%s\"",
+          shm_size / 1024, endpoint->name_.c_str());
+      endpoint->SetupSharedMemory(std::move(shm), page_size,
+                                  /*provided_by_producer=*/true);
+    } else {
+      PERFETTO_LOG(
+          "Discarding incorrectly sized producer-provided SMB for producer "
+          "\"%s\", falling back to service-provided SMB. Requested sizes: %zu "
+          "B total, %zu B page size; suggested corrected sizes: %zu B total, "
+          "%zu B page size",
+          endpoint->name_.c_str(), shm->size(),
+          endpoint->shmem_page_size_hint_bytes_, shm_size, page_size);
+      shm.reset();
+    }
+  }
+
+  return std::unique_ptr<ProducerEndpoint>(std::move(endpoint));
+}
+
+void TracingServiceImpl::DisconnectProducer(ProducerID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Producer %" PRIu16 " disconnected", id);
+  PERFETTO_DCHECK(producers_.count(id));
+
+  // Scrape remaining chunks for this producer to ensure we don't lose data.
+  if (auto* producer = GetProducer(id)) {
+    for (auto& session_id_and_session : tracing_sessions_)
+      ScrapeSharedMemoryBuffers(&session_id_and_session.second, producer);
+  }
+
+  for (auto it = data_sources_.begin(); it != data_sources_.end();) {
+    auto next = it;
+    next++;
+    if (it->second.producer_id == id)
+      UnregisterDataSource(id, it->second.descriptor.name());
+    it = next;
+  }
+
+  producers_.erase(id);
+  UpdateMemoryGuardrail();
+}
+
+TracingServiceImpl::ProducerEndpointImpl* TracingServiceImpl::GetProducer(
+    ProducerID id) const {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto it = producers_.find(id);
+  if (it == producers_.end())
+    return nullptr;
+  return it->second;
+}
+
+std::unique_ptr<TracingService::ConsumerEndpoint>
+TracingServiceImpl::ConnectConsumer(Consumer* consumer, uid_t uid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Consumer %p connected from UID %" PRIu64,
+                reinterpret_cast<void*>(consumer), static_cast<uint64_t>(uid));
+  std::unique_ptr<ConsumerEndpointImpl> endpoint(
+      new ConsumerEndpointImpl(this, task_runner_, consumer, uid));
+  auto it_and_inserted = consumers_.emplace(endpoint.get());
+  PERFETTO_DCHECK(it_and_inserted.second);
+  // Consumer might go away before we're able to send the connect notification,
+  // if that is the case just bail out.
+  auto weak_ptr = endpoint->weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_ptr] {
+    if (weak_ptr)
+      weak_ptr->consumer_->OnConnect();
+  });
+  return std::unique_ptr<ConsumerEndpoint>(std::move(endpoint));
+}
+
+void TracingServiceImpl::DisconnectConsumer(ConsumerEndpointImpl* consumer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Consumer %p disconnected", reinterpret_cast<void*>(consumer));
+  PERFETTO_DCHECK(consumers_.count(consumer));
+
+  // TODO(primiano) : Check that this is safe (what happens if there are
+  // ReadBuffers() calls posted in the meantime? They need to become noop).
+  if (consumer->tracing_session_id_)
+    FreeBuffers(consumer->tracing_session_id_);  // Will also DisableTracing().
+  consumers_.erase(consumer);
+
+  // At this point no more pointers to |consumer| should be around.
+  PERFETTO_DCHECK(!std::any_of(
+      tracing_sessions_.begin(), tracing_sessions_.end(),
+      [consumer](const std::pair<const TracingSessionID, TracingSession>& kv) {
+        return kv.second.consumer_maybe_null == consumer;
+      }));
+}
+
+bool TracingServiceImpl::DetachConsumer(ConsumerEndpointImpl* consumer,
+                                        const std::string& key) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Consumer %p detached", reinterpret_cast<void*>(consumer));
+  PERFETTO_DCHECK(consumers_.count(consumer));
+
+  TracingSessionID tsid = consumer->tracing_session_id_;
+  TracingSession* tracing_session;
+  if (!tsid || !(tracing_session = GetTracingSession(tsid)))
+    return false;
+
+  if (GetDetachedSession(consumer->uid_, key)) {
+    PERFETTO_ELOG("Another session has been detached with the same key \"%s\"",
+                  key.c_str());
+    return false;
+  }
+
+  PERFETTO_DCHECK(tracing_session->consumer_maybe_null == consumer);
+  tracing_session->consumer_maybe_null = nullptr;
+  tracing_session->detach_key = key;
+  consumer->tracing_session_id_ = 0;
+  return true;
+}
+
+bool TracingServiceImpl::AttachConsumer(ConsumerEndpointImpl* consumer,
+                                        const std::string& key) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Consumer %p attaching to session %s",
+                reinterpret_cast<void*>(consumer), key.c_str());
+  PERFETTO_DCHECK(consumers_.count(consumer));
+
+  if (consumer->tracing_session_id_) {
+    PERFETTO_ELOG(
+        "Cannot reattach consumer to session %s"
+        " while it already attached tracing session ID %" PRIu64,
+        key.c_str(), consumer->tracing_session_id_);
+    return false;
+  }
+
+  auto* tracing_session = GetDetachedSession(consumer->uid_, key);
+  if (!tracing_session) {
+    PERFETTO_ELOG(
+        "Failed to attach consumer, session '%s' not found for uid %d",
+        key.c_str(), static_cast<int>(consumer->uid_));
+    return false;
+  }
+
+  consumer->tracing_session_id_ = tracing_session->id;
+  tracing_session->consumer_maybe_null = consumer;
+  tracing_session->detach_key.clear();
+  return true;
+}
+
+base::Status TracingServiceImpl::EnableTracing(ConsumerEndpointImpl* consumer,
+                                               const TraceConfig& cfg,
+                                               base::ScopedFile fd) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  // If the producer is specifying a UUID, respect that (at least for the first
+  // snapshot). Otherwise generate a new UUID.
+  base::Uuid uuid(cfg.trace_uuid_lsb(), cfg.trace_uuid_msb());
+  if (!uuid)
+    uuid = base::Uuidv4();
+
+  PERFETTO_DLOG("Enabling tracing for consumer %p, UUID: %s",
+                reinterpret_cast<void*>(consumer),
+                uuid.ToPrettyString().c_str());
+  MaybeLogUploadEvent(cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracing);
+  if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_SET)
+    lockdown_mode_ = true;
+  if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_CLEAR)
+    lockdown_mode_ = false;
+
+  // Scope |tracing_session| to this block to prevent accidental use of a null
+  // pointer later in this function.
+  {
+    TracingSession* tracing_session =
+        GetTracingSession(consumer->tracing_session_id_);
+    if (tracing_session) {
+      MaybeLogUploadEvent(
+          cfg, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingExistingTraceSession);
+      return PERFETTO_SVC_ERR(
+          "A Consumer is trying to EnableTracing() but another tracing "
+          "session is already active (forgot a call to FreeBuffers() ?)");
+    }
+  }
+
+  const uint32_t max_duration_ms = cfg.enable_extra_guardrails()
+                                       ? kGuardrailsMaxTracingDurationMillis
+                                       : kMaxTracingDurationMillis;
+  if (cfg.duration_ms() > max_duration_ms) {
+    MaybeLogUploadEvent(cfg, uuid,
+                        PerfettoStatsdAtom::kTracedEnableTracingTooLongTrace);
+    return PERFETTO_SVC_ERR("Requested too long trace (%" PRIu32
+                            "ms  > %" PRIu32 " ms)",
+                            cfg.duration_ms(), max_duration_ms);
+  }
+
+  const bool has_trigger_config =
+      GetTriggerMode(cfg) != TraceConfig::TriggerConfig::UNSPECIFIED;
+  if (has_trigger_config &&
+      (cfg.trigger_config().trigger_timeout_ms() == 0 ||
+       cfg.trigger_config().trigger_timeout_ms() > max_duration_ms)) {
+    MaybeLogUploadEvent(
+        cfg, uuid,
+        PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerTimeout);
+    return PERFETTO_SVC_ERR(
+        "Traces with START_TRACING triggers must provide a positive "
+        "trigger_timeout_ms < 7 days (received %" PRIu32 "ms)",
+        cfg.trigger_config().trigger_timeout_ms());
+  }
+
+  // This check has been introduced in May 2023 after finding b/274931668.
+  if (static_cast<int>(cfg.trigger_config().trigger_mode()) >
+      TraceConfig::TriggerConfig::TriggerMode_MAX) {
+    MaybeLogUploadEvent(
+        cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerMode);
+    return PERFETTO_SVC_ERR(
+        "The trace config specified an invalid trigger_mode");
+  }
+
+  if (cfg.trigger_config().use_clone_snapshot_if_available() &&
+      cfg.trigger_config().trigger_mode() !=
+          TraceConfig::TriggerConfig::STOP_TRACING) {
+    MaybeLogUploadEvent(
+        cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerMode);
+    return PERFETTO_SVC_ERR(
+        "trigger_mode must be STOP_TRACING when "
+        "use_clone_snapshot_if_available=true");
+  }
+
+  if (has_trigger_config && cfg.duration_ms() != 0) {
+    MaybeLogUploadEvent(
+        cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingDurationWithTrigger);
+    return PERFETTO_SVC_ERR(
+        "duration_ms was set, this must not be set for traces with triggers.");
+  }
+
+  if ((GetTriggerMode(cfg) == TraceConfig::TriggerConfig::STOP_TRACING ||
+       GetTriggerMode(cfg) == TraceConfig::TriggerConfig::CLONE_SNAPSHOT) &&
+      cfg.write_into_file()) {
+    // We don't support this usecase because there are subtle assumptions which
+    // break around TracingServiceEvents and windowed sorting (i.e. if we don't
+    // drain the events in ReadBuffersIntoFile because we are waiting for
+    // STOP_TRACING, we can end up queueing up a lot of TracingServiceEvents and
+    // emitting them wildy out of order breaking windowed sorting in trace
+    // processor).
+    MaybeLogUploadEvent(
+        cfg, uuid,
+        PerfettoStatsdAtom::kTracedEnableTracingStopTracingWriteIntoFile);
+    return PERFETTO_SVC_ERR(
+        "Specifying trigger mode STOP_TRACING/CLONE_SNAPSHOT and "
+        "write_into_file together is unsupported");
+  }
+
+  std::unordered_set<std::string> triggers;
+  for (const auto& trigger : cfg.trigger_config().triggers()) {
+    if (!triggers.insert(trigger.name()).second) {
+      MaybeLogUploadEvent(
+          cfg, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingDuplicateTriggerName);
+      return PERFETTO_SVC_ERR("Duplicate trigger name: %s",
+                              trigger.name().c_str());
+    }
+  }
+
+  if (cfg.enable_extra_guardrails()) {
+    if (cfg.deferred_start()) {
+      MaybeLogUploadEvent(
+          cfg, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingInvalidDeferredStart);
+      return PERFETTO_SVC_ERR(
+          "deferred_start=true is not supported in unsupervised traces");
+    }
+    uint64_t buf_size_sum = 0;
+    for (const auto& buf : cfg.buffers()) {
+      if (buf.size_kb() % 4 != 0) {
+        MaybeLogUploadEvent(
+            cfg, uuid,
+            PerfettoStatsdAtom::kTracedEnableTracingInvalidBufferSize);
+        return PERFETTO_SVC_ERR(
+            "buffers.size_kb must be a multiple of 4, got %" PRIu32,
+            buf.size_kb());
+      }
+      buf_size_sum += buf.size_kb();
+    }
+
+    uint32_t max_tracing_buffer_size_kb =
+        std::max(kGuardrailsMaxTracingBufferSizeKb,
+                 cfg.guardrail_overrides().max_tracing_buffer_size_kb());
+    if (buf_size_sum > max_tracing_buffer_size_kb) {
+      MaybeLogUploadEvent(
+          cfg, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingBufferSizeTooLarge);
+      return PERFETTO_SVC_ERR("Requested too large trace buffer (%" PRIu64
+                              "kB  > %" PRIu32 " kB)",
+                              buf_size_sum, max_tracing_buffer_size_kb);
+    }
+  }
+
+  if (cfg.buffers_size() > kMaxBuffersPerConsumer) {
+    MaybeLogUploadEvent(cfg, uuid,
+                        PerfettoStatsdAtom::kTracedEnableTracingTooManyBuffers);
+    return PERFETTO_SVC_ERR("Too many buffers configured (%d)",
+                            cfg.buffers_size());
+  }
+  // Check that the config specifies all buffers for its data sources. This
+  // is also checked in SetupDataSource, but it is simpler to return a proper
+  // error to the consumer from here (and there will be less state to undo).
+  for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
+    size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
+    size_t target_buffer = cfg_data_source.config().target_buffer();
+    if (target_buffer >= num_buffers) {
+      MaybeLogUploadEvent(
+          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingOobTargetBuffer);
+      return PERFETTO_SVC_ERR(
+          "Data source \"%s\" specified an out of bounds target_buffer (%zu >= "
+          "%zu)",
+          cfg_data_source.config().name().c_str(), target_buffer, num_buffers);
+    }
+  }
+
+  if (!cfg.unique_session_name().empty()) {
+    const std::string& name = cfg.unique_session_name();
+    for (auto& kv : tracing_sessions_) {
+      if (kv.second.state == TracingSession::CLONED_READ_ONLY)
+        continue;  // Don't consider cloned sessions in uniqueness checks.
+      if (kv.second.config.unique_session_name() == name) {
+        MaybeLogUploadEvent(
+            cfg, uuid,
+            PerfettoStatsdAtom::kTracedEnableTracingDuplicateSessionName);
+        static const char fmt[] =
+            "A trace with this unique session name (%s) already exists";
+        // This happens frequently, don't make it an "E"LOG.
+        PERFETTO_LOG(fmt, name.c_str());
+        return base::ErrStatus(fmt, name.c_str());
+      }
+    }
+  }
+
+  if (cfg.enable_extra_guardrails()) {
+    // unique_session_name can be empty
+    const std::string& name = cfg.unique_session_name();
+    int64_t now_s = base::GetBootTimeS().count();
+
+    // Remove any entries where the time limit has passed so this map doesn't
+    // grow indefinitely:
+    std::map<std::string, int64_t>& sessions = session_to_last_trace_s_;
+    for (auto it = sessions.cbegin(); it != sessions.cend();) {
+      if (now_s - it->second > kMinSecondsBetweenTracesGuardrail) {
+        it = sessions.erase(it);
+      } else {
+        ++it;
+      }
+    }
+
+    int64_t& previous_s = session_to_last_trace_s_[name];
+    if (previous_s == 0) {
+      previous_s = now_s;
+    } else {
+      MaybeLogUploadEvent(
+          cfg, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingSessionNameTooRecent);
+      return PERFETTO_SVC_ERR(
+          "A trace with unique session name \"%s\" began less than %" PRId64
+          "s ago (%" PRId64 "s)",
+          name.c_str(), kMinSecondsBetweenTracesGuardrail, now_s - previous_s);
+    }
+  }
+
+  const int sessions_for_uid = static_cast<int>(std::count_if(
+      tracing_sessions_.begin(), tracing_sessions_.end(),
+      [consumer](const decltype(tracing_sessions_)::value_type& s) {
+        return s.second.consumer_uid == consumer->uid_;
+      }));
+
+  int per_uid_limit = kMaxConcurrentTracingSessionsPerUid;
+  if (consumer->uid_ == 1066 /* AID_STATSD*/) {
+    per_uid_limit = kMaxConcurrentTracingSessionsForStatsdUid;
+  }
+  if (sessions_for_uid >= per_uid_limit) {
+    MaybeLogUploadEvent(
+        cfg, uuid,
+        PerfettoStatsdAtom::kTracedEnableTracingTooManySessionsForUid);
+    return PERFETTO_SVC_ERR(
+        "Too many concurrent tracing sesions (%d) for uid %d limit is %d",
+        sessions_for_uid, static_cast<int>(consumer->uid_), per_uid_limit);
+  }
+
+  // TODO(primiano): This is a workaround to prevent that a producer gets stuck
+  // in a state where it stalls by design by having more TraceWriterImpl
+  // instances than free pages in the buffer. This is really a bug in
+  // trace_probes and the way it handles stalls in the shmem buffer.
+  if (tracing_sessions_.size() >= kMaxConcurrentTracingSessions) {
+    MaybeLogUploadEvent(
+        cfg, uuid,
+        PerfettoStatsdAtom::kTracedEnableTracingTooManyConcurrentSessions);
+    return PERFETTO_SVC_ERR("Too many concurrent tracing sesions (%zu)",
+                            tracing_sessions_.size());
+  }
+
+  // If the trace config provides a filter bytecode, setup the filter now.
+  // If the filter loading fails, abort the tracing session rather than running
+  // unfiltered.
+  std::unique_ptr<protozero::MessageFilter> trace_filter;
+  if (cfg.has_trace_filter()) {
+    const auto& filt = cfg.trace_filter();
+    trace_filter.reset(new protozero::MessageFilter());
+
+    protozero::StringFilter& string_filter = trace_filter->string_filter();
+    for (const auto& rule : filt.string_filter_chain().rules()) {
+      auto opt_policy = ConvertPolicy(rule.policy());
+      if (!opt_policy.has_value()) {
+        MaybeLogUploadEvent(
+            cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
+        return PERFETTO_SVC_ERR(
+            "Trace filter has invalid string filtering rules, aborting");
+      }
+      string_filter.AddRule(*opt_policy, rule.regex_pattern(),
+                            rule.atrace_payload_starts_with());
+    }
+
+    const std::string& bytecode_v1 = filt.bytecode();
+    const std::string& bytecode_v2 = filt.bytecode_v2();
+    const std::string& bytecode =
+        bytecode_v2.empty() ? bytecode_v1 : bytecode_v2;
+    if (!trace_filter->LoadFilterBytecode(bytecode.data(), bytecode.size())) {
+      MaybeLogUploadEvent(
+          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
+      return PERFETTO_SVC_ERR("Trace filter bytecode invalid, aborting");
+    }
+
+    // The filter is created using perfetto.protos.Trace as root message
+    // (because that makes it possible to play around with the `proto_filter`
+    // tool on actual traces). Here in the service, however, we deal with
+    // perfetto.protos.TracePacket(s), which are one level down (Trace.packet).
+    // The IPC client (or the write_into_filte logic in here) are responsible
+    // for pre-pending the packet preamble (See GetProtoPreamble() calls), but
+    // the preamble is not there at ReadBuffer time. Hence we change the root of
+    // the filtering to start at the Trace.packet level.
+    if (!trace_filter->SetFilterRoot({TracePacket::kPacketFieldNumber})) {
+      MaybeLogUploadEvent(
+          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
+      return PERFETTO_SVC_ERR("Failed to set filter root.");
+    }
+  }
+
+  const TracingSessionID tsid = ++last_tracing_session_id_;
+  TracingSession* tracing_session =
+      &tracing_sessions_
+           .emplace(std::piecewise_construct, std::forward_as_tuple(tsid),
+                    std::forward_as_tuple(tsid, consumer, cfg, task_runner_))
+           .first->second;
+
+  tracing_session->trace_uuid = uuid;
+
+  if (trace_filter)
+    tracing_session->trace_filter = std::move(trace_filter);
+
+  if (cfg.write_into_file()) {
+    if (!fd ^ !cfg.output_path().empty()) {
+      MaybeLogUploadEvent(
+          tracing_session->config, uuid,
+          PerfettoStatsdAtom::kTracedEnableTracingInvalidFdOutputFile);
+      tracing_sessions_.erase(tsid);
+      return PERFETTO_SVC_ERR(
+          "When write_into_file==true either a FD needs to be passed or "
+          "output_path must be populated (but not both)");
+    }
+    if (!cfg.output_path().empty()) {
+      fd = CreateTraceFile(cfg.output_path(), /*overwrite=*/false);
+      if (!fd) {
+        MaybeLogUploadEvent(
+            tracing_session->config, uuid,
+            PerfettoStatsdAtom::kTracedEnableTracingFailedToCreateFile);
+        tracing_sessions_.erase(tsid);
+        return PERFETTO_SVC_ERR("Failed to create the trace file %s",
+                                cfg.output_path().c_str());
+      }
+    }
+    tracing_session->write_into_file = std::move(fd);
+    uint32_t write_period_ms = cfg.file_write_period_ms();
+    if (write_period_ms == 0)
+      write_period_ms = kDefaultWriteIntoFilePeriodMs;
+    if (write_period_ms < min_write_period_ms_)
+      write_period_ms = min_write_period_ms_;
+    tracing_session->write_period_ms = write_period_ms;
+    tracing_session->max_file_size_bytes = cfg.max_file_size_bytes();
+    tracing_session->bytes_written_into_file = 0;
+  }
+
+  if (!cfg.compress_from_cli() &&
+      cfg.compression_type() == TraceConfig::COMPRESSION_TYPE_DEFLATE) {
+    if (init_opts_.compressor_fn) {
+      tracing_session->compress_deflate = true;
+    } else {
+      PERFETTO_LOG(
+          "COMPRESSION_TYPE_DEFLATE is not supported in the current build "
+          "configuration. Skipping compression");
+    }
+  }
+
+  // Initialize the log buffers.
+  bool did_allocate_all_buffers = true;
+  bool invalid_buffer_config = false;
+
+  // Allocate the trace buffers. Also create a map to translate a consumer
+  // relative index (TraceConfig.DataSourceConfig.target_buffer) into the
+  // corresponding BufferID, which is a global ID namespace for the service and
+  // all producers.
+  size_t total_buf_size_kb = 0;
+  const size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
+  tracing_session->buffers_index.reserve(num_buffers);
+  for (size_t i = 0; i < num_buffers; i++) {
+    const TraceConfig::BufferConfig& buffer_cfg = cfg.buffers()[i];
+    BufferID global_id = buffer_ids_.Allocate();
+    if (!global_id) {
+      did_allocate_all_buffers = false;  // We ran out of IDs.
+      break;
+    }
+    tracing_session->buffers_index.push_back(global_id);
+    // TraceBuffer size is limited to 32-bit.
+    const uint32_t buf_size_kb = buffer_cfg.size_kb();
+    const uint64_t buf_size_bytes = buf_size_kb * static_cast<uint64_t>(1024);
+    const size_t buf_size = static_cast<size_t>(buf_size_bytes);
+    if (buf_size_bytes == 0 ||
+        buf_size_bytes > std::numeric_limits<uint32_t>::max() ||
+        buf_size != buf_size_bytes) {
+      invalid_buffer_config = true;
+      did_allocate_all_buffers = false;
+      break;
+    }
+    total_buf_size_kb += buf_size_kb;
+    TraceBuffer::OverwritePolicy policy =
+        buffer_cfg.fill_policy() == TraceConfig::BufferConfig::DISCARD
+            ? TraceBuffer::kDiscard
+            : TraceBuffer::kOverwrite;
+    auto it_and_inserted =
+        buffers_.emplace(global_id, TraceBuffer::Create(buf_size, policy));
+    PERFETTO_DCHECK(it_and_inserted.second);  // buffers_.count(global_id) == 0.
+    std::unique_ptr<TraceBuffer>& trace_buffer = it_and_inserted.first->second;
+    if (!trace_buffer) {
+      did_allocate_all_buffers = false;
+      break;
+    }
+  }
+
+  // This can happen if either:
+  // - All the kMaxTraceBufferID slots are taken.
+  // - OOM, or, more realistically, we exhausted virtual memory.
+  // - The buffer size in the config is invalid.
+  // In any case, free all the previously allocated buffers and abort.
+  if (!did_allocate_all_buffers) {
+    for (BufferID global_id : tracing_session->buffers_index) {
+      buffer_ids_.Free(global_id);
+      buffers_.erase(global_id);
+    }
+    MaybeLogUploadEvent(tracing_session->config, uuid,
+                        PerfettoStatsdAtom::kTracedEnableTracingOom);
+    tracing_sessions_.erase(tsid);
+    if (invalid_buffer_config) {
+      return PERFETTO_SVC_ERR(
+          "Failed to allocate tracing buffers: Invalid buffer sizes");
+    }
+    return PERFETTO_SVC_ERR(
+        "Failed to allocate tracing buffers: OOM or too many buffers");
+  }
+
+  UpdateMemoryGuardrail();
+
+  consumer->tracing_session_id_ = tsid;
+
+  // Setup the data sources on the producers without starting them.
+  for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
+    // Scan all the registered data sources with a matching name.
+    auto range = data_sources_.equal_range(cfg_data_source.config().name());
+    for (auto it = range.first; it != range.second; it++) {
+      TraceConfig::ProducerConfig producer_config;
+      for (auto& config : cfg.producers()) {
+        if (GetProducer(it->second.producer_id)->name_ ==
+            config.producer_name()) {
+          producer_config = config;
+          break;
+        }
+      }
+      SetupDataSource(cfg_data_source, producer_config, it->second,
+                      tracing_session);
+    }
+  }
+
+  bool has_start_trigger = false;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  switch (GetTriggerMode(cfg)) {
+    case TraceConfig::TriggerConfig::UNSPECIFIED:
+      // no triggers are specified so this isn't a trace that is using triggers.
+      PERFETTO_DCHECK(!has_trigger_config);
+      break;
+    case TraceConfig::TriggerConfig::START_TRACING:
+      // For traces which use START_TRACE triggers we need to ensure that the
+      // tracing session will be cleaned up when it times out.
+      has_start_trigger = true;
+      task_runner_->PostDelayedTask(
+          [weak_this, tsid]() {
+            if (weak_this)
+              weak_this->OnStartTriggersTimeout(tsid);
+          },
+          cfg.trigger_config().trigger_timeout_ms());
+      break;
+    case TraceConfig::TriggerConfig::STOP_TRACING:
+    case TraceConfig::TriggerConfig::CLONE_SNAPSHOT:
+      // Update the tracing_session's duration_ms to ensure that if no trigger
+      // is received the session will end and be cleaned up equal to the
+      // timeout.
+      //
+      // TODO(nuskos): Refactor this so that rather then modifying the config we
+      // have a field we look at on the tracing_session.
+      tracing_session->config.set_duration_ms(
+          cfg.trigger_config().trigger_timeout_ms());
+      break;
+
+      // The case of unknown modes (coming from future versions of the service)
+      // is handled few lines above (search for TriggerMode_MAX).
+  }
+
+  tracing_session->state = TracingSession::CONFIGURED;
+  PERFETTO_LOG(
+      "Configured tracing session %" PRIu64
+      ", #sources:%zu, duration:%d ms%s, #buffers:%d, total "
+      "buffer size:%zu KB, total sessions:%zu, uid:%d session name: \"%s\"",
+      tsid, cfg.data_sources().size(), tracing_session->config.duration_ms(),
+      tracing_session->config.prefer_suspend_clock_for_duration()
+          ? " (suspend_clock)"
+          : "",
+      cfg.buffers_size(), total_buf_size_kb, tracing_sessions_.size(),
+      static_cast<unsigned int>(consumer->uid_),
+      cfg.unique_session_name().c_str());
+
+  // Start the data sources, unless this is a case of early setup + fast
+  // triggering, either through TraceConfig.deferred_start or
+  // TraceConfig.trigger_config(). If both are specified which ever one occurs
+  // first will initiate the trace.
+  if (!cfg.deferred_start() && !has_start_trigger)
+    return StartTracing(tsid);
+
+  return base::OkStatus();
+}
+
+void TracingServiceImpl::ChangeTraceConfig(ConsumerEndpointImpl* consumer,
+                                           const TraceConfig& updated_cfg) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session =
+      GetTracingSession(consumer->tracing_session_id_);
+  PERFETTO_DCHECK(tracing_session);
+
+  if ((tracing_session->state != TracingSession::STARTED) &&
+      (tracing_session->state != TracingSession::CONFIGURED)) {
+    PERFETTO_ELOG(
+        "ChangeTraceConfig() was called for a tracing session which isn't "
+        "running.");
+    return;
+  }
+
+  // We only support updating producer_name_{,regex}_filter (and pass-through
+  // configs) for now; null out any changeable fields and make sure the rest are
+  // identical.
+  TraceConfig new_config_copy(updated_cfg);
+  for (auto& ds_cfg : *new_config_copy.mutable_data_sources()) {
+    ds_cfg.clear_producer_name_filter();
+    ds_cfg.clear_producer_name_regex_filter();
+  }
+
+  TraceConfig current_config_copy(tracing_session->config);
+  for (auto& ds_cfg : *current_config_copy.mutable_data_sources()) {
+    ds_cfg.clear_producer_name_filter();
+    ds_cfg.clear_producer_name_regex_filter();
+  }
+
+  if (new_config_copy != current_config_copy) {
+    PERFETTO_LOG(
+        "ChangeTraceConfig() was called with a config containing unsupported "
+        "changes; only adding to the producer_name_{,regex}_filter is "
+        "currently supported and will have an effect.");
+  }
+
+  for (TraceConfig::DataSource& cfg_data_source :
+       *tracing_session->config.mutable_data_sources()) {
+    // Find the updated producer_filter in the new config.
+    std::vector<std::string> new_producer_name_filter;
+    std::vector<std::string> new_producer_name_regex_filter;
+    bool found_data_source = false;
+    for (const auto& it : updated_cfg.data_sources()) {
+      if (cfg_data_source.config().name() == it.config().name()) {
+        new_producer_name_filter = it.producer_name_filter();
+        new_producer_name_regex_filter = it.producer_name_regex_filter();
+        found_data_source = true;
+        break;
+      }
+    }
+
+    // Bail out if data source not present in the new config.
+    if (!found_data_source) {
+      PERFETTO_ELOG(
+          "ChangeTraceConfig() called without a current data source also "
+          "present in the new config: %s",
+          cfg_data_source.config().name().c_str());
+      continue;
+    }
+
+    // TODO(oysteine): Just replacing the filter means that if
+    // there are any filter entries which were present in the original config,
+    // but removed from the config passed to ChangeTraceConfig, any matching
+    // producers will keep producing but newly added producers after this
+    // point will never start.
+    *cfg_data_source.mutable_producer_name_filter() = new_producer_name_filter;
+    *cfg_data_source.mutable_producer_name_regex_filter() =
+        new_producer_name_regex_filter;
+
+    // Get the list of producers that are already set up.
+    std::unordered_set<uint16_t> set_up_producers;
+    auto& ds_instances = tracing_session->data_source_instances;
+    for (auto instance_it = ds_instances.begin();
+         instance_it != ds_instances.end(); ++instance_it) {
+      set_up_producers.insert(instance_it->first);
+    }
+
+    // Scan all the registered data sources with a matching name.
+    auto range = data_sources_.equal_range(cfg_data_source.config().name());
+    for (auto it = range.first; it != range.second; it++) {
+      ProducerEndpointImpl* producer = GetProducer(it->second.producer_id);
+      PERFETTO_DCHECK(producer);
+
+      // Check if the producer name of this data source is present
+      // in the name filters. We currently only support new filters, not
+      // removing old ones.
+      if (!NameMatchesFilter(producer->name_, new_producer_name_filter,
+                             new_producer_name_regex_filter)) {
+        continue;
+      }
+
+      // If this producer is already set up, we assume that all datasources
+      // in it started already.
+      if (set_up_producers.count(it->second.producer_id))
+        continue;
+
+      // If it wasn't previously setup, set it up now.
+      // (The per-producer config is optional).
+      TraceConfig::ProducerConfig producer_config;
+      for (auto& config : tracing_session->config.producers()) {
+        if (producer->name_ == config.producer_name()) {
+          producer_config = config;
+          break;
+        }
+      }
+
+      DataSourceInstance* ds_inst = SetupDataSource(
+          cfg_data_source, producer_config, it->second, tracing_session);
+
+      if (ds_inst && tracing_session->state == TracingSession::STARTED)
+        StartDataSourceInstance(producer, tracing_session, ds_inst);
+    }
+  }
+}
+
+base::Status TracingServiceImpl::StartTracing(TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    return PERFETTO_SVC_ERR(
+        "StartTracing() failed, invalid session ID %" PRIu64, tsid);
+  }
+
+  MaybeLogUploadEvent(tracing_session->config, tracing_session->trace_uuid,
+                      PerfettoStatsdAtom::kTracedStartTracing);
+
+  if (tracing_session->state != TracingSession::CONFIGURED) {
+    MaybeLogUploadEvent(
+        tracing_session->config, tracing_session->trace_uuid,
+        PerfettoStatsdAtom::kTracedStartTracingInvalidSessionState);
+    return PERFETTO_SVC_ERR("StartTracing() failed, invalid session state: %d",
+                            tracing_session->state);
+  }
+
+  tracing_session->state = TracingSession::STARTED;
+
+  // We store the start of trace snapshot separately as it's important to make
+  // sure we can interpret all the data in the trace and storing it in the ring
+  // buffer means it could be overwritten by a later snapshot.
+  if (!tracing_session->config.builtin_data_sources()
+           .disable_clock_snapshotting()) {
+    SnapshotClocks(&tracing_session->initial_clock_snapshot);
+  }
+
+  // We don't snapshot the clocks here because we just did this above.
+  SnapshotLifecyleEvent(
+      tracing_session,
+      protos::pbzero::TracingServiceEvent::kTracingStartedFieldNumber,
+      false /* snapshot_clocks */);
+
+  // Periodically snapshot clocks, stats, sync markers while the trace is
+  // active. The snapshots are emitted on the future ReadBuffers() calls, which
+  // means that:
+  //  (a) If we're streaming to a file (or to a consumer) while tracing, we
+  //      write snapshots periodically into the trace.
+  //  (b) If ReadBuffers() is only called after tracing ends, we emit the latest
+  //      snapshot into the trace. For clock snapshots, we keep track of the
+  //      snapshot recorded at the beginning of the session
+  //      (initial_clock_snapshot above), as well as the most recent sampled
+  //      snapshots that showed significant new drift between different clocks.
+  //      The latter clock snapshots are sampled periodically and at lifecycle
+  //      events.
+  base::PeriodicTask::Args snapshot_task_args;
+  snapshot_task_args.start_first_task_immediately = true;
+  snapshot_task_args.use_suspend_aware_timer =
+      tracing_session->config.builtin_data_sources()
+          .prefer_suspend_clock_for_snapshot();
+  snapshot_task_args.task = [weak_this, tsid] {
+    if (weak_this)
+      weak_this->PeriodicSnapshotTask(tsid);
+  };
+  snapshot_task_args.period_ms =
+      tracing_session->config.builtin_data_sources().snapshot_interval_ms();
+  if (!snapshot_task_args.period_ms)
+    snapshot_task_args.period_ms = kDefaultSnapshotsIntervalMs;
+  tracing_session->snapshot_periodic_task.Start(snapshot_task_args);
+
+  // Trigger delayed task if the trace is time limited.
+  const uint32_t trace_duration_ms = tracing_session->config.duration_ms();
+  if (trace_duration_ms > 0) {
+    auto stop_task =
+        std::bind(&TracingServiceImpl::StopOnDurationMsExpiry, weak_this, tsid);
+    if (tracing_session->config.prefer_suspend_clock_for_duration()) {
+      base::PeriodicTask::Args stop_args;
+      stop_args.use_suspend_aware_timer = true;
+      stop_args.period_ms = trace_duration_ms;
+      stop_args.one_shot = true;
+      stop_args.task = std::move(stop_task);
+      tracing_session->timed_stop_task.Start(stop_args);
+    } else {
+      task_runner_->PostDelayedTask(std::move(stop_task), trace_duration_ms);
+    }
+  }  // if (trace_duration_ms > 0).
+
+  // Start the periodic drain tasks if we should to save the trace into a file.
+  if (tracing_session->config.write_into_file()) {
+    task_runner_->PostDelayedTask(
+        [weak_this, tsid] {
+          if (weak_this)
+            weak_this->ReadBuffersIntoFile(tsid);
+        },
+        tracing_session->delay_to_next_write_period_ms());
+  }
+
+  // Start the periodic flush tasks if the config specified a flush period.
+  if (tracing_session->config.flush_period_ms())
+    PeriodicFlushTask(tsid, /*post_next_only=*/true);
+
+  // Start the periodic incremental state clear tasks if the config specified a
+  // period.
+  if (tracing_session->config.incremental_state_config().clear_period_ms()) {
+    PeriodicClearIncrementalStateTask(tsid, /*post_next_only=*/true);
+  }
+
+  for (auto& [prod_id, data_source] : tracing_session->data_source_instances) {
+    ProducerEndpointImpl* producer = GetProducer(prod_id);
+    if (!producer) {
+      PERFETTO_DFATAL("Producer does not exist.");
+      continue;
+    }
+    StartDataSourceInstance(producer, tracing_session, &data_source);
+  }
+
+  MaybeNotifyAllDataSourcesStarted(tracing_session);
+  return base::OkStatus();
+}
+
+// static
+void TracingServiceImpl::StopOnDurationMsExpiry(
+    base::WeakPtr<TracingServiceImpl> weak_this,
+    TracingSessionID tsid) {
+  // Skip entirely the flush if the trace session doesn't exist anymore.
+  // This is to prevent misleading error messages to be logged.
+  if (!weak_this)
+    return;
+  auto* tracing_session_ptr = weak_this->GetTracingSession(tsid);
+  if (!tracing_session_ptr)
+    return;
+  // If this trace was using STOP_TRACING triggers and we've seen
+  // one, then the trigger overrides the normal timeout. In this
+  // case we just return and let the other task clean up this trace.
+  if (GetTriggerMode(tracing_session_ptr->config) ==
+          TraceConfig::TriggerConfig::STOP_TRACING &&
+      !tracing_session_ptr->received_triggers.empty())
+    return;
+  // In all other cases (START_TRACING or no triggers) we flush
+  // after |trace_duration_ms| unconditionally.
+  weak_this->FlushAndDisableTracing(tsid);
+}
+
+void TracingServiceImpl::StartDataSourceInstance(
+    ProducerEndpointImpl* producer,
+    TracingSession* tracing_session,
+    TracingServiceImpl::DataSourceInstance* instance) {
+  PERFETTO_DCHECK(instance->state == DataSourceInstance::CONFIGURED);
+  if (instance->will_notify_on_start) {
+    instance->state = DataSourceInstance::STARTING;
+  } else {
+    instance->state = DataSourceInstance::STARTED;
+  }
+  if (tracing_session->consumer_maybe_null) {
+    tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
+        *producer, *instance);
+  }
+  producer->StartDataSource(instance->instance_id, instance->config);
+
+  // If all data sources are started, notify the consumer.
+  if (instance->state == DataSourceInstance::STARTED)
+    MaybeNotifyAllDataSourcesStarted(tracing_session);
+}
+
+// DisableTracing just stops the data sources but doesn't free up any buffer.
+// This is to allow the consumer to freeze the buffers (by stopping the trace)
+// and then drain the buffers. The actual teardown of the TracingSession happens
+// in FreeBuffers().
+void TracingServiceImpl::DisableTracing(TracingSessionID tsid,
+                                        bool disable_immediately) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    // Can happen if the consumer calls this before EnableTracing() or after
+    // FreeBuffers().
+    PERFETTO_DLOG("DisableTracing() failed, invalid session ID %" PRIu64, tsid);
+    return;
+  }
+
+  MaybeLogUploadEvent(tracing_session->config, tracing_session->trace_uuid,
+                      PerfettoStatsdAtom::kTracedDisableTracing);
+
+  switch (tracing_session->state) {
+    // Spurious call to DisableTracing() while already disabled, nothing to do.
+    case TracingSession::DISABLED:
+      PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
+      return;
+
+    case TracingSession::CLONED_READ_ONLY:
+      PERFETTO_DLOG("DisableTracing() cannot be called on a cloned session");
+      return;
+
+    // This is either:
+    // A) The case of a graceful DisableTracing() call followed by a call to
+    //    FreeBuffers(), iff |disable_immediately| == true. In this case we want
+    //    to forcefully transition in the disabled state without waiting for the
+    //    outstanding acks because the buffers are going to be destroyed soon.
+    // B) A spurious call, iff |disable_immediately| == false, in which case
+    //    there is nothing to do.
+    case TracingSession::DISABLING_WAITING_STOP_ACKS:
+      PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
+      if (disable_immediately)
+        DisableTracingNotifyConsumerAndFlushFile(tracing_session);
+      return;
+
+    // Continues below.
+    case TracingSession::CONFIGURED:
+      // If the session didn't even start there is no need to orchestrate a
+      // graceful stop of data sources.
+      disable_immediately = true;
+      break;
+
+    // This is the nominal case, continues below.
+    case TracingSession::STARTED:
+      break;
+  }
+
+  for (auto& data_source_inst : tracing_session->data_source_instances) {
+    const ProducerID producer_id = data_source_inst.first;
+    DataSourceInstance& instance = data_source_inst.second;
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    PERFETTO_DCHECK(producer);
+    PERFETTO_DCHECK(instance.state == DataSourceInstance::CONFIGURED ||
+                    instance.state == DataSourceInstance::STARTING ||
+                    instance.state == DataSourceInstance::STARTED);
+    StopDataSourceInstance(producer, tracing_session, &instance,
+                           disable_immediately);
+  }
+
+  // If the periodic task is running, we can stop the periodic snapshot timer
+  // here instead of waiting until FreeBuffers to prevent useless snapshots
+  // which won't be read.
+  tracing_session->snapshot_periodic_task.Reset();
+
+  // Either this request is flagged with |disable_immediately| or there are no
+  // data sources that are requesting a final handshake. In both cases just mark
+  // the session as disabled immediately, notify the consumer and flush the
+  // trace file (if used).
+  if (tracing_session->AllDataSourceInstancesStopped())
+    return DisableTracingNotifyConsumerAndFlushFile(tracing_session);
+
+  tracing_session->state = TracingSession::DISABLING_WAITING_STOP_ACKS;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      [weak_this, tsid] {
+        if (weak_this)
+          weak_this->OnDisableTracingTimeout(tsid);
+      },
+      tracing_session->data_source_stop_timeout_ms());
+
+  // Deliberately NOT removing the session from |tracing_session_|, it's still
+  // needed to call ReadBuffers(). FreeBuffers() will erase() the session.
+}
+
+void TracingServiceImpl::NotifyDataSourceStarted(
+    ProducerID producer_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (auto& kv : tracing_sessions_) {
+    TracingSession& tracing_session = kv.second;
+    DataSourceInstance* instance =
+        tracing_session.GetDataSourceInstance(producer_id, instance_id);
+
+    if (!instance)
+      continue;
+
+    // If the tracing session was already stopped, ignore this notification.
+    if (tracing_session.state != TracingSession::STARTED)
+      continue;
+
+    if (instance->state != DataSourceInstance::STARTING) {
+      PERFETTO_ELOG("Started data source instance in incorrect state: %d",
+                    instance->state);
+      continue;
+    }
+
+    instance->state = DataSourceInstance::STARTED;
+
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    PERFETTO_DCHECK(producer);
+    if (tracing_session.consumer_maybe_null) {
+      tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
+          *producer, *instance);
+    }
+
+    // If all data sources are started, notify the consumer.
+    MaybeNotifyAllDataSourcesStarted(&tracing_session);
+  }  // for (tracing_session)
+}
+
+void TracingServiceImpl::MaybeNotifyAllDataSourcesStarted(
+    TracingSession* tracing_session) {
+  if (!tracing_session->consumer_maybe_null)
+    return;
+
+  if (!tracing_session->AllDataSourceInstancesStarted())
+    return;
+
+  // In some rare cases, we can get in this state more than once. Consider the
+  // following scenario: 3 data sources are registered -> trace starts ->
+  // all 3 data sources ack -> OnAllDataSourcesStarted() is called.
+  // Imagine now that a 4th data source registers while the trace is ongoing.
+  // This would hit the AllDataSourceInstancesStarted() condition again.
+  // In this case, however, we don't want to re-notify the consumer again.
+  // That would be unexpected (even if, perhaps, technically correct) and
+  // trigger bugs in the consumer.
+  if (tracing_session->did_notify_all_data_source_started)
+    return;
+
+  PERFETTO_DLOG("All data sources started");
+
+  SnapshotLifecyleEvent(
+      tracing_session,
+      protos::pbzero::TracingServiceEvent::kAllDataSourcesStartedFieldNumber,
+      true /* snapshot_clocks */);
+
+  tracing_session->did_notify_all_data_source_started = true;
+  tracing_session->consumer_maybe_null->OnAllDataSourcesStarted();
+}
+
+void TracingServiceImpl::NotifyDataSourceStopped(
+    ProducerID producer_id,
+    DataSourceInstanceID instance_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (auto& kv : tracing_sessions_) {
+    TracingSession& tracing_session = kv.second;
+    DataSourceInstance* instance =
+        tracing_session.GetDataSourceInstance(producer_id, instance_id);
+
+    if (!instance)
+      continue;
+
+    if (instance->state != DataSourceInstance::STOPPING) {
+      PERFETTO_ELOG("Stopped data source instance in incorrect state: %d",
+                    instance->state);
+      continue;
+    }
+
+    instance->state = DataSourceInstance::STOPPED;
+
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    PERFETTO_DCHECK(producer);
+    if (tracing_session.consumer_maybe_null) {
+      tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
+          *producer, *instance);
+    }
+
+    if (!tracing_session.AllDataSourceInstancesStopped())
+      continue;
+
+    if (tracing_session.state != TracingSession::DISABLING_WAITING_STOP_ACKS)
+      continue;
+
+    // All data sources acked the termination.
+    DisableTracingNotifyConsumerAndFlushFile(&tracing_session);
+  }  // for (tracing_session)
+}
+
+void TracingServiceImpl::ActivateTriggers(
+    ProducerID producer_id,
+    const std::vector<std::string>& triggers) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto* producer = GetProducer(producer_id);
+  PERFETTO_DCHECK(producer);
+
+  int64_t now_ns = base::GetBootTimeNs().count();
+  for (const auto& trigger_name : triggers) {
+    PERFETTO_DLOG("Received ActivateTriggers request for \"%s\"",
+                  trigger_name.c_str());
+    base::Hasher hash;
+    hash.Update(trigger_name.c_str(), trigger_name.size());
+    std::string triggered_session_name;
+    base::Uuid triggered_session_uuid;
+    TracingSessionID triggered_session_id = 0;
+    auto trigger_mode = TraceConfig::TriggerConfig::UNSPECIFIED;
+
+    uint64_t trigger_name_hash = hash.digest();
+    size_t count_in_window =
+        PurgeExpiredAndCountTriggerInWindow(now_ns, trigger_name_hash);
+
+    bool trigger_matched = false;
+    bool trigger_activated = false;
+    for (auto& id_and_tracing_session : tracing_sessions_) {
+      auto& tracing_session = id_and_tracing_session.second;
+      TracingSessionID tsid = id_and_tracing_session.first;
+      auto iter = std::find_if(
+          tracing_session.config.trigger_config().triggers().begin(),
+          tracing_session.config.trigger_config().triggers().end(),
+          [&trigger_name](const TraceConfig::TriggerConfig::Trigger& trigger) {
+            return trigger.name() == trigger_name;
+          });
+      if (iter == tracing_session.config.trigger_config().triggers().end())
+        continue;
+      if (tracing_session.state == TracingSession::CLONED_READ_ONLY)
+        continue;
+
+      // If this trigger requires a certain producer to have sent it
+      // (non-empty producer_name()) ensure the producer who sent this trigger
+      // matches.
+      if (!iter->producer_name_regex().empty() &&
+          !std::regex_match(
+              producer->name_,
+              std::regex(iter->producer_name_regex(), std::regex::extended))) {
+        continue;
+      }
+
+      // Use a random number between 0 and 1 to check if we should allow this
+      // trigger through or not.
+      double trigger_rnd =
+          trigger_rnd_override_for_testing_ > 0
+              ? trigger_rnd_override_for_testing_
+              : trigger_probability_dist_(trigger_probability_rand_);
+      PERFETTO_DCHECK(trigger_rnd >= 0 && trigger_rnd < 1);
+      if (trigger_rnd < iter->skip_probability()) {
+        MaybeLogTriggerEvent(tracing_session.config,
+                             PerfettoTriggerAtom::kTracedLimitProbability,
+                             trigger_name);
+        continue;
+      }
+
+      // If we already triggered more times than the limit, silently ignore
+      // this trigger.
+      if (iter->max_per_24_h() > 0 && count_in_window >= iter->max_per_24_h()) {
+        MaybeLogTriggerEvent(tracing_session.config,
+                             PerfettoTriggerAtom::kTracedLimitMaxPer24h,
+                             trigger_name);
+        continue;
+      }
+      trigger_matched = true;
+      triggered_session_id = tracing_session.id;
+      triggered_session_name = tracing_session.config.unique_session_name();
+      triggered_session_uuid.set_lsb_msb(tracing_session.trace_uuid.lsb(),
+                                         tracing_session.trace_uuid.msb());
+      trigger_mode = GetTriggerMode(tracing_session.config);
+
+      const bool triggers_already_received =
+          !tracing_session.received_triggers.empty();
+      tracing_session.received_triggers.push_back(
+          {static_cast<uint64_t>(now_ns), iter->name(), producer->name_,
+           producer->uid()});
+      auto weak_this = weak_ptr_factory_.GetWeakPtr();
+      switch (trigger_mode) {
+        case TraceConfig::TriggerConfig::START_TRACING:
+          // If the session has already been triggered and moved past
+          // CONFIGURED then we don't need to repeat StartTracing. This would
+          // work fine (StartTracing would return false) but would add error
+          // logs.
+          if (tracing_session.state != TracingSession::CONFIGURED)
+            break;
+
+          trigger_activated = true;
+          MaybeLogUploadEvent(
+              tracing_session.config, tracing_session.trace_uuid,
+              PerfettoStatsdAtom::kTracedTriggerStartTracing, iter->name());
+
+          // We override the trace duration to be the trigger's requested
+          // value, this ensures that the trace will end after this amount
+          // of time has passed.
+          tracing_session.config.set_duration_ms(iter->stop_delay_ms());
+          StartTracing(tsid);
+          break;
+        case TraceConfig::TriggerConfig::STOP_TRACING:
+          // Only stop the trace once to avoid confusing log messages. I.E.
+          // when we've already hit the first trigger we've already Posted the
+          // task to FlushAndDisable. So all future triggers will just break
+          // out.
+          if (triggers_already_received)
+            break;
+
+          trigger_activated = true;
+          MaybeLogUploadEvent(
+              tracing_session.config, tracing_session.trace_uuid,
+              PerfettoStatsdAtom::kTracedTriggerStopTracing, iter->name());
+
+          // Now that we've seen a trigger we need to stop, flush, and disable
+          // this session after the configured |stop_delay_ms|.
+          task_runner_->PostDelayedTask(
+              [weak_this, tsid] {
+                // Skip entirely the flush if the trace session doesn't exist
+                // anymore. This is to prevent misleading error messages to be
+                // logged.
+                if (weak_this && weak_this->GetTracingSession(tsid))
+                  weak_this->FlushAndDisableTracing(tsid);
+              },
+              // If this trigger is zero this will immediately executable and
+              // will happen shortly.
+              iter->stop_delay_ms());
+          break;
+
+        case TraceConfig::TriggerConfig::CLONE_SNAPSHOT:
+          trigger_activated = true;
+          MaybeLogUploadEvent(
+              tracing_session.config, tracing_session.trace_uuid,
+              PerfettoStatsdAtom::kTracedTriggerCloneSnapshot, iter->name());
+          task_runner_->PostDelayedTask(
+              [weak_this, tsid] {
+                if (!weak_this)
+                  return;
+                auto* tsess = weak_this->GetTracingSession(tsid);
+                if (!tsess || !tsess->consumer_maybe_null)
+                  return;
+                tsess->consumer_maybe_null->NotifyCloneSnapshotTrigger();
+              },
+              iter->stop_delay_ms());
+          break;
+
+        case TraceConfig::TriggerConfig::UNSPECIFIED:
+          PERFETTO_ELOG("Trigger activated but trigger mode unspecified.");
+          break;
+      }
+    }  // for (.. : tracing_sessions_)
+
+    if (trigger_matched) {
+      trigger_history_.emplace_back(TriggerHistory{now_ns, trigger_name_hash});
+    }
+
+    if (trigger_activated) {
+      // Log only the trigger that actually caused a trace stop/start, don't log
+      // the follow-up ones, even if they matched.
+      PERFETTO_LOG(
+          "Trace trigger activated: trigger_name=\"%s\" trigger_mode=%d "
+          "trace_name=\"%s\" trace_uuid=\"%s\" tsid=%" PRIu64,
+          trigger_name.c_str(), trigger_mode, triggered_session_name.c_str(),
+          triggered_session_uuid.ToPrettyString().c_str(),
+          triggered_session_id);
+    }
+  }  // for (trigger_name : triggers)
+}
+
+// Always invoked TraceConfig.data_source_stop_timeout_ms (by default
+// kDataSourceStopTimeoutMs) after DisableTracing(). In nominal conditions all
+// data sources should have acked the stop and this will early out.
+void TracingServiceImpl::OnDisableTracingTimeout(TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session ||
+      tracing_session->state != TracingSession::DISABLING_WAITING_STOP_ACKS) {
+    return;  // Tracing session was successfully disabled.
+  }
+
+  PERFETTO_ILOG("Timeout while waiting for ACKs for tracing session %" PRIu64,
+                tsid);
+  PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
+  DisableTracingNotifyConsumerAndFlushFile(tracing_session);
+}
+
+void TracingServiceImpl::DisableTracingNotifyConsumerAndFlushFile(
+    TracingSession* tracing_session) {
+  PERFETTO_DCHECK(tracing_session->state != TracingSession::DISABLED);
+  for (auto& inst_kv : tracing_session->data_source_instances) {
+    if (inst_kv.second.state == DataSourceInstance::STOPPED)
+      continue;
+    inst_kv.second.state = DataSourceInstance::STOPPED;
+    ProducerEndpointImpl* producer = GetProducer(inst_kv.first);
+    PERFETTO_DCHECK(producer);
+    if (tracing_session->consumer_maybe_null) {
+      tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
+          *producer, inst_kv.second);
+    }
+  }
+  tracing_session->state = TracingSession::DISABLED;
+
+  // Scrape any remaining chunks that weren't flushed by the producers.
+  for (auto& producer_id_and_producer : producers_)
+    ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);
+
+  SnapshotLifecyleEvent(
+      tracing_session,
+      protos::pbzero::TracingServiceEvent::kTracingDisabledFieldNumber,
+      true /* snapshot_clocks */);
+
+  if (tracing_session->write_into_file) {
+    tracing_session->write_period_ms = 0;
+    ReadBuffersIntoFile(tracing_session->id);
+  }
+
+  MaybeLogUploadEvent(tracing_session->config, tracing_session->trace_uuid,
+                      PerfettoStatsdAtom::kTracedNotifyTracingDisabled);
+
+  if (tracing_session->consumer_maybe_null)
+    tracing_session->consumer_maybe_null->NotifyOnTracingDisabled("");
+}
+
+void TracingServiceImpl::Flush(TracingSessionID tsid,
+                               uint32_t timeout_ms,
+                               ConsumerEndpoint::FlushCallback callback,
+                               FlushFlags flush_flags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    PERFETTO_DLOG("Flush() failed, invalid session ID %" PRIu64, tsid);
+    return;
+  }
+
+  if (!timeout_ms)
+    timeout_ms = tracing_session->flush_timeout_ms();
+
+  if (tracing_session->pending_flushes.size() > 1000) {
+    PERFETTO_ELOG("Too many flushes (%zu) pending for the tracing session",
+                  tracing_session->pending_flushes.size());
+    callback(false);
+    return;
+  }
+
+  if (tracing_session->state != TracingSession::STARTED) {
+    PERFETTO_ELOG("Flush() called, but tracing has not been started");
+    callback(false);
+    return;
+  }
+
+  ++tracing_session->flushes_requested;
+  FlushRequestID flush_request_id = ++last_flush_request_id_;
+  PendingFlush& pending_flush =
+      tracing_session->pending_flushes
+          .emplace_hint(tracing_session->pending_flushes.end(),
+                        flush_request_id, PendingFlush(std::move(callback)))
+          ->second;
+
+  // Send a flush request to each producer involved in the tracing session. In
+  // order to issue a flush request we have to build a map of all data source
+  // instance ids enabled for each producer.
+
+  std::map<ProducerID, std::vector<DataSourceInstanceID>> flush_map;
+  for (const auto& kv : tracing_session->data_source_instances) {
+    const ProducerID producer_id = kv.first;
+    const DataSourceInstance& ds_inst = kv.second;
+    if (ds_inst.no_flush)
+      continue;
+    flush_map[producer_id].push_back(ds_inst.instance_id);
+  }
+
+  for (const auto& kv : flush_map) {
+    ProducerID producer_id = kv.first;
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    const std::vector<DataSourceInstanceID>& data_sources = kv.second;
+    producer->Flush(flush_request_id, data_sources, flush_flags);
+    pending_flush.producers.insert(producer_id);
+  }
+
+  // If there are no producers to flush (realistically this happens only in
+  // some tests) fire OnFlushTimeout() straight away, without waiting.
+  if (flush_map.empty())
+    timeout_ms = 0;
+
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      [weak_this, tsid, flush_request_id] {
+        if (weak_this)
+          weak_this->OnFlushTimeout(tsid, flush_request_id);
+      },
+      timeout_ms);
+}
+
+void TracingServiceImpl::NotifyFlushDoneForProducer(
+    ProducerID producer_id,
+    FlushRequestID flush_request_id) {
+  for (auto& kv : tracing_sessions_) {
+    // Remove all pending flushes <= |flush_request_id| for |producer_id|.
+    auto& pending_flushes = kv.second.pending_flushes;
+    auto end_it = pending_flushes.upper_bound(flush_request_id);
+    for (auto it = pending_flushes.begin(); it != end_it;) {
+      PendingFlush& pending_flush = it->second;
+      pending_flush.producers.erase(producer_id);
+      if (pending_flush.producers.empty()) {
+        auto weak_this = weak_ptr_factory_.GetWeakPtr();
+        TracingSessionID tsid = kv.first;
+        auto callback = std::move(pending_flush.callback);
+        task_runner_->PostTask([weak_this, tsid, callback]() {
+          if (weak_this) {
+            weak_this->CompleteFlush(tsid, std::move(callback),
+                                     /*success=*/true);
+          }
+        });
+        it = pending_flushes.erase(it);
+      } else {
+        it++;
+      }
+    }  // for (pending_flushes)
+  }    // for (tracing_session)
+}
+
+void TracingServiceImpl::OnFlushTimeout(TracingSessionID tsid,
+                                        FlushRequestID flush_request_id) {
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session)
+    return;
+  auto it = tracing_session->pending_flushes.find(flush_request_id);
+  if (it == tracing_session->pending_flushes.end())
+    return;  // Nominal case: flush was completed and acked on time.
+
+  // If there were no producers to flush, consider it a success.
+  bool success = it->second.producers.empty();
+  auto callback = std::move(it->second.callback);
+  tracing_session->pending_flushes.erase(it);
+  CompleteFlush(tsid, std::move(callback), success);
+}
+
+void TracingServiceImpl::CompleteFlush(TracingSessionID tsid,
+                                       ConsumerEndpoint::FlushCallback callback,
+                                       bool success) {
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    callback(false);
+    return;
+  }
+  // Producers may not have been able to flush all their data, even if they
+  // indicated flush completion. If possible, also collect uncommitted chunks
+  // to make sure we have everything they wrote so far.
+  for (auto& producer_id_and_producer : producers_) {
+    ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);
+  }
+  SnapshotLifecyleEvent(
+      tracing_session,
+      protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
+      true /* snapshot_clocks */);
+
+  tracing_session->flushes_succeeded += success ? 1 : 0;
+  tracing_session->flushes_failed += success ? 0 : 1;
+  callback(success);
+}
+
+void TracingServiceImpl::ScrapeSharedMemoryBuffers(
+    TracingSession* tracing_session,
+    ProducerEndpointImpl* producer) {
+  if (!producer->smb_scraping_enabled_)
+    return;
+
+  // Can't copy chunks if we don't know about any trace writers.
+  if (producer->writers_.empty())
+    return;
+
+  // Performance optimization: On flush or session disconnect, this method is
+  // called for each producer. If the producer doesn't participate in the
+  // session, there's no need to scape its chunks right now. We can tell if a
+  // producer participates in the session by checking if the producer is allowed
+  // to write into the session's log buffers.
+  const auto& session_buffers = tracing_session->buffers_index;
+  bool producer_in_session =
+      std::any_of(session_buffers.begin(), session_buffers.end(),
+                  [producer](BufferID buffer_id) {
+                    return producer->allowed_target_buffers_.count(buffer_id);
+                  });
+  if (!producer_in_session)
+    return;
+
+  PERFETTO_DLOG("Scraping SMB for producer %" PRIu16, producer->id_);
+
+  // Find and copy any uncommitted chunks from the SMB.
+  //
+  // In nominal conditions, the page layout of the used SMB pages should never
+  // change because the service is the only one who is supposed to modify used
+  // pages (to make them free again).
+  //
+  // However, the code here needs to deal with the case of a malicious producer
+  // altering the SMB in unpredictable ways. Thankfully the SMB size is
+  // immutable, so a chunk will always point to some valid memory, even if the
+  // producer alters the intended layout and chunk header concurrently.
+  // Ultimately a malicious producer altering the SMB's chunk layout while we
+  // are iterating in this function is not any different from the case of a
+  // malicious producer asking to commit a chunk made of random data, which is
+  // something this class has to deal with regardless.
+  //
+  // The only legitimate mutations that can happen from sane producers,
+  // concurrently to this function, are:
+  //   A. free pages being partitioned,
+  //   B. free chunks being migrated to kChunkBeingWritten,
+  //   C. kChunkBeingWritten chunks being migrated to kChunkCompleted.
+
+  SharedMemoryABI* abi = &producer->shmem_abi_;
+  // num_pages() is immutable after the SMB is initialized and cannot be changed
+  // even by a producer even if malicious.
+  for (size_t page_idx = 0; page_idx < abi->num_pages(); page_idx++) {
+    uint32_t layout = abi->GetPageLayout(page_idx);
+
+    uint32_t used_chunks = abi->GetUsedChunks(layout);  // Returns a bitmap.
+    // Skip empty pages.
+    if (used_chunks == 0)
+      continue;
+
+    // Scrape the chunks that are currently used. These should be either in
+    // state kChunkBeingWritten or kChunkComplete.
+    for (uint32_t chunk_idx = 0; used_chunks; chunk_idx++, used_chunks >>= 1) {
+      if (!(used_chunks & 1))
+        continue;
+
+      SharedMemoryABI::ChunkState state =
+          SharedMemoryABI::GetChunkStateFromLayout(layout, chunk_idx);
+      PERFETTO_DCHECK(state == SharedMemoryABI::kChunkBeingWritten ||
+                      state == SharedMemoryABI::kChunkComplete);
+      bool chunk_complete = state == SharedMemoryABI::kChunkComplete;
+
+      SharedMemoryABI::Chunk chunk =
+          abi->GetChunkUnchecked(page_idx, layout, chunk_idx);
+
+      uint16_t packet_count;
+      uint8_t flags;
+      // GetPacketCountAndFlags has acquire_load semantics.
+      std::tie(packet_count, flags) = chunk.GetPacketCountAndFlags();
+
+      // It only makes sense to copy an incomplete chunk if there's at least
+      // one full packet available. (The producer may not have completed the
+      // last packet in it yet, so we need at least 2.)
+      if (!chunk_complete && packet_count < 2)
+        continue;
+
+      // At this point, it is safe to access the remaining header fields of
+      // the chunk. Even if the chunk was only just transferred from
+      // kChunkFree into kChunkBeingWritten state, the header should be
+      // written completely once the packet count increased above 1 (it was
+      // reset to 0 by the service when the chunk was freed).
+
+      WriterID writer_id = chunk.writer_id();
+      std::optional<BufferID> target_buffer_id =
+          producer->buffer_id_for_writer(writer_id);
+
+      // We can only scrape this chunk if we know which log buffer to copy it
+      // into.
+      if (!target_buffer_id)
+        continue;
+
+      // Skip chunks that don't belong to the requested tracing session.
+      bool target_buffer_belongs_to_session =
+          std::find(session_buffers.begin(), session_buffers.end(),
+                    *target_buffer_id) != session_buffers.end();
+      if (!target_buffer_belongs_to_session)
+        continue;
+
+      uint32_t chunk_id =
+          chunk.header()->chunk_id.load(std::memory_order_relaxed);
+
+      CopyProducerPageIntoLogBuffer(
+          producer->id_, producer->client_identity_, writer_id, chunk_id,
+          *target_buffer_id, packet_count, flags, chunk_complete,
+          chunk.payload_begin(), chunk.payload_size());
+    }
+  }
+}
+
+void TracingServiceImpl::FlushAndDisableTracing(TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Triggering final flush for %" PRIu64, tsid);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  Flush(
+      tsid, 0,
+      [weak_this, tsid](bool success) {
+        // This was a DLOG up to Jun 2021 (v16, Android S).
+        PERFETTO_LOG("FlushAndDisableTracing(%" PRIu64 ") done, success=%d",
+                     tsid, success);
+        if (!weak_this)
+          return;
+        TracingSession* session = weak_this->GetTracingSession(tsid);
+        if (!session) {
+          return;
+        }
+        session->final_flush_outcome = success
+                                           ? TraceStats::FINAL_FLUSH_SUCCEEDED
+                                           : TraceStats::FINAL_FLUSH_FAILED;
+        if (session->consumer_maybe_null) {
+          // If the consumer is still attached, just disable the session but
+          // give it a chance to read the contents.
+          weak_this->DisableTracing(tsid);
+        } else {
+          // If the consumer detached, destroy the session. If the consumer did
+          // start the session in long-tracing mode, the service will have saved
+          // the contents to the passed file. If not, the contents will be
+          // destroyed.
+          weak_this->FreeBuffers(tsid);
+        }
+      },
+      FlushFlags(FlushFlags::Initiator::kTraced,
+                 FlushFlags::Reason::kTraceStop));
+}
+
+void TracingServiceImpl::PeriodicFlushTask(TracingSessionID tsid,
+                                           bool post_next_only) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session || tracing_session->state != TracingSession::STARTED)
+    return;
+
+  uint32_t flush_period_ms = tracing_session->config.flush_period_ms();
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      [weak_this, tsid] {
+        if (weak_this)
+          weak_this->PeriodicFlushTask(tsid, /*post_next_only=*/false);
+      },
+      flush_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
+                                              flush_period_ms));
+
+  if (post_next_only)
+    return;
+
+  PERFETTO_DLOG("Triggering periodic flush for trace session %" PRIu64, tsid);
+  Flush(
+      tsid, 0,
+      [](bool success) {
+        if (!success)
+          PERFETTO_ELOG("Periodic flush timed out");
+      },
+      FlushFlags(FlushFlags::Initiator::kTraced,
+                 FlushFlags::Reason::kPeriodic));
+}
+
+void TracingServiceImpl::PeriodicClearIncrementalStateTask(
+    TracingSessionID tsid,
+    bool post_next_only) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session || tracing_session->state != TracingSession::STARTED)
+    return;
+
+  uint32_t clear_period_ms =
+      tracing_session->config.incremental_state_config().clear_period_ms();
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      [weak_this, tsid] {
+        if (weak_this)
+          weak_this->PeriodicClearIncrementalStateTask(
+              tsid, /*post_next_only=*/false);
+      },
+      clear_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
+                                              clear_period_ms));
+
+  if (post_next_only)
+    return;
+
+  PERFETTO_DLOG(
+      "Performing periodic incremental state clear for trace session %" PRIu64,
+      tsid);
+
+  // Queue the IPCs to producers with active data sources that opted in.
+  std::map<ProducerID, std::vector<DataSourceInstanceID>> clear_map;
+  for (const auto& kv : tracing_session->data_source_instances) {
+    ProducerID producer_id = kv.first;
+    const DataSourceInstance& data_source = kv.second;
+    if (data_source.handles_incremental_state_clear) {
+      clear_map[producer_id].push_back(data_source.instance_id);
+    }
+  }
+
+  for (const auto& kv : clear_map) {
+    ProducerID producer_id = kv.first;
+    const std::vector<DataSourceInstanceID>& data_sources = kv.second;
+    ProducerEndpointImpl* producer = GetProducer(producer_id);
+    if (!producer) {
+      PERFETTO_DFATAL("Producer does not exist.");
+      continue;
+    }
+    producer->ClearIncrementalState(data_sources);
+  }
+}
+
+bool TracingServiceImpl::ReadBuffersIntoConsumer(
+    TracingSessionID tsid,
+    ConsumerEndpointImpl* consumer) {
+  PERFETTO_DCHECK(consumer);
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    PERFETTO_DLOG(
+        "Cannot ReadBuffersIntoConsumer(): no tracing session is active");
+    return false;
+  }
+
+  if (tracing_session->write_into_file) {
+    // If the consumer enabled tracing and asked to save the contents into the
+    // passed file makes little sense to also try to read the buffers over IPC,
+    // as that would just steal data from the periodic draining task.
+    PERFETTO_ELOG("Consumer trying to read from write_into_file session.");
+    return false;
+  }
+
+  if (IsWaitingForTrigger(tracing_session))
+    return false;
+
+  // This is a rough threshold to determine how much to read from the buffer in
+  // each task. This is to avoid executing a single huge sending task for too
+  // long and risk to hit the watchdog. This is *not* an upper bound: we just
+  // stop accumulating new packets and PostTask *after* we cross this threshold.
+  // This constant essentially balances the PostTask and IPC overhead vs the
+  // responsiveness of the service. An extremely small value will cause one IPC
+  // and one PostTask for each slice but will keep the service extremely
+  // responsive. An extremely large value will batch the send for the full
+  // buffer in one large task, will hit the blocking send() once the socket
+  // buffers are full and hang the service for a bit (until the consumer
+  // catches up).
+  static constexpr size_t kApproxBytesPerTask = 32768;
+  bool has_more;
+  std::vector<TracePacket> packets =
+      ReadBuffers(tracing_session, kApproxBytesPerTask, &has_more);
+
+  if (has_more) {
+    auto weak_consumer = consumer->weak_ptr_factory_.GetWeakPtr();
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostTask([weak_this, weak_consumer, tsid] {
+      if (!weak_this || !weak_consumer)
+        return;
+      weak_this->ReadBuffersIntoConsumer(tsid, weak_consumer.get());
+    });
+  }
+
+  // Keep this as tail call, just in case the consumer re-enters.
+  consumer->consumer_->OnTraceData(std::move(packets), has_more);
+  return true;
+}
+
+bool TracingServiceImpl::ReadBuffersIntoFile(TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    // This will be hit systematically from the PostDelayedTask. Avoid logging,
+    // it would be just spam.
+    return false;
+  }
+
+  // This can happen if the file is closed by a previous task because it reaches
+  // |max_file_size_bytes|.
+  if (!tracing_session->write_into_file)
+    return false;
+
+  if (IsWaitingForTrigger(tracing_session))
+    return false;
+
+  // ReadBuffers() can allocate memory internally, for filtering. By limiting
+  // the data that ReadBuffers() reads to kWriteIntoChunksSize per iteration,
+  // we limit the amount of memory used on each iteration.
+  //
+  // It would be tempting to split this into multiple tasks like in
+  // ReadBuffersIntoConsumer, but that's not currently possible.
+  // ReadBuffersIntoFile has to read the whole available data before returning,
+  // to support the disable_immediately=true code paths.
+  bool has_more = true;
+  bool stop_writing_into_file = false;
+  do {
+    std::vector<TracePacket> packets =
+        ReadBuffers(tracing_session, kWriteIntoFileChunkSize, &has_more);
+
+    stop_writing_into_file = WriteIntoFile(tracing_session, std::move(packets));
+  } while (has_more && !stop_writing_into_file);
+
+  if (stop_writing_into_file || tracing_session->write_period_ms == 0) {
+    // Ensure all data was written to the file before we close it.
+    base::FlushFile(tracing_session->write_into_file.get());
+    tracing_session->write_into_file.reset();
+    tracing_session->write_period_ms = 0;
+    if (tracing_session->state == TracingSession::STARTED)
+      DisableTracing(tsid);
+    return true;
+  }
+
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostDelayedTask(
+      [weak_this, tsid] {
+        if (weak_this)
+          weak_this->ReadBuffersIntoFile(tsid);
+      },
+      tracing_session->delay_to_next_write_period_ms());
+  return true;
+}
+
+bool TracingServiceImpl::IsWaitingForTrigger(TracingSession* tracing_session) {
+  // Ignore the logic below for cloned tracing sessions. In this case we
+  // actually want to read the (cloned) trace buffers even if no trigger was
+  // hit.
+  if (tracing_session->state == TracingSession::CLONED_READ_ONLY) {
+    return false;
+  }
+
+  // When a tracing session is waiting for a trigger, it is considered empty. If
+  // a tracing session finishes and moves into DISABLED without ever receiving a
+  // trigger, the trace should never return any data. This includes the
+  // synthetic packets like TraceConfig and Clock snapshots. So we bail out
+  // early and let the consumer know there is no data.
+  if (!tracing_session->config.trigger_config().triggers().empty() &&
+      tracing_session->received_triggers.empty()) {
+    PERFETTO_DLOG(
+        "ReadBuffers(): tracing session has not received a trigger yet.");
+    return true;
+  }
+
+  // Traces with CLONE_SNAPSHOT triggers are a special case of the above. They
+  // can be read only via a CloneSession() request. This is to keep the
+  // behavior consistent with the STOP_TRACING+triggers case and avoid periodic
+  // finalizations and uploads of the main CLONE_SNAPSHOT triggers.
+  if (GetTriggerMode(tracing_session->config) ==
+      TraceConfig::TriggerConfig::CLONE_SNAPSHOT) {
+    PERFETTO_DLOG(
+        "ReadBuffers(): skipping because the tracing session has "
+        "CLONE_SNAPSHOT triggers defined");
+    return true;
+  }
+
+  return false;
+}
+
+std::vector<TracePacket> TracingServiceImpl::ReadBuffers(
+    TracingSession* tracing_session,
+    size_t threshold,
+    bool* has_more) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(tracing_session);
+  *has_more = false;
+
+  std::vector<TracePacket> packets;
+  packets.reserve(1024);  // Just an educated guess to avoid trivial expansions.
+
+  if (!tracing_session->initial_clock_snapshot.empty()) {
+    EmitClockSnapshot(tracing_session,
+                      std::move(tracing_session->initial_clock_snapshot),
+                      &packets);
+  }
+
+  for (auto& snapshot : tracing_session->clock_snapshot_ring_buffer) {
+    PERFETTO_DCHECK(!snapshot.empty());
+    EmitClockSnapshot(tracing_session, std::move(snapshot), &packets);
+  }
+  tracing_session->clock_snapshot_ring_buffer.clear();
+
+  if (tracing_session->should_emit_sync_marker) {
+    EmitSyncMarker(&packets);
+    tracing_session->should_emit_sync_marker = false;
+  }
+
+  if (!tracing_session->config.builtin_data_sources().disable_trace_config()) {
+    MaybeEmitTraceConfig(tracing_session, &packets);
+    MaybeEmitReceivedTriggers(tracing_session, &packets);
+  }
+  if (!tracing_session->did_emit_initial_packets) {
+    EmitUuid(tracing_session, &packets);
+    if (!tracing_session->config.builtin_data_sources().disable_system_info())
+      EmitSystemInfo(&packets);
+  }
+  tracing_session->did_emit_initial_packets = true;
+
+  // Note that in the proto comment, we guarantee that the tracing_started
+  // lifecycle event will be emitted before any data packets so make sure to
+  // keep this before reading the tracing buffers.
+  if (!tracing_session->config.builtin_data_sources().disable_service_events())
+    EmitLifecycleEvents(tracing_session, &packets);
+
+  size_t packets_bytes = 0;  // SUM(slice.size() for each slice in |packets|).
+
+  // Add up size for packets added by the Maybe* calls above.
+  for (const TracePacket& packet : packets) {
+    packets_bytes += packet.size();
+  }
+
+  bool did_hit_threshold = false;
+
+  for (size_t buf_idx = 0;
+       buf_idx < tracing_session->num_buffers() && !did_hit_threshold;
+       buf_idx++) {
+    auto tbuf_iter = buffers_.find(tracing_session->buffers_index[buf_idx]);
+    if (tbuf_iter == buffers_.end()) {
+      PERFETTO_DFATAL("Buffer not found.");
+      continue;
+    }
+    TraceBuffer& tbuf = *tbuf_iter->second;
+    tbuf.BeginRead();
+    while (!did_hit_threshold) {
+      TracePacket packet;
+      TraceBuffer::PacketSequenceProperties sequence_properties{};
+      bool previous_packet_dropped;
+      if (!tbuf.ReadNextTracePacket(&packet, &sequence_properties,
+                                    &previous_packet_dropped)) {
+        break;
+      }
+      packet.set_buffer_index_for_stats(static_cast<uint32_t>(buf_idx));
+      PERFETTO_DCHECK(sequence_properties.producer_id_trusted != 0);
+      PERFETTO_DCHECK(sequence_properties.writer_id != 0);
+      PERFETTO_DCHECK(sequence_properties.client_identity_trusted.has_uid());
+      // Not checking sequence_properties.client_identity_trusted.has_pid():
+      // it is false if the platform doesn't support it.
+
+      PERFETTO_DCHECK(packet.size() > 0);
+      if (!PacketStreamValidator::Validate(packet.slices())) {
+        tracing_session->invalid_packets++;
+        PERFETTO_DLOG("Dropping invalid packet");
+        continue;
+      }
+
+      // Append a slice with the trusted field data. This can't be spoofed
+      // because above we validated that the existing slices don't contain any
+      // trusted fields. For added safety we append instead of prepending
+      // because according to protobuf semantics, if the same field is
+      // encountered multiple times the last instance takes priority. Note that
+      // truncated packets are also rejected, so the producer can't give us a
+      // partial packet (e.g., a truncated string) which only becomes valid when
+      // the trusted data is appended here.
+      Slice slice = Slice::Allocate(32);
+      protozero::StaticBuffered<protos::pbzero::TracePacket> trusted_packet(
+          slice.own_data(), slice.size);
+      const auto& client_identity_trusted =
+          sequence_properties.client_identity_trusted;
+      trusted_packet->set_trusted_uid(
+          static_cast<int32_t>(client_identity_trusted.uid()));
+      trusted_packet->set_trusted_packet_sequence_id(
+          tracing_session->GetPacketSequenceID(
+              client_identity_trusted.machine_id(),
+              sequence_properties.producer_id_trusted,
+              sequence_properties.writer_id));
+      if (client_identity_trusted.has_pid()) {
+        // Not supported on all platforms.
+        trusted_packet->set_trusted_pid(
+            static_cast<int32_t>(client_identity_trusted.pid()));
+      }
+      if (client_identity_trusted.has_non_default_machine_id()) {
+        trusted_packet->set_machine_id(client_identity_trusted.machine_id());
+      }
+      if (previous_packet_dropped)
+        trusted_packet->set_previous_packet_dropped(previous_packet_dropped);
+      slice.size = trusted_packet.Finalize();
+      packet.AddSlice(std::move(slice));
+
+      // Append the packet (inclusive of the trusted uid) to |packets|.
+      packets_bytes += packet.size();
+      did_hit_threshold = packets_bytes >= threshold;
+      packets.emplace_back(std::move(packet));
+    }  // for(packets...)
+  }    // for(buffers...)
+
+  *has_more = did_hit_threshold;
+
+  // Only emit the "read complete" lifetime event when there is no more trace
+  // data available to read. These events are used as safe points to limit
+  // sorting in trace processor: the code shouldn't emit the event unless the
+  // buffers are empty.
+  if (!*has_more && !tracing_session->config.builtin_data_sources()
+                         .disable_service_events()) {
+    // We don't bother snapshotting clocks here because we wouldn't be able to
+    // emit it and we shouldn't have significant drift from the last snapshot in
+    // any case.
+    SnapshotLifecyleEvent(tracing_session,
+                          protos::pbzero::TracingServiceEvent::
+                              kReadTracingBuffersCompletedFieldNumber,
+                          false /* snapshot_clocks */);
+    EmitLifecycleEvents(tracing_session, &packets);
+  }
+
+  // Only emit the stats when there is no more trace data is available to read.
+  // That way, any problems that occur while reading from the buffers are
+  // reflected in the emitted stats. This is particularly important for use
+  // cases where ReadBuffers is only ever called after the tracing session is
+  // stopped.
+  if (!*has_more && tracing_session->should_emit_stats) {
+    EmitStats(tracing_session, &packets);
+    tracing_session->should_emit_stats = false;
+  }
+
+  MaybeFilterPackets(tracing_session, &packets);
+
+  MaybeCompressPackets(tracing_session, &packets);
+
+  if (!*has_more) {
+    // We've observed some extremely high memory usage by scudo after
+    // MaybeFilterPackets in the past. The original bug (b/195145848) is fixed
+    // now, but this code asks scudo to release memory just in case.
+    base::MaybeReleaseAllocatorMemToOS();
+  }
+
+  return packets;
+}
+
+void TracingServiceImpl::MaybeFilterPackets(TracingSession* tracing_session,
+                                            std::vector<TracePacket>* packets) {
+  // If the tracing session specified a filter, run all packets through the
+  // filter and replace them with the filter results.
+  // The process below mantains the cardinality of input packets. Even if an
+  // entire packet is filtered out, we emit a zero-sized TracePacket proto. That
+  // makes debugging and reasoning about the trace stats easier.
+  // This place swaps the contents of each |packets| entry in place.
+  if (!tracing_session->trace_filter) {
+    return;
+  }
+  protozero::MessageFilter& trace_filter = *tracing_session->trace_filter;
+  // The filter root should be reset from protos.Trace to protos.TracePacket
+  // by the earlier call to SetFilterRoot() in EnableTracing().
+  PERFETTO_DCHECK(trace_filter.config().root_msg_index() != 0);
+  std::vector<protozero::MessageFilter::InputSlice> filter_input;
+  auto start = base::GetWallTimeNs();
+  for (TracePacket& packet : *packets) {
+    const auto& packet_slices = packet.slices();
+    const size_t input_packet_size = packet.size();
+    filter_input.clear();
+    filter_input.resize(packet_slices.size());
+    ++tracing_session->filter_input_packets;
+    tracing_session->filter_input_bytes += input_packet_size;
+    for (size_t i = 0; i < packet_slices.size(); ++i)
+      filter_input[i] = {packet_slices[i].start, packet_slices[i].size};
+    auto filtered_packet = trace_filter.FilterMessageFragments(
+        &filter_input[0], filter_input.size());
+
+    // Replace the packet in-place with the filtered one (unless failed).
+    std::optional<uint32_t> maybe_buffer_idx = packet.buffer_index_for_stats();
+    packet = TracePacket();
+    if (filtered_packet.error) {
+      ++tracing_session->filter_errors;
+      PERFETTO_DLOG("Trace packet filtering failed @ packet %" PRIu64,
+                    tracing_session->filter_input_packets);
+      continue;
+    }
+    tracing_session->filter_output_bytes += filtered_packet.size;
+    if (maybe_buffer_idx.has_value()) {
+      // Keep the per-buffer stats updated. Also propagate the
+      // buffer_index_for_stats in the output packet to allow accounting by
+      // other parts of the ReadBuffer pipeline.
+      uint32_t buffer_idx = maybe_buffer_idx.value();
+      packet.set_buffer_index_for_stats(buffer_idx);
+      auto& vec = tracing_session->filter_bytes_discarded_per_buffer;
+      if (static_cast<size_t>(buffer_idx) >= vec.size())
+        vec.resize(buffer_idx + 1);
+      PERFETTO_DCHECK(input_packet_size >= filtered_packet.size);
+      size_t bytes_filtered_out = input_packet_size - filtered_packet.size;
+      vec[buffer_idx] += bytes_filtered_out;
+    }
+    AppendOwnedSlicesToPacket(std::move(filtered_packet.data),
+                              filtered_packet.size, kMaxTracePacketSliceSize,
+                              &packet);
+  }
+  auto end = base::GetWallTimeNs();
+  tracing_session->filter_time_taken_ns +=
+      static_cast<uint64_t>((end - start).count());
+}
+
+void TracingServiceImpl::MaybeCompressPackets(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  if (!tracing_session->compress_deflate) {
+    return;
+  }
+
+  init_opts_.compressor_fn(packets);
+}
+
+bool TracingServiceImpl::WriteIntoFile(TracingSession* tracing_session,
+                                       std::vector<TracePacket> packets) {
+  if (!tracing_session->write_into_file) {
+    return false;
+  }
+  const uint64_t max_size = tracing_session->max_file_size_bytes
+                                ? tracing_session->max_file_size_bytes
+                                : std::numeric_limits<size_t>::max();
+
+  size_t total_slices = 0;
+  for (const TracePacket& packet : packets) {
+    total_slices += packet.slices().size();
+  }
+  // When writing into a file, the file should look like a root trace.proto
+  // message. Each packet should be prepended with a proto preamble stating
+  // its field id (within trace.proto) and size. Hence the addition below.
+  const size_t max_iovecs = total_slices + packets.size();
+
+  size_t num_iovecs = 0;
+  bool stop_writing_into_file = false;
+  std::unique_ptr<struct iovec[]> iovecs(new struct iovec[max_iovecs]);
+  size_t num_iovecs_at_last_packet = 0;
+  uint64_t bytes_about_to_be_written = 0;
+  for (TracePacket& packet : packets) {
+    std::tie(iovecs[num_iovecs].iov_base, iovecs[num_iovecs].iov_len) =
+        packet.GetProtoPreamble();
+    bytes_about_to_be_written += iovecs[num_iovecs].iov_len;
+    num_iovecs++;
+    for (const Slice& slice : packet.slices()) {
+      // writev() doesn't change the passed pointer. However, struct iovec
+      // take a non-const ptr because it's the same struct used by readv().
+      // Hence the const_cast here.
+      char* start = static_cast<char*>(const_cast<void*>(slice.start));
+      bytes_about_to_be_written += slice.size;
+      iovecs[num_iovecs++] = {start, slice.size};
+    }
+
+    if (tracing_session->bytes_written_into_file + bytes_about_to_be_written >=
+        max_size) {
+      stop_writing_into_file = true;
+      num_iovecs = num_iovecs_at_last_packet;
+      break;
+    }
+
+    num_iovecs_at_last_packet = num_iovecs;
+  }
+  PERFETTO_DCHECK(num_iovecs <= max_iovecs);
+  int fd = *tracing_session->write_into_file;
+
+  uint64_t total_wr_size = 0;
+
+  // writev() can take at most IOV_MAX entries per call. Batch them.
+  constexpr size_t kIOVMax = IOV_MAX;
+  for (size_t i = 0; i < num_iovecs; i += kIOVMax) {
+    int iov_batch_size = static_cast<int>(std::min(num_iovecs - i, kIOVMax));
+    ssize_t wr_size = PERFETTO_EINTR(writev(fd, &iovecs[i], iov_batch_size));
+    if (wr_size <= 0) {
+      PERFETTO_PLOG("writev() failed");
+      stop_writing_into_file = true;
+      break;
+    }
+    total_wr_size += static_cast<size_t>(wr_size);
+  }
+
+  tracing_session->bytes_written_into_file += total_wr_size;
+
+  PERFETTO_DLOG("Draining into file, written: %" PRIu64 " KB, stop: %d",
+                (total_wr_size + 1023) / 1024, stop_writing_into_file);
+  return stop_writing_into_file;
+}
+
+void TracingServiceImpl::FreeBuffers(TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Freeing buffers for session %" PRIu64, tsid);
+  TracingSession* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session) {
+    PERFETTO_DLOG("FreeBuffers() failed, invalid session ID %" PRIu64, tsid);
+    return;  // TODO(primiano): signal failure?
+  }
+  DisableTracing(tsid, /*disable_immediately=*/true);
+
+  PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
+  tracing_session->data_source_instances.clear();
+
+  for (auto& producer_entry : producers_) {
+    ProducerEndpointImpl* producer = producer_entry.second;
+    producer->OnFreeBuffers(tracing_session->buffers_index);
+  }
+
+  for (BufferID buffer_id : tracing_session->buffers_index) {
+    buffer_ids_.Free(buffer_id);
+    PERFETTO_DCHECK(buffers_.count(buffer_id) == 1);
+    buffers_.erase(buffer_id);
+  }
+  bool notify_traceur =
+      tracing_session->config.notify_traceur() &&
+      tracing_session->state != TracingSession::CLONED_READ_ONLY;
+  bool is_long_trace =
+      (tracing_session->config.write_into_file() &&
+       tracing_session->config.file_write_period_ms() < kMillisPerDay);
+  tracing_sessions_.erase(tsid);
+  tracing_session = nullptr;
+  UpdateMemoryGuardrail();
+
+  PERFETTO_LOG("Tracing session %" PRIu64 " ended, total sessions:%zu", tsid,
+               tracing_sessions_.size());
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) && \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  if (notify_traceur && is_long_trace) {
+    PERFETTO_LAZY_LOAD(android_internal::NotifyTraceSessionEnded, notify_fn);
+    if (!notify_fn || !notify_fn(/*session_stolen=*/false))
+      PERFETTO_ELOG("Failed to notify Traceur long tracing has ended");
+  }
+#else
+  base::ignore_result(notify_traceur);
+  base::ignore_result(is_long_trace);
+#endif
+}
+
+void TracingServiceImpl::RegisterDataSource(ProducerID producer_id,
+                                            const DataSourceDescriptor& desc) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (desc.name().empty()) {
+    PERFETTO_DLOG("Received RegisterDataSource() with empty name");
+    return;
+  }
+
+  ProducerEndpointImpl* producer = GetProducer(producer_id);
+  if (!producer) {
+    PERFETTO_DFATAL("Producer not found.");
+    return;
+  }
+
+  // Check that the producer doesn't register two data sources with the same ID.
+  // Note that we tolerate |id| == 0 because until Android T / v22 the |id|
+  // field didn't exist.
+  for (const auto& kv : data_sources_) {
+    if (desc.id() && kv.second.producer_id == producer_id &&
+        kv.second.descriptor.id() == desc.id()) {
+      PERFETTO_ELOG(
+          "Failed to register data source \"%s\". A data source with the same "
+          "id %" PRIu64 " (name=\"%s\") is already registered for producer %d",
+          desc.name().c_str(), desc.id(), kv.second.descriptor.name().c_str(),
+          producer_id);
+      return;
+    }
+  }
+
+  PERFETTO_DLOG("Producer %" PRIu16 " registered data source \"%s\"",
+                producer_id, desc.name().c_str());
+
+  auto reg_ds = data_sources_.emplace(desc.name(),
+                                      RegisteredDataSource{producer_id, desc});
+
+  // If there are existing tracing sessions, we need to check if the new
+  // data source is enabled by any of them.
+  for (auto& iter : tracing_sessions_) {
+    TracingSession& tracing_session = iter.second;
+    if (tracing_session.state != TracingSession::STARTED &&
+        tracing_session.state != TracingSession::CONFIGURED) {
+      continue;
+    }
+
+    TraceConfig::ProducerConfig producer_config;
+    for (auto& config : tracing_session.config.producers()) {
+      if (producer->name_ == config.producer_name()) {
+        producer_config = config;
+        break;
+      }
+    }
+    for (const TraceConfig::DataSource& cfg_data_source :
+         tracing_session.config.data_sources()) {
+      if (cfg_data_source.config().name() != desc.name())
+        continue;
+      DataSourceInstance* ds_inst = SetupDataSource(
+          cfg_data_source, producer_config, reg_ds->second, &tracing_session);
+      if (ds_inst && tracing_session.state == TracingSession::STARTED)
+        StartDataSourceInstance(producer, &tracing_session, ds_inst);
+    }
+  }  // for(iter : tracing_sessions_)
+}
+
+void TracingServiceImpl::UpdateDataSource(
+    ProducerID producer_id,
+    const DataSourceDescriptor& new_desc) {
+  if (new_desc.id() == 0) {
+    PERFETTO_ELOG("UpdateDataSource() must have a non-zero id");
+    return;
+  }
+
+  // If this producer has already registered a matching descriptor name and id,
+  // just update the descriptor.
+  RegisteredDataSource* data_source = nullptr;
+  auto range = data_sources_.equal_range(new_desc.name());
+  for (auto it = range.first; it != range.second; ++it) {
+    if (it->second.producer_id == producer_id &&
+        it->second.descriptor.id() == new_desc.id()) {
+      data_source = &it->second;
+      break;
+    }
+  }
+
+  if (!data_source) {
+    PERFETTO_ELOG(
+        "UpdateDataSource() failed, could not find an existing data source "
+        "with name=\"%s\" id=%" PRIu64,
+        new_desc.name().c_str(), new_desc.id());
+    return;
+  }
+
+  data_source->descriptor = new_desc;
+}
+
+void TracingServiceImpl::StopDataSourceInstance(ProducerEndpointImpl* producer,
+                                                TracingSession* tracing_session,
+                                                DataSourceInstance* instance,
+                                                bool disable_immediately) {
+  const DataSourceInstanceID ds_inst_id = instance->instance_id;
+  if (instance->will_notify_on_stop && !disable_immediately) {
+    instance->state = DataSourceInstance::STOPPING;
+  } else {
+    instance->state = DataSourceInstance::STOPPED;
+  }
+  if (tracing_session->consumer_maybe_null) {
+    tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
+        *producer, *instance);
+  }
+  producer->StopDataSource(ds_inst_id);
+}
+
+void TracingServiceImpl::UnregisterDataSource(ProducerID producer_id,
+                                              const std::string& name) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Producer %" PRIu16 " unregistered data source \"%s\"",
+                producer_id, name.c_str());
+  PERFETTO_CHECK(producer_id);
+  ProducerEndpointImpl* producer = GetProducer(producer_id);
+  PERFETTO_DCHECK(producer);
+  for (auto& kv : tracing_sessions_) {
+    auto& ds_instances = kv.second.data_source_instances;
+    bool removed = false;
+    for (auto it = ds_instances.begin(); it != ds_instances.end();) {
+      if (it->first == producer_id && it->second.data_source_name == name) {
+        DataSourceInstanceID ds_inst_id = it->second.instance_id;
+        if (it->second.state != DataSourceInstance::STOPPED) {
+          if (it->second.state != DataSourceInstance::STOPPING) {
+            StopDataSourceInstance(producer, &kv.second, &it->second,
+                                   /* disable_immediately = */ false);
+          }
+
+          // Mark the instance as stopped immediately, since we are
+          // unregistering it below.
+          //
+          //  The StopDataSourceInstance above might have set the state to
+          //  STOPPING so this condition isn't an else.
+          if (it->second.state == DataSourceInstance::STOPPING)
+            NotifyDataSourceStopped(producer_id, ds_inst_id);
+        }
+        it = ds_instances.erase(it);
+        removed = true;
+      } else {
+        ++it;
+      }
+    }  // for (data_source_instances)
+    if (removed)
+      MaybeNotifyAllDataSourcesStarted(&kv.second);
+  }  // for (tracing_session)
+
+  for (auto it = data_sources_.begin(); it != data_sources_.end(); ++it) {
+    if (it->second.producer_id == producer_id &&
+        it->second.descriptor.name() == name) {
+      data_sources_.erase(it);
+      return;
+    }
+  }
+
+  PERFETTO_DFATAL(
+      "Tried to unregister a non-existent data source \"%s\" for "
+      "producer %" PRIu16,
+      name.c_str(), producer_id);
+}
+
+TracingServiceImpl::DataSourceInstance* TracingServiceImpl::SetupDataSource(
+    const TraceConfig::DataSource& cfg_data_source,
+    const TraceConfig::ProducerConfig& producer_config,
+    const RegisteredDataSource& data_source,
+    TracingSession* tracing_session) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  ProducerEndpointImpl* producer = GetProducer(data_source.producer_id);
+  PERFETTO_DCHECK(producer);
+  // An existing producer that is not ftrace could have registered itself as
+  // ftrace, we must not enable it in that case.
+  if (lockdown_mode_ && producer->uid() != uid_) {
+    PERFETTO_DLOG("Lockdown mode: not enabling producer %hu", producer->id_);
+    return nullptr;
+  }
+  // TODO(primiano): Add tests for registration ordering (data sources vs
+  // consumers).
+  if (!NameMatchesFilter(producer->name_,
+                         cfg_data_source.producer_name_filter(),
+                         cfg_data_source.producer_name_regex_filter())) {
+    PERFETTO_DLOG("Data source: %s is filtered out for producer: %s",
+                  cfg_data_source.config().name().c_str(),
+                  producer->name_.c_str());
+    return nullptr;
+  }
+
+  auto relative_buffer_id = cfg_data_source.config().target_buffer();
+  if (relative_buffer_id >= tracing_session->num_buffers()) {
+    PERFETTO_LOG(
+        "The TraceConfig for DataSource %s specified a target_buffer out of "
+        "bound (%d). Skipping it.",
+        cfg_data_source.config().name().c_str(), relative_buffer_id);
+    return nullptr;
+  }
+
+  // Create a copy of the DataSourceConfig specified in the trace config. This
+  // will be passed to the producer after translating the |target_buffer| id.
+  // The |target_buffer| parameter passed by the consumer in the trace config is
+  // relative to the buffers declared in the same trace config. This has to be
+  // translated to the global BufferID before passing it to the producers, which
+  // don't know anything about tracing sessions and consumers.
+
+  DataSourceInstanceID inst_id = ++last_data_source_instance_id_;
+  auto insert_iter = tracing_session->data_source_instances.emplace(
+      std::piecewise_construct,  //
+      std::forward_as_tuple(producer->id_),
+      std::forward_as_tuple(
+          inst_id,
+          cfg_data_source.config(),  //  Deliberate copy.
+          data_source.descriptor.name(),
+          data_source.descriptor.will_notify_on_start(),
+          data_source.descriptor.will_notify_on_stop(),
+          data_source.descriptor.handles_incremental_state_clear(),
+          data_source.descriptor.no_flush()));
+  DataSourceInstance* ds_instance = &insert_iter->second;
+
+  // New data source instance starts out in CONFIGURED state.
+  if (tracing_session->consumer_maybe_null) {
+    tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
+        *producer, *ds_instance);
+  }
+
+  DataSourceConfig& ds_config = ds_instance->config;
+  ds_config.set_trace_duration_ms(tracing_session->config.duration_ms());
+
+  // Rationale for `if (prefer) set_prefer(true)`, rather than `set(prefer)`:
+  // ComputeStartupConfigHash() in tracing_muxer_impl.cc compares hashes of the
+  // DataSourceConfig and expects to know (and clear) the fields generated by
+  // the tracing service. Unconditionally adding a new field breaks backward
+  // compatibility of startup tracing with older SDKs, because the serialization
+  // also propagates unkonwn fields, breaking the hash matching check.
+  if (tracing_session->config.prefer_suspend_clock_for_duration())
+    ds_config.set_prefer_suspend_clock_for_duration(true);
+
+  ds_config.set_stop_timeout_ms(tracing_session->data_source_stop_timeout_ms());
+  ds_config.set_enable_extra_guardrails(
+      tracing_session->config.enable_extra_guardrails());
+  if (tracing_session->consumer_uid == 1066 /* AID_STATSD */ &&
+      tracing_session->config.statsd_metadata().triggering_config_uid() !=
+          2000 /* AID_SHELL */
+      && tracing_session->config.statsd_metadata().triggering_config_uid() !=
+             0 /* AID_ROOT */) {
+    // StatsD can be triggered either by shell, root or an app that has DUMP and
+    // USAGE_STATS permission. When triggered by shell or root, we do not want
+    // to consider the trace a trusted system trace, as it was initiated by the
+    // user. Otherwise, it has to come from an app with DUMP and
+    // PACKAGE_USAGE_STATS, which has to be preinstalled and trusted by the
+    // system.
+    // Check for shell / root: https://bit.ly/3b7oZNi
+    // Check for DUMP or PACKAGE_USAGE_STATS: https://bit.ly/3ep0NrR
+    ds_config.set_session_initiator(
+        DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM);
+  } else {
+    // Unset in case the consumer set it.
+    // We need to be able to trust this field.
+    ds_config.set_session_initiator(
+        DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
+  }
+  ds_config.set_tracing_session_id(tracing_session->id);
+  BufferID global_id = tracing_session->buffers_index[relative_buffer_id];
+  PERFETTO_DCHECK(global_id);
+  ds_config.set_target_buffer(global_id);
+
+  PERFETTO_DLOG("Setting up data source %s with target buffer %" PRIu16,
+                ds_config.name().c_str(), global_id);
+  if (!producer->shared_memory()) {
+    // Determine the SMB page size. Must be an integer multiple of 4k.
+    // As for the SMB size below, the decision tree is as follows:
+    // 1. Give priority to what is defined in the trace config.
+    // 2. If unset give priority to the hint passed by the producer.
+    // 3. Keep within bounds and ensure it's a multiple of 4k.
+    size_t page_size = producer_config.page_size_kb() * 1024;
+    if (page_size == 0)
+      page_size = producer->shmem_page_size_hint_bytes_;
+
+    // Determine the SMB size. Must be an integer multiple of the SMB page size.
+    // The decision tree is as follows:
+    // 1. Give priority to what defined in the trace config.
+    // 2. If unset give priority to the hint passed by the producer.
+    // 3. Keep within bounds and ensure it's a multiple of the page size.
+    size_t shm_size = producer_config.shm_size_kb() * 1024;
+    if (shm_size == 0)
+      shm_size = producer->shmem_size_hint_bytes_;
+
+    auto valid_sizes = EnsureValidShmSizes(shm_size, page_size);
+    if (valid_sizes != std::tie(shm_size, page_size)) {
+      PERFETTO_DLOG(
+          "Invalid configured SMB sizes: shm_size %zu page_size %zu. Falling "
+          "back to shm_size %zu page_size %zu.",
+          shm_size, page_size, std::get<0>(valid_sizes),
+          std::get<1>(valid_sizes));
+    }
+    std::tie(shm_size, page_size) = valid_sizes;
+
+    // TODO(primiano): right now Create() will suicide in case of OOM if the
+    // mmap fails. We should instead gracefully fail the request and tell the
+    // client to go away.
+    PERFETTO_DLOG("Creating SMB of %zu KB for producer \"%s\"", shm_size / 1024,
+                  producer->name_.c_str());
+    auto shared_memory = shm_factory_->CreateSharedMemory(shm_size);
+    producer->SetupSharedMemory(std::move(shared_memory), page_size,
+                                /*provided_by_producer=*/false);
+  }
+  producer->SetupDataSource(inst_id, ds_config);
+  return ds_instance;
+}
+
+// Note: all the fields % *_trusted ones are untrusted, as in, the Producer
+// might be lying / returning garbage contents. |src| and |size| can be trusted
+// in terms of being a valid pointer, but not the contents.
+void TracingServiceImpl::CopyProducerPageIntoLogBuffer(
+    ProducerID producer_id_trusted,
+    const ClientIdentity& client_identity_trusted,
+    WriterID writer_id,
+    ChunkID chunk_id,
+    BufferID buffer_id,
+    uint16_t num_fragments,
+    uint8_t chunk_flags,
+    bool chunk_complete,
+    const uint8_t* src,
+    size_t size) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  ProducerEndpointImpl* producer = GetProducer(producer_id_trusted);
+  if (!producer) {
+    PERFETTO_DFATAL("Producer not found.");
+    chunks_discarded_++;
+    return;
+  }
+
+  TraceBuffer* buf = GetBufferByID(buffer_id);
+  if (!buf) {
+    PERFETTO_DLOG("Could not find target buffer %" PRIu16
+                  " for producer %" PRIu16,
+                  buffer_id, producer_id_trusted);
+    chunks_discarded_++;
+    return;
+  }
+
+  // Verify that the producer is actually allowed to write into the target
+  // buffer specified in the request. This prevents a malicious producer from
+  // injecting data into a log buffer that belongs to a tracing session the
+  // producer is not part of.
+  if (!producer->is_allowed_target_buffer(buffer_id)) {
+    PERFETTO_ELOG("Producer %" PRIu16
+                  " tried to write into forbidden target buffer %" PRIu16,
+                  producer_id_trusted, buffer_id);
+    PERFETTO_DFATAL("Forbidden target buffer");
+    chunks_discarded_++;
+    return;
+  }
+
+  // If the writer was registered by the producer, it should only write into the
+  // buffer it was registered with.
+  std::optional<BufferID> associated_buffer =
+      producer->buffer_id_for_writer(writer_id);
+  if (associated_buffer && *associated_buffer != buffer_id) {
+    PERFETTO_ELOG("Writer %" PRIu16 " of producer %" PRIu16
+                  " was registered to write into target buffer %" PRIu16
+                  ", but tried to write into buffer %" PRIu16,
+                  writer_id, producer_id_trusted, *associated_buffer,
+                  buffer_id);
+    PERFETTO_DFATAL("Wrong target buffer");
+    chunks_discarded_++;
+    return;
+  }
+
+  buf->CopyChunkUntrusted(producer_id_trusted, client_identity_trusted,
+                          writer_id, chunk_id, num_fragments, chunk_flags,
+                          chunk_complete, src, size);
+}
+
+void TracingServiceImpl::ApplyChunkPatches(
+    ProducerID producer_id_trusted,
+    const std::vector<CommitDataRequest::ChunkToPatch>& chunks_to_patch) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  for (const auto& chunk : chunks_to_patch) {
+    const ChunkID chunk_id = static_cast<ChunkID>(chunk.chunk_id());
+    const WriterID writer_id = static_cast<WriterID>(chunk.writer_id());
+    TraceBuffer* buf =
+        GetBufferByID(static_cast<BufferID>(chunk.target_buffer()));
+    static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
+                  "Add a '|| chunk_id > kMaxChunkID' below if this fails");
+    if (!writer_id || writer_id > kMaxWriterID || !buf) {
+      // This can genuinely happen when the trace is stopped. The producers
+      // might see the stop signal with some delay and try to keep sending
+      // patches left soon after.
+      PERFETTO_DLOG(
+          "Received invalid chunks_to_patch request from Producer: %" PRIu16
+          ", BufferID: %" PRIu32 " ChunkdID: %" PRIu32 " WriterID: %" PRIu16,
+          producer_id_trusted, chunk.target_buffer(), chunk_id, writer_id);
+      patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
+      continue;
+    }
+
+    // Note, there's no need to validate that the producer is allowed to write
+    // to the specified buffer ID (or that it's the correct buffer ID for a
+    // registered TraceWriter). That's because TraceBuffer uses the producer ID
+    // and writer ID to look up the chunk to patch. If the producer specifies an
+    // incorrect buffer, this lookup will fail and TraceBuffer will ignore the
+    // patches. Because the producer ID is trusted, there's also no way for a
+    // malicious producer to patch another producer's data.
+
+    // Speculate on the fact that there are going to be a limited amount of
+    // patches per request, so we can allocate the |patches| array on the stack.
+    std::array<TraceBuffer::Patch, 1024> patches;  // Uninitialized.
+    if (chunk.patches().size() > patches.size()) {
+      PERFETTO_ELOG("Too many patches (%zu) batched in the same request",
+                    patches.size());
+      PERFETTO_DFATAL("Too many patches");
+      patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
+      continue;
+    }
+
+    size_t i = 0;
+    for (const auto& patch : chunk.patches()) {
+      const std::string& patch_data = patch.data();
+      if (patch_data.size() != patches[i].data.size()) {
+        PERFETTO_ELOG("Received patch from producer: %" PRIu16
+                      " of unexpected size %zu",
+                      producer_id_trusted, patch_data.size());
+        patches_discarded_++;
+        continue;
+      }
+      patches[i].offset_untrusted = patch.offset();
+      memcpy(&patches[i].data[0], patch_data.data(), patches[i].data.size());
+      i++;
+    }
+    buf->TryPatchChunkContents(producer_id_trusted, writer_id, chunk_id,
+                               &patches[0], i, chunk.has_more_patches());
+  }
+}
+
+TracingServiceImpl::TracingSession* TracingServiceImpl::GetDetachedSession(
+    uid_t uid,
+    const std::string& key) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  for (auto& kv : tracing_sessions_) {
+    TracingSession* session = &kv.second;
+    if (session->consumer_uid == uid && session->detach_key == key) {
+      PERFETTO_DCHECK(session->consumer_maybe_null == nullptr);
+      return session;
+    }
+  }
+  return nullptr;
+}
+
+TracingServiceImpl::TracingSession* TracingServiceImpl::GetTracingSession(
+    TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto it = tsid ? tracing_sessions_.find(tsid) : tracing_sessions_.end();
+  if (it == tracing_sessions_.end())
+    return nullptr;
+  return &it->second;
+}
+
+TracingServiceImpl::TracingSession*
+TracingServiceImpl::FindTracingSessionWithMaxBugreportScore() {
+  TracingSession* max_session = nullptr;
+  for (auto& session_id_and_session : tracing_sessions_) {
+    auto& session = session_id_and_session.second;
+    const int32_t score = session.config.bugreport_score();
+    // Exclude sessions with 0 (or below) score. By default tracing sessions
+    // should NOT be eligible to be attached to bugreports.
+    if (score <= 0 || session.state != TracingSession::STARTED)
+      continue;
+
+    if (!max_session || score > max_session->config.bugreport_score())
+      max_session = &session;
+  }
+  return max_session;
+}
+
+ProducerID TracingServiceImpl::GetNextProducerID() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_CHECK(producers_.size() < kMaxProducerID);
+  do {
+    ++last_producer_id_;
+  } while (producers_.count(last_producer_id_) || last_producer_id_ == 0);
+  PERFETTO_DCHECK(last_producer_id_ > 0 && last_producer_id_ <= kMaxProducerID);
+  return last_producer_id_;
+}
+
+TraceBuffer* TracingServiceImpl::GetBufferByID(BufferID buffer_id) {
+  auto buf_iter = buffers_.find(buffer_id);
+  if (buf_iter == buffers_.end())
+    return nullptr;
+  return &*buf_iter->second;
+}
+
+void TracingServiceImpl::OnStartTriggersTimeout(TracingSessionID tsid) {
+  // Skip entirely the flush if the trace session doesn't exist anymore.
+  // This is to prevent misleading error messages to be logged.
+  //
+  // if the trace has started from the trigger we rely on
+  // the |stop_delay_ms| from the trigger so don't flush and
+  // disable if we've moved beyond a CONFIGURED state
+  auto* tracing_session_ptr = GetTracingSession(tsid);
+  if (tracing_session_ptr &&
+      tracing_session_ptr->state == TracingSession::CONFIGURED) {
+    PERFETTO_DLOG("Disabling TracingSession %" PRIu64
+                  " since no triggers activated.",
+                  tsid);
+    // No data should be returned from ReadBuffers() regardless of if we
+    // call FreeBuffers() or DisableTracing(). This is because in
+    // STOP_TRACING we need this promise in either case, and using
+    // DisableTracing() allows a graceful shutdown. Consumers can follow
+    // their normal path and check the buffers through ReadBuffers() and
+    // the code won't hang because the tracing session will still be
+    // alive just disabled.
+    DisableTracing(tsid);
+  }
+}
+
+void TracingServiceImpl::UpdateMemoryGuardrail() {
+#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
+  uint64_t total_buffer_bytes = 0;
+
+  // Sum up all the shared memory buffers.
+  for (const auto& id_to_producer : producers_) {
+    if (id_to_producer.second->shared_memory())
+      total_buffer_bytes += id_to_producer.second->shared_memory()->size();
+  }
+
+  // Sum up all the trace buffers.
+  for (const auto& id_to_buffer : buffers_) {
+    total_buffer_bytes += id_to_buffer.second->size();
+  }
+
+  // Set the guard rail to 32MB + the sum of all the buffers over a 30 second
+  // interval.
+  uint64_t guardrail = base::kWatchdogDefaultMemorySlack + total_buffer_bytes;
+  base::Watchdog::GetInstance()->SetMemoryLimit(guardrail, 30 * 1000);
+#endif
+}
+
+void TracingServiceImpl::PeriodicSnapshotTask(TracingSessionID tsid) {
+  auto* tracing_session = GetTracingSession(tsid);
+  if (!tracing_session)
+    return;
+  if (tracing_session->state != TracingSession::STARTED)
+    return;
+  tracing_session->should_emit_sync_marker = true;
+  tracing_session->should_emit_stats = true;
+  MaybeSnapshotClocksIntoRingBuffer(tracing_session);
+}
+
+void TracingServiceImpl::SnapshotLifecyleEvent(TracingSession* tracing_session,
+                                               uint32_t field_id,
+                                               bool snapshot_clocks) {
+  // field_id should be an id of a field in TracingServiceEvent.
+  auto& lifecycle_events = tracing_session->lifecycle_events;
+  auto event_it =
+      std::find_if(lifecycle_events.begin(), lifecycle_events.end(),
+                   [field_id](const TracingSession::LifecycleEvent& event) {
+                     return event.field_id == field_id;
+                   });
+
+  TracingSession::LifecycleEvent* event;
+  if (event_it == lifecycle_events.end()) {
+    lifecycle_events.emplace_back(field_id);
+    event = &lifecycle_events.back();
+  } else {
+    event = &*event_it;
+  }
+
+  // Snapshot the clocks before capturing the timestamp for the event so we can
+  // use this snapshot to resolve the event timestamp if necessary.
+  if (snapshot_clocks)
+    MaybeSnapshotClocksIntoRingBuffer(tracing_session);
+
+  // Erase before emplacing to prevent a unncessary doubling of memory if
+  // not needed.
+  if (event->timestamps.size() >= event->max_size) {
+    event->timestamps.erase_front(1 + event->timestamps.size() -
+                                  event->max_size);
+  }
+  event->timestamps.emplace_back(base::GetBootTimeNs().count());
+}
+
+void TracingServiceImpl::MaybeSnapshotClocksIntoRingBuffer(
+    TracingSession* tracing_session) {
+  if (tracing_session->config.builtin_data_sources()
+          .disable_clock_snapshotting()) {
+    return;
+  }
+
+  // We are making an explicit copy of the latest snapshot (if it exists)
+  // because SnapshotClocks reads this data and computes the drift based on its
+  // content. If the clock drift is high enough, it will update the contents of
+  // |snapshot| and return true. Otherwise, it will return false.
+  TracingSession::ClockSnapshotData snapshot =
+      tracing_session->clock_snapshot_ring_buffer.empty()
+          ? TracingSession::ClockSnapshotData()
+          : tracing_session->clock_snapshot_ring_buffer.back();
+  bool did_update = SnapshotClocks(&snapshot);
+  if (did_update) {
+    // This means clocks drifted enough since last snapshot. See the comment
+    // in SnapshotClocks.
+    auto* snapshot_buffer = &tracing_session->clock_snapshot_ring_buffer;
+
+    // Erase before emplacing to prevent a unncessary doubling of memory if
+    // not needed.
+    static constexpr uint32_t kClockSnapshotRingBufferSize = 16;
+    if (snapshot_buffer->size() >= kClockSnapshotRingBufferSize) {
+      snapshot_buffer->erase_front(1 + snapshot_buffer->size() -
+                                   kClockSnapshotRingBufferSize);
+    }
+    snapshot_buffer->emplace_back(std::move(snapshot));
+  }
+}
+
+// Returns true when the data in |snapshot_data| is updated with the new state
+// of the clocks and false otherwise.
+bool TracingServiceImpl::SnapshotClocks(
+    TracingSession::ClockSnapshotData* snapshot_data) {
+  // Minimum drift that justifies replacing a prior clock snapshot that hasn't
+  // been emitted into the trace yet (see comment below).
+  static constexpr int64_t kSignificantDriftNs = 10 * 1000 * 1000;  // 10 ms
+
+  TracingSession::ClockSnapshotData new_snapshot_data;
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&   \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+  struct {
+    clockid_t id;
+    protos::pbzero::BuiltinClock type;
+    struct timespec ts;
+  } clocks[] = {
+      {CLOCK_BOOTTIME, protos::pbzero::BUILTIN_CLOCK_BOOTTIME, {0, 0}},
+      {CLOCK_REALTIME_COARSE,
+       protos::pbzero::BUILTIN_CLOCK_REALTIME_COARSE,
+       {0, 0}},
+      {CLOCK_MONOTONIC_COARSE,
+       protos::pbzero::BUILTIN_CLOCK_MONOTONIC_COARSE,
+       {0, 0}},
+      {CLOCK_REALTIME, protos::pbzero::BUILTIN_CLOCK_REALTIME, {0, 0}},
+      {CLOCK_MONOTONIC, protos::pbzero::BUILTIN_CLOCK_MONOTONIC, {0, 0}},
+      {CLOCK_MONOTONIC_RAW,
+       protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW,
+       {0, 0}},
+  };
+  // First snapshot all the clocks as atomically as we can.
+  for (auto& clock : clocks) {
+    if (clock_gettime(clock.id, &clock.ts) == -1)
+      PERFETTO_DLOG("clock_gettime failed for clock %d", clock.id);
+  }
+  for (auto& clock : clocks) {
+    new_snapshot_data.push_back(std::make_pair(
+        static_cast<uint32_t>(clock.type),
+        static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count())));
+  }
+#else  // OS_APPLE || OS_WIN && OS_NACL
+  auto wall_time_ns = static_cast<uint64_t>(base::GetWallTimeNs().count());
+  // The default trace clock is boot time, so we always need to emit a path to
+  // it. However since we don't actually have a boot time source on these
+  // platforms, pretend that wall time equals boot time.
+  new_snapshot_data.push_back(
+      std::make_pair(protos::pbzero::BUILTIN_CLOCK_BOOTTIME, wall_time_ns));
+  new_snapshot_data.push_back(
+      std::make_pair(protos::pbzero::BUILTIN_CLOCK_MONOTONIC, wall_time_ns));
+#endif
+
+  // If we're about to update a session's latest clock snapshot that hasn't been
+  // emitted into the trace yet, check whether the clocks have drifted enough to
+  // warrant overriding the current snapshot values. The older snapshot would be
+  // valid for a larger part of the currently buffered trace data because the
+  // clock sync protocol in trace processor uses the latest clock <= timestamp
+  // to translate times (see https://perfetto.dev/docs/concepts/clock-sync), so
+  // we try to keep it if we can.
+  if (!snapshot_data->empty()) {
+    PERFETTO_DCHECK(snapshot_data->size() == new_snapshot_data.size());
+    PERFETTO_DCHECK((*snapshot_data)[0].first ==
+                    protos::gen::BUILTIN_CLOCK_BOOTTIME);
+
+    bool update_snapshot = false;
+    uint64_t old_boot_ns = (*snapshot_data)[0].second;
+    uint64_t new_boot_ns = new_snapshot_data[0].second;
+    int64_t boot_diff =
+        static_cast<int64_t>(new_boot_ns) - static_cast<int64_t>(old_boot_ns);
+
+    for (size_t i = 1; i < snapshot_data->size(); i++) {
+      uint64_t old_ns = (*snapshot_data)[i].second;
+      uint64_t new_ns = new_snapshot_data[i].second;
+
+      int64_t diff =
+          static_cast<int64_t>(new_ns) - static_cast<int64_t>(old_ns);
+
+      // Compare the boottime delta against the delta of this clock.
+      if (std::abs(boot_diff - diff) >= kSignificantDriftNs) {
+        update_snapshot = true;
+        break;
+      }
+    }
+    if (!update_snapshot)
+      return false;
+    snapshot_data->clear();
+  }
+
+  *snapshot_data = std::move(new_snapshot_data);
+  return true;
+}
+
+void TracingServiceImpl::EmitClockSnapshot(
+    TracingSession* tracing_session,
+    TracingSession::ClockSnapshotData snapshot_data,
+    std::vector<TracePacket>* packets) {
+  PERFETTO_DCHECK(!tracing_session->config.builtin_data_sources()
+                       .disable_clock_snapshotting());
+
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  auto* snapshot = packet->set_clock_snapshot();
+
+  protos::gen::BuiltinClock trace_clock =
+      tracing_session->config.builtin_data_sources().primary_trace_clock();
+  if (!trace_clock)
+    trace_clock = protos::gen::BUILTIN_CLOCK_BOOTTIME;
+  snapshot->set_primary_trace_clock(
+      static_cast<protos::pbzero::BuiltinClock>(trace_clock));
+
+  for (auto& clock_id_and_ts : snapshot_data) {
+    auto* c = snapshot->add_clocks();
+    c->set_clock_id(clock_id_and_ts.first);
+    c->set_timestamp(clock_id_and_ts.second);
+  }
+
+  packet->set_trusted_uid(static_cast<int32_t>(uid_));
+  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+void TracingServiceImpl::EmitSyncMarker(std::vector<TracePacket>* packets) {
+  // The sync marks are used to tokenize large traces efficiently.
+  // See description in trace_packet.proto.
+  if (sync_marker_packet_size_ == 0) {
+    // The marker ABI expects that the marker is written after the uid.
+    // Protozero guarantees that fields are written in the same order of the
+    // calls. The ResynchronizeTraceStreamUsingSyncMarker test verifies the ABI.
+    protozero::StaticBuffered<protos::pbzero::TracePacket> packet(
+        &sync_marker_packet_[0], sizeof(sync_marker_packet_));
+    packet->set_trusted_uid(static_cast<int32_t>(uid_));
+    packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+
+    // Keep this last.
+    packet->set_synchronization_marker(kSyncMarker, sizeof(kSyncMarker));
+    sync_marker_packet_size_ = packet.Finalize();
+  }
+  packets->emplace_back();
+  packets->back().AddSlice(&sync_marker_packet_[0], sync_marker_packet_size_);
+}
+
+void TracingServiceImpl::EmitStats(TracingSession* tracing_session,
+                                   std::vector<TracePacket>* packets) {
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  packet->set_trusted_uid(static_cast<int32_t>(uid_));
+  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+  GetTraceStats(tracing_session).Serialize(packet->set_trace_stats());
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+TraceStats TracingServiceImpl::GetTraceStats(TracingSession* tracing_session) {
+  TraceStats trace_stats;
+  trace_stats.set_producers_connected(static_cast<uint32_t>(producers_.size()));
+  trace_stats.set_producers_seen(last_producer_id_);
+  trace_stats.set_data_sources_registered(
+      static_cast<uint32_t>(data_sources_.size()));
+  trace_stats.set_data_sources_seen(last_data_source_instance_id_);
+  trace_stats.set_tracing_sessions(
+      static_cast<uint32_t>(tracing_sessions_.size()));
+  trace_stats.set_total_buffers(static_cast<uint32_t>(buffers_.size()));
+  trace_stats.set_chunks_discarded(chunks_discarded_);
+  trace_stats.set_patches_discarded(patches_discarded_);
+  trace_stats.set_invalid_packets(tracing_session->invalid_packets);
+  trace_stats.set_flushes_requested(tracing_session->flushes_requested);
+  trace_stats.set_flushes_succeeded(tracing_session->flushes_succeeded);
+  trace_stats.set_flushes_failed(tracing_session->flushes_failed);
+  trace_stats.set_final_flush_outcome(tracing_session->final_flush_outcome);
+
+  if (tracing_session->trace_filter) {
+    auto* filt_stats = trace_stats.mutable_filter_stats();
+    filt_stats->set_input_packets(tracing_session->filter_input_packets);
+    filt_stats->set_input_bytes(tracing_session->filter_input_bytes);
+    filt_stats->set_output_bytes(tracing_session->filter_output_bytes);
+    filt_stats->set_errors(tracing_session->filter_errors);
+    filt_stats->set_time_taken_ns(tracing_session->filter_time_taken_ns);
+    for (uint64_t value : tracing_session->filter_bytes_discarded_per_buffer)
+      filt_stats->add_bytes_discarded_per_buffer(value);
+  }
+
+  for (BufferID buf_id : tracing_session->buffers_index) {
+    TraceBuffer* buf = GetBufferByID(buf_id);
+    if (!buf) {
+      PERFETTO_DFATAL("Buffer not found.");
+      continue;
+    }
+    *trace_stats.add_buffer_stats() = buf->stats();
+  }  // for (buf in session).
+
+  if (!tracing_session->config.builtin_data_sources()
+           .disable_chunk_usage_histograms()) {
+    // Emit chunk usage stats broken down by sequence ID (i.e. by trace-writer).
+    // Writer stats are updated by each TraceBuffer object at ReadBuffers time,
+    // and there can be >1 buffer per session. A trace writer never writes to
+    // more than one buffer (it's technically allowed but doesn't happen in the
+    // current impl of the tracing SDK).
+
+    bool has_written_bucket_definition = false;
+    uint32_t buf_idx = static_cast<uint32_t>(-1);
+    for (const BufferID buf_id : tracing_session->buffers_index) {
+      ++buf_idx;
+      const TraceBuffer* buf = GetBufferByID(buf_id);
+      if (!buf)
+        continue;
+      for (auto it = buf->writer_stats().GetIterator(); it; ++it) {
+        const auto& hist = it.value().used_chunk_hist;
+        ProducerID p;
+        WriterID w;
+        GetProducerAndWriterID(it.key(), &p, &w);
+        if (!has_written_bucket_definition) {
+          // Serialize one-off the histogram bucket definition, which is the
+          // same for all entries in the map.
+          has_written_bucket_definition = true;
+          // The -1 in the loop below is to skip the implicit overflow bucket.
+          for (size_t i = 0; i < hist.num_buckets() - 1; ++i) {
+            trace_stats.add_chunk_payload_histogram_def(hist.GetBucketThres(i));
+          }
+        }  // if(!has_written_bucket_definition)
+        auto* wri_stats = trace_stats.add_writer_stats();
+        wri_stats->set_sequence_id(
+            tracing_session->GetPacketSequenceID(kDefaultMachineID, p, w));
+        wri_stats->set_buffer(buf_idx);
+        for (size_t i = 0; i < hist.num_buckets(); ++i) {
+          wri_stats->add_chunk_payload_histogram_counts(hist.GetBucketCount(i));
+          wri_stats->add_chunk_payload_histogram_sum(hist.GetBucketSum(i));
+        }
+      }  // for each sequence (writer).
+    }    // for each buffer.
+  }      // if (!disable_chunk_usage_histograms)
+
+  return trace_stats;
+}
+
+void TracingServiceImpl::EmitUuid(TracingSession* tracing_session,
+                                  std::vector<TracePacket>* packets) {
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  packet->set_trusted_uid(static_cast<int32_t>(uid_));
+  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+  auto* uuid = packet->set_trace_uuid();
+  uuid->set_lsb(tracing_session->trace_uuid.lsb());
+  uuid->set_msb(tracing_session->trace_uuid.msb());
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+void TracingServiceImpl::MaybeEmitTraceConfig(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  if (tracing_session->did_emit_initial_packets)
+    return;
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  packet->set_trusted_uid(static_cast<int32_t>(uid_));
+  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+  tracing_session->config.Serialize(packet->set_trace_config());
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+void TracingServiceImpl::EmitSystemInfo(std::vector<TracePacket>* packets) {
+  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+  auto* info = packet->set_system_info();
+  info->set_tracing_service_version(base::GetVersionString());
+
+  std::optional<int32_t> tzoff = base::GetTimezoneOffsetMins();
+  if (tzoff.has_value())
+    info->set_timezone_off_mins(*tzoff);
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+  struct utsname uname_info;
+  if (uname(&uname_info) == 0) {
+    auto* utsname_info = info->set_utsname();
+    utsname_info->set_sysname(uname_info.sysname);
+    utsname_info->set_version(uname_info.version);
+    utsname_info->set_machine(uname_info.machine);
+    utsname_info->set_release(uname_info.release);
+  }
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  std::string fingerprint_value = base::GetAndroidProp("ro.build.fingerprint");
+  if (!fingerprint_value.empty()) {
+    info->set_android_build_fingerprint(fingerprint_value);
+  } else {
+    PERFETTO_ELOG("Unable to read ro.build.fingerprint");
+  }
+
+  std::string sdk_str_value = base::GetAndroidProp("ro.build.version.sdk");
+  std::optional<uint64_t> sdk_value = base::StringToUInt64(sdk_str_value);
+  if (sdk_value.has_value()) {
+    info->set_android_sdk_version(*sdk_value);
+  } else {
+    PERFETTO_ELOG("Unable to read ro.build.version.sdk");
+  }
+  info->set_hz(sysconf(_SC_CLK_TCK));
+  info->set_page_size(static_cast<uint32_t>(sysconf(_SC_PAGESIZE)));
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  packet->set_trusted_uid(static_cast<int32_t>(uid_));
+  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+}
+
+void TracingServiceImpl::EmitLifecycleEvents(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  using TimestampedPacket =
+      std::pair<int64_t /* ts */, std::vector<uint8_t> /* serialized packet */>;
+
+  std::vector<TimestampedPacket> timestamped_packets;
+  for (auto& event : tracing_session->lifecycle_events) {
+    for (int64_t ts : event.timestamps) {
+      protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+      packet->set_timestamp(static_cast<uint64_t>(ts));
+      packet->set_trusted_uid(static_cast<int32_t>(uid_));
+      packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+
+      auto* service_event = packet->set_service_event();
+      service_event->AppendVarInt(event.field_id, 1);
+      timestamped_packets.emplace_back(ts, packet.SerializeAsArray());
+    }
+    event.timestamps.clear();
+  }
+
+  // We sort by timestamp here to ensure that the "sequence" of lifecycle
+  // packets has monotonic timestamps like other sequences in the trace.
+  // Note that these events could still be out of order with respect to other
+  // events on the service packet sequence (e.g. trigger received packets).
+  std::sort(timestamped_packets.begin(), timestamped_packets.end(),
+            [](const TimestampedPacket& a, const TimestampedPacket& b) {
+              return a.first < b.first;
+            });
+
+  for (const auto& pair : timestamped_packets)
+    SerializeAndAppendPacket(packets, std::move(pair.second));
+}
+
+void TracingServiceImpl::MaybeEmitReceivedTriggers(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  PERFETTO_DCHECK(tracing_session->num_triggers_emitted_into_trace <=
+                  tracing_session->received_triggers.size());
+  for (size_t i = tracing_session->num_triggers_emitted_into_trace;
+       i < tracing_session->received_triggers.size(); ++i) {
+    const auto& info = tracing_session->received_triggers[i];
+    protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+    auto* trigger = packet->set_trigger();
+    trigger->set_trigger_name(info.trigger_name);
+    trigger->set_producer_name(info.producer_name);
+    trigger->set_trusted_producer_uid(static_cast<int32_t>(info.producer_uid));
+
+    packet->set_timestamp(info.boot_time_ns);
+    packet->set_trusted_uid(static_cast<int32_t>(uid_));
+    packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
+    SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+    ++tracing_session->num_triggers_emitted_into_trace;
+  }
+}
+
+void TracingServiceImpl::MaybeLogUploadEvent(const TraceConfig& cfg,
+                                             const base::Uuid& uuid,
+                                             PerfettoStatsdAtom atom,
+                                             const std::string& trigger_name) {
+  if (!ShouldLogEvent(cfg))
+    return;
+
+  PERFETTO_DCHECK(uuid);  // The UUID must be set at this point.
+  android_stats::MaybeLogUploadEvent(atom, uuid.lsb(), uuid.msb(),
+                                     trigger_name);
+}
+
+void TracingServiceImpl::MaybeLogTriggerEvent(const TraceConfig& cfg,
+                                              PerfettoTriggerAtom atom,
+                                              const std::string& trigger_name) {
+  if (!ShouldLogEvent(cfg))
+    return;
+  android_stats::MaybeLogTriggerEvent(atom, trigger_name);
+}
+
+size_t TracingServiceImpl::PurgeExpiredAndCountTriggerInWindow(
+    int64_t now_ns,
+    uint64_t trigger_name_hash) {
+  PERFETTO_DCHECK(
+      std::is_sorted(trigger_history_.begin(), trigger_history_.end()));
+  size_t remove_count = 0;
+  size_t trigger_count = 0;
+  for (const TriggerHistory& h : trigger_history_) {
+    if (h.timestamp_ns < now_ns - trigger_window_ns_) {
+      remove_count++;
+    } else if (h.name_hash == trigger_name_hash) {
+      trigger_count++;
+    }
+  }
+  trigger_history_.erase_front(remove_count);
+  return trigger_count;
+}
+
+void TracingServiceImpl::FlushAndCloneSession(ConsumerEndpointImpl* consumer,
+                                              TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto clone_target = FlushFlags::CloneTarget::kUnknown;
+  bool for_bugreport = false;
+
+  if (tsid == kBugreportSessionId) {
+    PERFETTO_LOG("Looking for sessions for bugreport");
+    TracingSession* session = FindTracingSessionWithMaxBugreportScore();
+    if (!session) {
+      consumer->consumer_->OnSessionCloned(
+          {false, "No tracing sessions eligible for bugreport found", {}});
+      return;
+    }
+    tsid = session->id;
+    clone_target = FlushFlags::CloneTarget::kBugreport;
+    for_bugreport = true;
+  }
+
+  TracingSession* session = GetTracingSession(tsid);
+  if (!session) {
+    consumer->consumer_->OnSessionCloned(
+        {false, "Tracing session not found", {}});
+    return;
+  }
+
+  // If any of the buffers are marked as clear_before_clone, reset them before
+  // issuing the Flush(kCloneReason).
+  size_t buf_idx = 0;
+  for (BufferID src_buf_id : session->buffers_index) {
+    if (!session->config.buffers()[buf_idx++].clear_before_clone())
+      continue;
+    auto buf_iter = buffers_.find(src_buf_id);
+    PERFETTO_CHECK(buf_iter != buffers_.end());
+    std::unique_ptr<TraceBuffer>& buf = buf_iter->second;
+
+    // No need to reset the buffer if nothing has been written into it yet.
+    // This is the canonical case if producers behive nicely and don't timeout
+    // the handling of writes during the flush.
+    // This check avoids a useless re-mmap upon every Clone() if the buffer is
+    // already empty (when used in combination with `transfer_on_clone`).
+    if (!buf->has_data())
+      continue;
+
+    // Some leftover data was left in the buffer. Recreate it to empty it.
+    const auto buf_policy = buf->overwrite_policy();
+    const auto buf_size = buf->size();
+    std::unique_ptr<TraceBuffer> old_buf = std::move(buf);
+    buf = TraceBuffer::Create(buf_size, buf_policy);
+    if (!buf) {
+      // This is extremely rare but could happen on 32-bit. If the new buffer
+      // allocation failed, put back the buffer where it was and fail the clone.
+      // We cannot leave the original tracing session buffer-less as it would
+      // cause crashes when data sources commit new data.
+      buf = std::move(old_buf);
+      consumer->consumer_->OnSessionCloned(
+          {false, "Buffer allocation failed while attempting to clone", {}});
+      return;
+    }
+  }
+
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto weak_consumer = consumer->GetWeakPtr();
+  Flush(
+      tsid, 0,
+      [weak_this, tsid, for_bugreport,
+       weak_consumer](bool final_flush_outcome) {
+        PERFETTO_LOG("FlushAndCloneSession(%" PRIu64 ") started, success=%d",
+                     tsid, final_flush_outcome);
+        if (!weak_this || !weak_consumer)
+          return;
+        base::Uuid uuid;
+        base::Status result = weak_this->DoCloneSession(
+            &*weak_consumer, tsid, for_bugreport, final_flush_outcome, &uuid);
+        weak_consumer->consumer_->OnSessionCloned(
+            {result.ok(), result.message(), uuid});
+      },
+      FlushFlags(FlushFlags::Initiator::kTraced,
+                 FlushFlags::Reason::kTraceClone, clone_target));
+}
+
+base::Status TracingServiceImpl::DoCloneSession(ConsumerEndpointImpl* consumer,
+                                                TracingSessionID src_tsid,
+                                                bool for_bugreport,
+                                                bool final_flush_outcome,
+                                                base::Uuid* new_uuid) {
+  PERFETTO_DLOG("CloneSession(%" PRIu64 ") started, consumer uid: %d", src_tsid,
+                static_cast<int>(consumer->uid_));
+
+  TracingSession* src = GetTracingSession(src_tsid);
+
+  // The session might be gone by the time we try to clone it.
+  if (!src)
+    return PERFETTO_SVC_ERR("session not found");
+
+  if (consumer->tracing_session_id_) {
+    return PERFETTO_SVC_ERR(
+        "The consumer is already attached to another tracing session");
+  }
+
+  // Skip the UID check for sessions marked with a bugreport_score > 0.
+  // Those sessions, by design, can be stolen by any other consumer for the
+  // sake of creating snapshots for bugreports.
+  if (src->config.bugreport_score() <= 0 &&
+      src->consumer_uid != consumer->uid_ && consumer->uid_ != 0) {
+    return PERFETTO_SVC_ERR("Not allowed to clone a session from another UID");
+  }
+
+  // First clone all TraceBuffer(s). This can fail because of ENOMEM. If it
+  // happens bail out early before creating any session.
+  std::vector<std::pair<BufferID, std::unique_ptr<TraceBuffer>>> buf_snaps;
+  buf_snaps.reserve(src->num_buffers());
+  PERFETTO_DCHECK(src->num_buffers() == src->config.buffers().size());
+  bool buf_clone_failed = false;
+  size_t buf_idx = 0;
+  for (BufferID src_buf_id : src->buffers_index) {
+    auto buf_iter = buffers_.find(src_buf_id);
+    PERFETTO_CHECK(buf_iter != buffers_.end());
+    std::unique_ptr<TraceBuffer>& src_buf = buf_iter->second;
+    std::unique_ptr<TraceBuffer> new_buf;
+    if (src->config.buffers()[buf_idx].transfer_on_clone()) {
+      const auto buf_policy = src_buf->overwrite_policy();
+      const auto buf_size = src_buf->size();
+      new_buf = std::move(src_buf);
+      src_buf = TraceBuffer::Create(buf_size, buf_policy);
+      if (!src_buf) {
+        // If the allocation fails put the buffer back and let the code below
+        // handle the failure gracefully.
+        src_buf = std::move(new_buf);
+      }
+    } else {
+      new_buf = src_buf->CloneReadOnly();
+    }
+    BufferID buf_global_id = buffer_ids_.Allocate();
+    buf_clone_failed |= !new_buf.get() || !buf_global_id;
+    buf_snaps.emplace_back(buf_global_id, std::move(new_buf));
+    ++buf_idx;
+  }
+
+  // Free up allocated IDs in case of failure. No need to free the TraceBuffers,
+  // as they are still owned by the temporary |buf_snaps|.
+  if (buf_clone_failed) {
+    for (auto& kv : buf_snaps) {
+      if (kv.first)
+        buffer_ids_.Free(kv.first);
+    }
+    return PERFETTO_SVC_ERR("Buffer allocation failed");
+  }
+
+  const TracingSessionID tsid = ++last_tracing_session_id_;
+  TracingSession* cloned_session =
+      &tracing_sessions_
+           .emplace(
+               std::piecewise_construct, std::forward_as_tuple(tsid),
+               std::forward_as_tuple(tsid, consumer, src->config, task_runner_))
+           .first->second;
+
+  // Generate a new UUID for the cloned session, but preserve the LSB. In some
+  // contexts the LSB is used to tie the trace back to the statsd subscription
+  // that triggered it. See the corresponding code in perfetto_cmd.cc which
+  // reads at triggering_subscription_id().
+  const int64_t orig_uuid_lsb = src->trace_uuid.lsb();
+  cloned_session->state = TracingSession::CLONED_READ_ONLY;
+  cloned_session->trace_uuid = base::Uuidv4();
+  cloned_session->trace_uuid.set_lsb(orig_uuid_lsb);
+  *new_uuid = cloned_session->trace_uuid;
+
+  for (auto& kv : buf_snaps) {
+    BufferID buf_global_id = kv.first;
+    std::unique_ptr<TraceBuffer>& buf = kv.second;
+    // This is only needed for transfer_on_clone. Other buffers are already
+    // marked as read-only by CloneReadOnly(). We cannot do this early because
+    // in case of an allocation failure we will put std::move() the original
+    // buffer back in its place and in that case should not be made read-only.
+    buf->set_read_only();
+    buffers_.emplace(buf_global_id, std::move(buf));
+    cloned_session->buffers_index.emplace_back(buf_global_id);
+  }
+  UpdateMemoryGuardrail();
+
+  // Copy over relevant state that we want to persist in the cloned session.
+  // Mostly stats and metadata that is emitted in the trace file by the service.
+  // Also clear the received trigger list in the main tracing session. A
+  // CLONE_SNAPSHOT session can go in ring buffer mode for several hours and get
+  // snapshotted several times. This causes two issues with `received_triggers`:
+  // 1. Adding noise in the cloned trace emitting triggers that happened too
+  //    far back (see b/290799105).
+  // 2. Bloating memory (see b/290798988).
+  cloned_session->should_emit_stats = true;
+  cloned_session->received_triggers = std::move(src->received_triggers);
+  src->received_triggers.clear();
+  src->num_triggers_emitted_into_trace = 0;
+  cloned_session->lifecycle_events =
+      std::vector<TracingSession::LifecycleEvent>(src->lifecycle_events);
+  cloned_session->initial_clock_snapshot = src->initial_clock_snapshot;
+  cloned_session->clock_snapshot_ring_buffer = src->clock_snapshot_ring_buffer;
+  cloned_session->invalid_packets = src->invalid_packets;
+  cloned_session->flushes_requested = src->flushes_requested;
+  cloned_session->flushes_succeeded = src->flushes_succeeded;
+  cloned_session->flushes_failed = src->flushes_failed;
+  cloned_session->compress_deflate = src->compress_deflate;
+  if (src->trace_filter && !for_bugreport) {
+    // Copy the trace filter, unless it's a clone-for-bugreport (b/317065412).
+    cloned_session->trace_filter.reset(
+        new protozero::MessageFilter(src->trace_filter->config()));
+  }
+
+  SnapshotLifecyleEvent(
+      cloned_session,
+      protos::pbzero::TracingServiceEvent::kTracingDisabledFieldNumber,
+      true /* snapshot_clocks */);
+
+  PERFETTO_DLOG("Consumer (uid:%d) cloned tracing session %" PRIu64
+                " -> %" PRIu64,
+                static_cast<int>(consumer->uid_), src_tsid, tsid);
+
+  consumer->tracing_session_id_ = tsid;
+  cloned_session->final_flush_outcome = final_flush_outcome
+                                            ? TraceStats::FINAL_FLUSH_SUCCEEDED
+                                            : TraceStats::FINAL_FLUSH_FAILED;
+  return base::OkStatus();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TracingServiceImpl::ConsumerEndpointImpl implementation
+////////////////////////////////////////////////////////////////////////////////
+
+TracingServiceImpl::ConsumerEndpointImpl::ConsumerEndpointImpl(
+    TracingServiceImpl* service,
+    base::TaskRunner* task_runner,
+    Consumer* consumer,
+    uid_t uid)
+    : task_runner_(task_runner),
+      service_(service),
+      consumer_(consumer),
+      uid_(uid),
+      weak_ptr_factory_(this) {}
+
+TracingServiceImpl::ConsumerEndpointImpl::~ConsumerEndpointImpl() {
+  service_->DisconnectConsumer(this);
+  consumer_->OnDisconnect();
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::NotifyOnTracingDisabled(
+    const std::string& error) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, error /* deliberate copy */] {
+    if (weak_this)
+      weak_this->consumer_->OnTracingDisabled(error);
+  });
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::EnableTracing(
+    const TraceConfig& cfg,
+    base::ScopedFile fd) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto status = service_->EnableTracing(this, cfg, std::move(fd));
+  if (!status.ok())
+    NotifyOnTracingDisabled(status.message());
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::ChangeTraceConfig(
+    const TraceConfig& cfg) {
+  if (!tracing_session_id_) {
+    PERFETTO_LOG(
+        "Consumer called ChangeTraceConfig() but tracing was "
+        "not active");
+    return;
+  }
+  service_->ChangeTraceConfig(this, cfg);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::StartTracing() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!tracing_session_id_) {
+    PERFETTO_LOG("Consumer called StartTracing() but tracing was not active");
+    return;
+  }
+  service_->StartTracing(tracing_session_id_);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::DisableTracing() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!tracing_session_id_) {
+    PERFETTO_LOG("Consumer called DisableTracing() but tracing was not active");
+    return;
+  }
+  service_->DisableTracing(tracing_session_id_);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::ReadBuffers() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!tracing_session_id_) {
+    PERFETTO_LOG("Consumer called ReadBuffers() but tracing was not active");
+    consumer_->OnTraceData({}, /* has_more = */ false);
+    return;
+  }
+  if (!service_->ReadBuffersIntoConsumer(tracing_session_id_, this)) {
+    consumer_->OnTraceData({}, /* has_more = */ false);
+  }
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::FreeBuffers() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!tracing_session_id_) {
+    PERFETTO_LOG("Consumer called FreeBuffers() but tracing was not active");
+    return;
+  }
+  service_->FreeBuffers(tracing_session_id_);
+  tracing_session_id_ = 0;
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::Flush(uint32_t timeout_ms,
+                                                     FlushCallback callback,
+                                                     FlushFlags flush_flags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!tracing_session_id_) {
+    PERFETTO_LOG("Consumer called Flush() but tracing was not active");
+    return;
+  }
+  service_->Flush(tracing_session_id_, timeout_ms, callback, flush_flags);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::Detach(const std::string& key) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  bool success = service_->DetachConsumer(this, key);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, success] {
+    if (weak_this)
+      weak_this->consumer_->OnDetach(success);
+  });
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::Attach(const std::string& key) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  bool success = service_->AttachConsumer(this, key);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, success] {
+    if (!weak_this)
+      return;
+    Consumer* consumer = weak_this->consumer_;
+    TracingSession* session =
+        weak_this->service_->GetTracingSession(weak_this->tracing_session_id_);
+    if (!session) {
+      consumer->OnAttach(false, TraceConfig());
+      return;
+    }
+    consumer->OnAttach(success, session->config);
+  });
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::GetTraceStats() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  bool success = false;
+  TraceStats stats;
+  TracingSession* session = service_->GetTracingSession(tracing_session_id_);
+  if (session) {
+    success = true;
+    stats = service_->GetTraceStats(session);
+  }
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, success, stats] {
+    if (weak_this)
+      weak_this->consumer_->OnTraceStats(success, stats);
+  });
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::ObserveEvents(
+    uint32_t events_mask) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  observable_events_mask_ = events_mask;
+  TracingSession* session = service_->GetTracingSession(tracing_session_id_);
+  if (!session)
+    return;
+
+  if (observable_events_mask_ & ObservableEvents::TYPE_DATA_SOURCES_INSTANCES) {
+    // Issue initial states.
+    for (const auto& kv : session->data_source_instances) {
+      ProducerEndpointImpl* producer = service_->GetProducer(kv.first);
+      PERFETTO_DCHECK(producer);
+      OnDataSourceInstanceStateChange(*producer, kv.second);
+    }
+  }
+
+  // If the ObserveEvents() call happens after data sources have acked already
+  // notify immediately.
+  if (observable_events_mask_ &
+      ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED) {
+    service_->MaybeNotifyAllDataSourcesStarted(session);
+  }
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::OnDataSourceInstanceStateChange(
+    const ProducerEndpointImpl& producer,
+    const DataSourceInstance& instance) {
+  if (!(observable_events_mask_ &
+        ObservableEvents::TYPE_DATA_SOURCES_INSTANCES)) {
+    return;
+  }
+
+  if (instance.state != DataSourceInstance::CONFIGURED &&
+      instance.state != DataSourceInstance::STARTED &&
+      instance.state != DataSourceInstance::STOPPED) {
+    return;
+  }
+
+  auto* observable_events = AddObservableEvents();
+  auto* change = observable_events->add_instance_state_changes();
+  change->set_producer_name(producer.name_);
+  change->set_data_source_name(instance.data_source_name);
+  if (instance.state == DataSourceInstance::STARTED) {
+    change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
+  } else {
+    change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
+  }
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::OnAllDataSourcesStarted() {
+  if (!(observable_events_mask_ &
+        ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED)) {
+    return;
+  }
+  auto* observable_events = AddObservableEvents();
+  observable_events->set_all_data_sources_started(true);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::NotifyCloneSnapshotTrigger() {
+  if (!(observable_events_mask_ & ObservableEvents::TYPE_CLONE_TRIGGER_HIT)) {
+    return;
+  }
+  auto* observable_events = AddObservableEvents();
+  auto* clone_trig = observable_events->mutable_clone_trigger_hit();
+  clone_trig->set_tracing_session_id(static_cast<int64_t>(tracing_session_id_));
+}
+
+ObservableEvents*
+TracingServiceImpl::ConsumerEndpointImpl::AddObservableEvents() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!observable_events_) {
+    observable_events_.reset(new ObservableEvents());
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostTask([weak_this] {
+      if (!weak_this)
+        return;
+
+      // Move into a temporary to allow reentrancy in OnObservableEvents.
+      auto observable_events = std::move(weak_this->observable_events_);
+      weak_this->consumer_->OnObservableEvents(*observable_events);
+    });
+  }
+  return observable_events_.get();
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::QueryServiceState(
+    QueryServiceStateCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingServiceState svc_state;
+
+  const auto& sessions = service_->tracing_sessions_;
+  svc_state.set_tracing_service_version(base::GetVersionString());
+  svc_state.set_num_sessions(static_cast<int>(sessions.size()));
+
+  int num_started = 0;
+  for (const auto& kv : sessions)
+    num_started += kv.second.state == TracingSession::State::STARTED ? 1 : 0;
+  svc_state.set_num_sessions_started(static_cast<int>(num_started));
+
+  for (const auto& kv : service_->producers_) {
+    auto* producer = svc_state.add_producers();
+    producer->set_id(static_cast<int>(kv.first));
+    producer->set_name(kv.second->name_);
+    producer->set_sdk_version(kv.second->sdk_version_);
+    producer->set_uid(static_cast<int32_t>(kv.second->uid()));
+    producer->set_pid(static_cast<int32_t>(kv.second->pid()));
+  }
+
+  for (const auto& kv : service_->data_sources_) {
+    const auto& registered_data_source = kv.second;
+    auto* data_source = svc_state.add_data_sources();
+    *data_source->mutable_ds_descriptor() = registered_data_source.descriptor;
+    data_source->set_producer_id(
+        static_cast<int>(registered_data_source.producer_id));
+  }
+
+  svc_state.set_supports_tracing_sessions(true);
+  for (const auto& kv : service_->tracing_sessions_) {
+    const TracingSession& s = kv.second;
+    // List only tracing sessions for the calling UID (or everything for root).
+    if (uid_ != 0 && uid_ != s.consumer_uid)
+      continue;
+    auto* session = svc_state.add_tracing_sessions();
+    session->set_id(s.id);
+    session->set_consumer_uid(static_cast<int>(s.consumer_uid));
+    session->set_duration_ms(s.config.duration_ms());
+    session->set_num_data_sources(
+        static_cast<uint32_t>(s.data_source_instances.size()));
+    session->set_unique_session_name(s.config.unique_session_name());
+    for (const auto& snap_kv : s.initial_clock_snapshot) {
+      if (snap_kv.first == protos::pbzero::BUILTIN_CLOCK_REALTIME)
+        session->set_start_realtime_ns(static_cast<int64_t>(snap_kv.second));
+    }
+    for (const auto& buf : s.config.buffers())
+      session->add_buffer_size_kb(buf.size_kb());
+
+    switch (s.state) {
+      case TracingSession::State::DISABLED:
+        session->set_state("DISABLED");
+        break;
+      case TracingSession::State::CONFIGURED:
+        session->set_state("CONFIGURED");
+        break;
+      case TracingSession::State::STARTED:
+        session->set_state("STARTED");
+        break;
+      case TracingSession::State::DISABLING_WAITING_STOP_ACKS:
+        session->set_state("STOP_WAIT");
+        break;
+      case TracingSession::State::CLONED_READ_ONLY:
+        session->set_state("CLONED_READ_ONLY");
+        break;
+    }
+  }
+  callback(/*success=*/true, svc_state);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::QueryCapabilities(
+    QueryCapabilitiesCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  TracingServiceCapabilities caps;
+  caps.set_has_query_capabilities(true);
+  caps.set_has_trace_config_output_path(true);
+  caps.set_has_clone_session(true);
+  caps.add_observable_events(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES);
+  caps.add_observable_events(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
+  caps.add_observable_events(ObservableEvents::TYPE_CLONE_TRIGGER_HIT);
+  static_assert(
+      ObservableEvents::Type_MAX == ObservableEvents::TYPE_CLONE_TRIGGER_HIT,
+      "");
+  callback(caps);
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::SaveTraceForBugreport(
+    SaveTraceForBugreportCallback consumer_callback) {
+  consumer_callback(false,
+                    "SaveTraceForBugreport is deprecated. Use "
+                    "CloneSession(kBugreportSessionId) instead.");
+}
+
+void TracingServiceImpl::ConsumerEndpointImpl::CloneSession(
+    TracingSessionID tsid) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // FlushAndCloneSession will call OnSessionCloned after the async flush.
+  service_->FlushAndCloneSession(this, tsid);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TracingServiceImpl::ProducerEndpointImpl implementation
+////////////////////////////////////////////////////////////////////////////////
+
+TracingServiceImpl::ProducerEndpointImpl::ProducerEndpointImpl(
+    ProducerID id,
+    const ClientIdentity& client_identity,
+    TracingServiceImpl* service,
+    base::TaskRunner* task_runner,
+    Producer* producer,
+    const std::string& producer_name,
+    const std::string& sdk_version,
+    bool in_process,
+    bool smb_scraping_enabled)
+    : id_(id),
+      client_identity_(client_identity),
+      service_(service),
+      task_runner_(task_runner),
+      producer_(producer),
+      name_(producer_name),
+      sdk_version_(sdk_version),
+      in_process_(in_process),
+      smb_scraping_enabled_(smb_scraping_enabled),
+      weak_ptr_factory_(this) {}
+
+TracingServiceImpl::ProducerEndpointImpl::~ProducerEndpointImpl() {
+  service_->DisconnectProducer(id_);
+  producer_->OnDisconnect();
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::Disconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // Disconnection is only supported via destroying the ProducerEndpoint.
+  PERFETTO_FATAL("Not supported");
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::RegisterDataSource(
+    const DataSourceDescriptor& desc) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->RegisterDataSource(id_, desc);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::UpdateDataSource(
+    const DataSourceDescriptor& desc) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->UpdateDataSource(id_, desc);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::UnregisterDataSource(
+    const std::string& name) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->UnregisterDataSource(id_, name);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::RegisterTraceWriter(
+    uint32_t writer_id,
+    uint32_t target_buffer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  writers_[static_cast<WriterID>(writer_id)] =
+      static_cast<BufferID>(target_buffer);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::UnregisterTraceWriter(
+    uint32_t writer_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  writers_.erase(static_cast<WriterID>(writer_id));
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::CommitData(
+    const CommitDataRequest& req_untrusted,
+    CommitDataCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  if (metatrace::IsEnabled(metatrace::TAG_TRACE_SERVICE)) {
+    PERFETTO_METATRACE_COUNTER(TAG_TRACE_SERVICE, TRACE_SERVICE_COMMIT_DATA,
+                               EncodeCommitDataRequest(id_, req_untrusted));
+  }
+
+  if (!shared_memory_) {
+    PERFETTO_DLOG(
+        "Attempted to commit data before the shared memory was allocated.");
+    return;
+  }
+  PERFETTO_DCHECK(shmem_abi_.is_valid());
+  for (const auto& entry : req_untrusted.chunks_to_move()) {
+    const uint32_t page_idx = entry.page();
+    if (page_idx >= shmem_abi_.num_pages())
+      continue;  // A buggy or malicious producer.
+
+    SharedMemoryABI::Chunk chunk;
+    bool commit_data_over_ipc = entry.has_data();
+    if (PERFETTO_UNLIKELY(commit_data_over_ipc)) {
+      // Chunk data is passed over the wire. Create a chunk using the serialized
+      // protobuf message.
+      const std::string& data = entry.data();
+      if (data.size() > SharedMemoryABI::Chunk::kMaxSize) {
+        PERFETTO_DFATAL("IPC data commit too large: %zu", data.size());
+        continue;  // A malicious or buggy producer
+      }
+      // |data| is not altered, but we need to const_cast becasue Chunk data
+      // members are non-const.
+      chunk = SharedMemoryABI::MakeChunkFromSerializedData(
+          reinterpret_cast<uint8_t*>(const_cast<char*>(data.data())),
+          static_cast<uint16_t>(entry.data().size()),
+          static_cast<uint8_t>(entry.chunk()));
+    } else
+      chunk = shmem_abi_.TryAcquireChunkForReading(page_idx, entry.chunk());
+    if (!chunk.is_valid()) {
+      PERFETTO_DLOG("Asked to move chunk %d:%d, but it's not complete",
+                    entry.page(), entry.chunk());
+      continue;
+    }
+
+    // TryAcquireChunkForReading() has load-acquire semantics. Once acquired,
+    // the ABI contract expects the producer to not touch the chunk anymore
+    // (until the service marks that as free). This is why all the reads below
+    // are just memory_order_relaxed. Also, the code here assumes that all this
+    // data can be malicious and just gives up if anything is malformed.
+    BufferID buffer_id = static_cast<BufferID>(entry.target_buffer());
+    const SharedMemoryABI::ChunkHeader& chunk_header = *chunk.header();
+    WriterID writer_id = chunk_header.writer_id.load(std::memory_order_relaxed);
+    ChunkID chunk_id = chunk_header.chunk_id.load(std::memory_order_relaxed);
+    auto packets = chunk_header.packets.load(std::memory_order_relaxed);
+    uint16_t num_fragments = packets.count;
+    uint8_t chunk_flags = packets.flags;
+
+    service_->CopyProducerPageIntoLogBuffer(
+        id_, client_identity_, writer_id, chunk_id, buffer_id, num_fragments,
+        chunk_flags,
+        /*chunk_complete=*/true, chunk.payload_begin(), chunk.payload_size());
+
+    if (!commit_data_over_ipc) {
+      // This one has release-store semantics.
+      shmem_abi_.ReleaseChunkAsFree(std::move(chunk));
+    }
+  }  // for(chunks_to_move)
+
+  service_->ApplyChunkPatches(id_, req_untrusted.chunks_to_patch());
+
+  if (req_untrusted.flush_request_id()) {
+    service_->NotifyFlushDoneForProducer(id_, req_untrusted.flush_request_id());
+  }
+
+  // Keep this invocation last. ProducerIPCService::CommitData() relies on this
+  // callback being invoked within the same callstack and not posted. If this
+  // changes, the code there needs to be changed accordingly.
+  if (callback)
+    callback();
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::SetupSharedMemory(
+    std::unique_ptr<SharedMemory> shared_memory,
+    size_t page_size_bytes,
+    bool provided_by_producer) {
+  PERFETTO_DCHECK(!shared_memory_ && !shmem_abi_.is_valid());
+  PERFETTO_DCHECK(page_size_bytes % 1024 == 0);
+
+  shared_memory_ = std::move(shared_memory);
+  shared_buffer_page_size_kb_ = page_size_bytes / 1024;
+  is_shmem_provided_by_producer_ = provided_by_producer;
+
+  shmem_abi_.Initialize(reinterpret_cast<uint8_t*>(shared_memory_->start()),
+                        shared_memory_->size(),
+                        shared_buffer_page_size_kb() * 1024,
+                        SharedMemoryABI::ShmemMode::kDefault);
+  if (in_process_) {
+    inproc_shmem_arbiter_.reset(new SharedMemoryArbiterImpl(
+        shared_memory_->start(), shared_memory_->size(),
+        SharedMemoryABI::ShmemMode::kDefault,
+        shared_buffer_page_size_kb_ * 1024, this, task_runner_));
+    inproc_shmem_arbiter_->SetDirectSMBPatchingSupportedByService();
+  }
+
+  OnTracingSetup();
+  service_->UpdateMemoryGuardrail();
+}
+
+SharedMemory* TracingServiceImpl::ProducerEndpointImpl::shared_memory() const {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  return shared_memory_.get();
+}
+
+size_t TracingServiceImpl::ProducerEndpointImpl::shared_buffer_page_size_kb()
+    const {
+  return shared_buffer_page_size_kb_;
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::ActivateTriggers(
+    const std::vector<std::string>& triggers) {
+  service_->ActivateTriggers(id_, triggers);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::StopDataSource(
+    DataSourceInstanceID ds_inst_id) {
+  // TODO(primiano): When we'll support tearing down the SMB, at this point we
+  // should send the Producer a TearDownTracing if all its data sources have
+  // been disabled (see b/77532839 and aosp/655179 PS1).
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, ds_inst_id] {
+    if (weak_this)
+      weak_this->producer_->StopDataSource(ds_inst_id);
+  });
+}
+
+SharedMemoryArbiter*
+TracingServiceImpl::ProducerEndpointImpl::MaybeSharedMemoryArbiter() {
+  if (!inproc_shmem_arbiter_) {
+    PERFETTO_FATAL(
+        "The in-process SharedMemoryArbiter can only be used when "
+        "CreateProducer has been called with in_process=true and after tracing "
+        "has started.");
+  }
+
+  PERFETTO_DCHECK(in_process_);
+  return inproc_shmem_arbiter_.get();
+}
+
+bool TracingServiceImpl::ProducerEndpointImpl::IsShmemProvidedByProducer()
+    const {
+  return is_shmem_provided_by_producer_;
+}
+
+// Can be called on any thread.
+std::unique_ptr<TraceWriter>
+TracingServiceImpl::ProducerEndpointImpl::CreateTraceWriter(
+    BufferID buf_id,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
+  return MaybeSharedMemoryArbiter()->CreateTraceWriter(buf_id,
+                                                       buffer_exhausted_policy);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::NotifyFlushComplete(
+    FlushRequestID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
+  return MaybeSharedMemoryArbiter()->NotifyFlushComplete(id);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::OnTracingSetup() {
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this] {
+    if (weak_this)
+      weak_this->producer_->OnTracingSetup();
+  });
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::Flush(
+    FlushRequestID flush_request_id,
+    const std::vector<DataSourceInstanceID>& data_sources,
+    FlushFlags flush_flags) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask(
+      [weak_this, flush_request_id, data_sources, flush_flags] {
+        if (weak_this) {
+          weak_this->producer_->Flush(flush_request_id, data_sources.data(),
+                                      data_sources.size(), flush_flags);
+        }
+      });
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::SetupDataSource(
+    DataSourceInstanceID ds_id,
+    const DataSourceConfig& config) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  allowed_target_buffers_.insert(static_cast<BufferID>(config.target_buffer()));
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, ds_id, config] {
+    if (weak_this)
+      weak_this->producer_->SetupDataSource(ds_id, std::move(config));
+  });
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::StartDataSource(
+    DataSourceInstanceID ds_id,
+    const DataSourceConfig& config) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, ds_id, config] {
+    if (weak_this)
+      weak_this->producer_->StartDataSource(ds_id, std::move(config));
+  });
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStarted(
+    DataSourceInstanceID data_source_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->NotifyDataSourceStarted(id_, data_source_id);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStopped(
+    DataSourceInstanceID data_source_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  service_->NotifyDataSourceStopped(id_, data_source_id);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::OnFreeBuffers(
+    const std::vector<BufferID>& target_buffers) {
+  if (allowed_target_buffers_.empty())
+    return;
+  for (BufferID buffer : target_buffers)
+    allowed_target_buffers_.erase(buffer);
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::ClearIncrementalState(
+    const std::vector<DataSourceInstanceID>& data_sources) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this, data_sources] {
+    if (weak_this) {
+      base::StringView producer_name(weak_this->name_);
+      weak_this->producer_->ClearIncrementalState(data_sources.data(),
+                                                  data_sources.size());
+    }
+  });
+}
+
+void TracingServiceImpl::ProducerEndpointImpl::Sync(
+    std::function<void()> callback) {
+  task_runner_->PostTask(callback);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// TracingServiceImpl::TracingSession implementation
+////////////////////////////////////////////////////////////////////////////////
+
+TracingServiceImpl::TracingSession::TracingSession(
+    TracingSessionID session_id,
+    ConsumerEndpointImpl* consumer,
+    const TraceConfig& new_config,
+    base::TaskRunner* task_runner)
+    : id(session_id),
+      consumer_maybe_null(consumer),
+      consumer_uid(consumer->uid_),
+      config(new_config),
+      snapshot_periodic_task(task_runner),
+      timed_stop_task(task_runner) {
+  // all_data_sources_flushed is special because we store up to 64 events of
+  // this type. Other events will go through the default case in
+  // SnapshotLifecycleEvent() where they will be given a max history of 1.
+  lifecycle_events.emplace_back(
+      protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
+      64 /* max_size */);
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/in_process_tracing_backend.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/in_process_tracing_backend.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+// gen_amalgamated expanded: #include "src/tracing/core/in_process_shared_memory.h"
+
+// TODO(primiano): When the in-process backend is used, we should never end up
+// in a situation where the thread where the TracingService and Producer live
+// writes a packet and hence can get into the GetNewChunk() stall.
+// This would happen only if the API client code calls Trace() from one of the
+// callbacks it receives (e.g. OnStart(), OnStop()). We should either cause a
+// hard crash or ignore traces from that thread if that happens, because it
+// will deadlock (the Service will never free up the SMB because won't ever get
+// to run the task).
+
+namespace perfetto {
+namespace internal {
+
+// static
+TracingBackend* InProcessTracingBackend::GetInstance() {
+  static auto* instance = new InProcessTracingBackend();
+  return instance;
+}
+
+InProcessTracingBackend::InProcessTracingBackend() {}
+
+std::unique_ptr<ProducerEndpoint> InProcessTracingBackend::ConnectProducer(
+    const ConnectProducerArgs& args) {
+  PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
+  return GetOrCreateService(args.task_runner)
+      ->ConnectProducer(args.producer, ClientIdentity(/*uid=*/0, /*pid=*/0),
+                        args.producer_name, args.shmem_size_hint_bytes,
+                        /*in_process=*/true,
+                        TracingService::ProducerSMBScrapingMode::kEnabled,
+                        args.shmem_page_size_hint_bytes);
+}
+
+std::unique_ptr<ConsumerEndpoint> InProcessTracingBackend::ConnectConsumer(
+    const ConnectConsumerArgs& args) {
+  return GetOrCreateService(args.task_runner)
+      ->ConnectConsumer(args.consumer, /*uid=*/0);
+}
+
+TracingService* InProcessTracingBackend::GetOrCreateService(
+    base::TaskRunner* task_runner) {
+  if (!service_) {
+    std::unique_ptr<InProcessSharedMemory::Factory> shm(
+        new InProcessSharedMemory::Factory());
+    service_ = TracingService::CreateInstance(std::move(shm), task_runner);
+    service_->SetSMBScrapingEnabled(true);
+  }
+  return service_.get();
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+CloneSessionResponse::CloneSessionResponse() = default;
+CloneSessionResponse::~CloneSessionResponse() = default;
+CloneSessionResponse::CloneSessionResponse(const CloneSessionResponse&) = default;
+CloneSessionResponse& CloneSessionResponse::operator=(const CloneSessionResponse&) = default;
+CloneSessionResponse::CloneSessionResponse(CloneSessionResponse&&) noexcept = default;
+CloneSessionResponse& CloneSessionResponse::operator=(CloneSessionResponse&&) = default;
+
+bool CloneSessionResponse::operator==(const CloneSessionResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
+   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_)
+   && ::protozero::internal::gen_helpers::EqualsField(uuid_msb_, other.uuid_msb_)
+   && ::protozero::internal::gen_helpers::EqualsField(uuid_lsb_, other.uuid_lsb_);
+}
+
+bool CloneSessionResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* success */:
+        field.get(&success_);
+        break;
+      case 2 /* error */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
+        break;
+      case 3 /* uuid_msb */:
+        field.get(&uuid_msb_);
+        break;
+      case 4 /* uuid_lsb */:
+        field.get(&uuid_lsb_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CloneSessionResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CloneSessionResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CloneSessionResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
+  }
+
+  // Field 2: error
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, error_, msg);
+  }
+
+  // Field 3: uuid_msb
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, uuid_msb_, msg);
+  }
+
+  // Field 4: uuid_lsb
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, uuid_lsb_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+CloneSessionRequest::CloneSessionRequest() = default;
+CloneSessionRequest::~CloneSessionRequest() = default;
+CloneSessionRequest::CloneSessionRequest(const CloneSessionRequest&) = default;
+CloneSessionRequest& CloneSessionRequest::operator=(const CloneSessionRequest&) = default;
+CloneSessionRequest::CloneSessionRequest(CloneSessionRequest&&) noexcept = default;
+CloneSessionRequest& CloneSessionRequest::operator=(CloneSessionRequest&&) = default;
+
+bool CloneSessionRequest::operator==(const CloneSessionRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(session_id_, other.session_id_);
+}
+
+bool CloneSessionRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* session_id */:
+        field.get(&session_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CloneSessionRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CloneSessionRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CloneSessionRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: session_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, session_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+SaveTraceForBugreportResponse::SaveTraceForBugreportResponse() = default;
+SaveTraceForBugreportResponse::~SaveTraceForBugreportResponse() = default;
+SaveTraceForBugreportResponse::SaveTraceForBugreportResponse(const SaveTraceForBugreportResponse&) = default;
+SaveTraceForBugreportResponse& SaveTraceForBugreportResponse::operator=(const SaveTraceForBugreportResponse&) = default;
+SaveTraceForBugreportResponse::SaveTraceForBugreportResponse(SaveTraceForBugreportResponse&&) noexcept = default;
+SaveTraceForBugreportResponse& SaveTraceForBugreportResponse::operator=(SaveTraceForBugreportResponse&&) = default;
+
+bool SaveTraceForBugreportResponse::operator==(const SaveTraceForBugreportResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_, other.msg_);
+}
+
+bool SaveTraceForBugreportResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* success */:
+        field.get(&success_);
+        break;
+      case 2 /* msg */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &msg_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SaveTraceForBugreportResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SaveTraceForBugreportResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SaveTraceForBugreportResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
+  }
+
+  // Field 2: msg
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, msg_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+SaveTraceForBugreportRequest::SaveTraceForBugreportRequest() = default;
+SaveTraceForBugreportRequest::~SaveTraceForBugreportRequest() = default;
+SaveTraceForBugreportRequest::SaveTraceForBugreportRequest(const SaveTraceForBugreportRequest&) = default;
+SaveTraceForBugreportRequest& SaveTraceForBugreportRequest::operator=(const SaveTraceForBugreportRequest&) = default;
+SaveTraceForBugreportRequest::SaveTraceForBugreportRequest(SaveTraceForBugreportRequest&&) noexcept = default;
+SaveTraceForBugreportRequest& SaveTraceForBugreportRequest::operator=(SaveTraceForBugreportRequest&&) = default;
+
+bool SaveTraceForBugreportRequest::operator==(const SaveTraceForBugreportRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool SaveTraceForBugreportRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SaveTraceForBugreportRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SaveTraceForBugreportRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SaveTraceForBugreportRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+QueryCapabilitiesResponse::QueryCapabilitiesResponse() = default;
+QueryCapabilitiesResponse::~QueryCapabilitiesResponse() = default;
+QueryCapabilitiesResponse::QueryCapabilitiesResponse(const QueryCapabilitiesResponse&) = default;
+QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(const QueryCapabilitiesResponse&) = default;
+QueryCapabilitiesResponse::QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept = default;
+QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(QueryCapabilitiesResponse&&) = default;
+
+bool QueryCapabilitiesResponse::operator==(const QueryCapabilitiesResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(capabilities_, other.capabilities_);
+}
+
+bool QueryCapabilitiesResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* capabilities */:
+        (*capabilities_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string QueryCapabilitiesResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryCapabilitiesResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void QueryCapabilitiesResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: capabilities
+  if (_has_field_[1]) {
+    (*capabilities_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+QueryCapabilitiesRequest::QueryCapabilitiesRequest() = default;
+QueryCapabilitiesRequest::~QueryCapabilitiesRequest() = default;
+QueryCapabilitiesRequest::QueryCapabilitiesRequest(const QueryCapabilitiesRequest&) = default;
+QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(const QueryCapabilitiesRequest&) = default;
+QueryCapabilitiesRequest::QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept = default;
+QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(QueryCapabilitiesRequest&&) = default;
+
+bool QueryCapabilitiesRequest::operator==(const QueryCapabilitiesRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool QueryCapabilitiesRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string QueryCapabilitiesRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryCapabilitiesRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void QueryCapabilitiesRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+QueryServiceStateResponse::QueryServiceStateResponse() = default;
+QueryServiceStateResponse::~QueryServiceStateResponse() = default;
+QueryServiceStateResponse::QueryServiceStateResponse(const QueryServiceStateResponse&) = default;
+QueryServiceStateResponse& QueryServiceStateResponse::operator=(const QueryServiceStateResponse&) = default;
+QueryServiceStateResponse::QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept = default;
+QueryServiceStateResponse& QueryServiceStateResponse::operator=(QueryServiceStateResponse&&) = default;
+
+bool QueryServiceStateResponse::operator==(const QueryServiceStateResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(service_state_, other.service_state_);
+}
+
+bool QueryServiceStateResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* service_state */:
+        (*service_state_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string QueryServiceStateResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryServiceStateResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void QueryServiceStateResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: service_state
+  if (_has_field_[1]) {
+    (*service_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+QueryServiceStateRequest::QueryServiceStateRequest() = default;
+QueryServiceStateRequest::~QueryServiceStateRequest() = default;
+QueryServiceStateRequest::QueryServiceStateRequest(const QueryServiceStateRequest&) = default;
+QueryServiceStateRequest& QueryServiceStateRequest::operator=(const QueryServiceStateRequest&) = default;
+QueryServiceStateRequest::QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept = default;
+QueryServiceStateRequest& QueryServiceStateRequest::operator=(QueryServiceStateRequest&&) = default;
+
+bool QueryServiceStateRequest::operator==(const QueryServiceStateRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool QueryServiceStateRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string QueryServiceStateRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> QueryServiceStateRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void QueryServiceStateRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ObserveEventsResponse::ObserveEventsResponse() = default;
+ObserveEventsResponse::~ObserveEventsResponse() = default;
+ObserveEventsResponse::ObserveEventsResponse(const ObserveEventsResponse&) = default;
+ObserveEventsResponse& ObserveEventsResponse::operator=(const ObserveEventsResponse&) = default;
+ObserveEventsResponse::ObserveEventsResponse(ObserveEventsResponse&&) noexcept = default;
+ObserveEventsResponse& ObserveEventsResponse::operator=(ObserveEventsResponse&&) = default;
+
+bool ObserveEventsResponse::operator==(const ObserveEventsResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(events_, other.events_);
+}
+
+bool ObserveEventsResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* events */:
+        (*events_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObserveEventsResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObserveEventsResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObserveEventsResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: events
+  if (_has_field_[1]) {
+    (*events_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ObserveEventsRequest::ObserveEventsRequest() = default;
+ObserveEventsRequest::~ObserveEventsRequest() = default;
+ObserveEventsRequest::ObserveEventsRequest(const ObserveEventsRequest&) = default;
+ObserveEventsRequest& ObserveEventsRequest::operator=(const ObserveEventsRequest&) = default;
+ObserveEventsRequest::ObserveEventsRequest(ObserveEventsRequest&&) noexcept = default;
+ObserveEventsRequest& ObserveEventsRequest::operator=(ObserveEventsRequest&&) = default;
+
+bool ObserveEventsRequest::operator==(const ObserveEventsRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(events_to_observe_, other.events_to_observe_);
+}
+
+bool ObserveEventsRequest::ParseFromArray(const void* raw, size_t size) {
+  events_to_observe_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* events_to_observe */:
+        events_to_observe_.emplace_back();
+        field.get(&events_to_observe_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ObserveEventsRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ObserveEventsRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ObserveEventsRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: events_to_observe
+  for (auto& it : events_to_observe_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetTraceStatsResponse::GetTraceStatsResponse() = default;
+GetTraceStatsResponse::~GetTraceStatsResponse() = default;
+GetTraceStatsResponse::GetTraceStatsResponse(const GetTraceStatsResponse&) = default;
+GetTraceStatsResponse& GetTraceStatsResponse::operator=(const GetTraceStatsResponse&) = default;
+GetTraceStatsResponse::GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept = default;
+GetTraceStatsResponse& GetTraceStatsResponse::operator=(GetTraceStatsResponse&&) = default;
+
+bool GetTraceStatsResponse::operator==(const GetTraceStatsResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_stats_, other.trace_stats_);
+}
+
+bool GetTraceStatsResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_stats */:
+        (*trace_stats_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetTraceStatsResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetTraceStatsResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetTraceStatsResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_stats
+  if (_has_field_[1]) {
+    (*trace_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetTraceStatsRequest::GetTraceStatsRequest() = default;
+GetTraceStatsRequest::~GetTraceStatsRequest() = default;
+GetTraceStatsRequest::GetTraceStatsRequest(const GetTraceStatsRequest&) = default;
+GetTraceStatsRequest& GetTraceStatsRequest::operator=(const GetTraceStatsRequest&) = default;
+GetTraceStatsRequest::GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept = default;
+GetTraceStatsRequest& GetTraceStatsRequest::operator=(GetTraceStatsRequest&&) = default;
+
+bool GetTraceStatsRequest::operator==(const GetTraceStatsRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool GetTraceStatsRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetTraceStatsRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetTraceStatsRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetTraceStatsRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+AttachResponse::AttachResponse() = default;
+AttachResponse::~AttachResponse() = default;
+AttachResponse::AttachResponse(const AttachResponse&) = default;
+AttachResponse& AttachResponse::operator=(const AttachResponse&) = default;
+AttachResponse::AttachResponse(AttachResponse&&) noexcept = default;
+AttachResponse& AttachResponse::operator=(AttachResponse&&) = default;
+
+bool AttachResponse::operator==(const AttachResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_);
+}
+
+bool AttachResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_config */:
+        (*trace_config_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AttachResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AttachResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AttachResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+AttachRequest::AttachRequest() = default;
+AttachRequest::~AttachRequest() = default;
+AttachRequest::AttachRequest(const AttachRequest&) = default;
+AttachRequest& AttachRequest::operator=(const AttachRequest&) = default;
+AttachRequest::AttachRequest(AttachRequest&&) noexcept = default;
+AttachRequest& AttachRequest::operator=(AttachRequest&&) = default;
+
+bool AttachRequest::operator==(const AttachRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(key_, other.key_);
+}
+
+bool AttachRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* key */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &key_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string AttachRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> AttachRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void AttachRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: key
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, key_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DetachResponse::DetachResponse() = default;
+DetachResponse::~DetachResponse() = default;
+DetachResponse::DetachResponse(const DetachResponse&) = default;
+DetachResponse& DetachResponse::operator=(const DetachResponse&) = default;
+DetachResponse::DetachResponse(DetachResponse&&) noexcept = default;
+DetachResponse& DetachResponse::operator=(DetachResponse&&) = default;
+
+bool DetachResponse::operator==(const DetachResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool DetachResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DetachResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DetachResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DetachResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DetachRequest::DetachRequest() = default;
+DetachRequest::~DetachRequest() = default;
+DetachRequest::DetachRequest(const DetachRequest&) = default;
+DetachRequest& DetachRequest::operator=(const DetachRequest&) = default;
+DetachRequest::DetachRequest(DetachRequest&&) noexcept = default;
+DetachRequest& DetachRequest::operator=(DetachRequest&&) = default;
+
+bool DetachRequest::operator==(const DetachRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(key_, other.key_);
+}
+
+bool DetachRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* key */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &key_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DetachRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DetachRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DetachRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: key
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, key_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FlushResponse::FlushResponse() = default;
+FlushResponse::~FlushResponse() = default;
+FlushResponse::FlushResponse(const FlushResponse&) = default;
+FlushResponse& FlushResponse::operator=(const FlushResponse&) = default;
+FlushResponse::FlushResponse(FlushResponse&&) noexcept = default;
+FlushResponse& FlushResponse::operator=(FlushResponse&&) = default;
+
+bool FlushResponse::operator==(const FlushResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool FlushResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FlushResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FlushResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FlushResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FlushRequest::FlushRequest() = default;
+FlushRequest::~FlushRequest() = default;
+FlushRequest::FlushRequest(const FlushRequest&) = default;
+FlushRequest& FlushRequest::operator=(const FlushRequest&) = default;
+FlushRequest::FlushRequest(FlushRequest&&) noexcept = default;
+FlushRequest& FlushRequest::operator=(FlushRequest&&) = default;
+
+bool FlushRequest::operator==(const FlushRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(timeout_ms_, other.timeout_ms_)
+   && ::protozero::internal::gen_helpers::EqualsField(flags_, other.flags_);
+}
+
+bool FlushRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* timeout_ms */:
+        field.get(&timeout_ms_);
+        break;
+      case 2 /* flags */:
+        field.get(&flags_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FlushRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FlushRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FlushRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: timeout_ms
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, timeout_ms_, msg);
+  }
+
+  // Field 2: flags
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, flags_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FreeBuffersResponse::FreeBuffersResponse() = default;
+FreeBuffersResponse::~FreeBuffersResponse() = default;
+FreeBuffersResponse::FreeBuffersResponse(const FreeBuffersResponse&) = default;
+FreeBuffersResponse& FreeBuffersResponse::operator=(const FreeBuffersResponse&) = default;
+FreeBuffersResponse::FreeBuffersResponse(FreeBuffersResponse&&) noexcept = default;
+FreeBuffersResponse& FreeBuffersResponse::operator=(FreeBuffersResponse&&) = default;
+
+bool FreeBuffersResponse::operator==(const FreeBuffersResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool FreeBuffersResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FreeBuffersResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FreeBuffersResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FreeBuffersResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+FreeBuffersRequest::FreeBuffersRequest() = default;
+FreeBuffersRequest::~FreeBuffersRequest() = default;
+FreeBuffersRequest::FreeBuffersRequest(const FreeBuffersRequest&) = default;
+FreeBuffersRequest& FreeBuffersRequest::operator=(const FreeBuffersRequest&) = default;
+FreeBuffersRequest::FreeBuffersRequest(FreeBuffersRequest&&) noexcept = default;
+FreeBuffersRequest& FreeBuffersRequest::operator=(FreeBuffersRequest&&) = default;
+
+bool FreeBuffersRequest::operator==(const FreeBuffersRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(buffer_ids_, other.buffer_ids_);
+}
+
+bool FreeBuffersRequest::ParseFromArray(const void* raw, size_t size) {
+  buffer_ids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* buffer_ids */:
+        buffer_ids_.emplace_back();
+        field.get(&buffer_ids_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string FreeBuffersRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> FreeBuffersRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void FreeBuffersRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: buffer_ids
+  for (auto& it : buffer_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ReadBuffersResponse::ReadBuffersResponse() = default;
+ReadBuffersResponse::~ReadBuffersResponse() = default;
+ReadBuffersResponse::ReadBuffersResponse(const ReadBuffersResponse&) = default;
+ReadBuffersResponse& ReadBuffersResponse::operator=(const ReadBuffersResponse&) = default;
+ReadBuffersResponse::ReadBuffersResponse(ReadBuffersResponse&&) noexcept = default;
+ReadBuffersResponse& ReadBuffersResponse::operator=(ReadBuffersResponse&&) = default;
+
+bool ReadBuffersResponse::operator==(const ReadBuffersResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(slices_, other.slices_);
+}
+
+int ReadBuffersResponse::slices_size() const { return static_cast<int>(slices_.size()); }
+void ReadBuffersResponse::clear_slices() { slices_.clear(); }
+ReadBuffersResponse_Slice* ReadBuffersResponse::add_slices() { slices_.emplace_back(); return &slices_.back(); }
+bool ReadBuffersResponse::ParseFromArray(const void* raw, size_t size) {
+  slices_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 2 /* slices */:
+        slices_.emplace_back();
+        slices_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ReadBuffersResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ReadBuffersResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ReadBuffersResponse::Serialize(::protozero::Message* msg) const {
+  // Field 2: slices
+  for (auto& it : slices_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ReadBuffersResponse_Slice::ReadBuffersResponse_Slice() = default;
+ReadBuffersResponse_Slice::~ReadBuffersResponse_Slice() = default;
+ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&) = default;
+ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(const ReadBuffersResponse_Slice&) = default;
+ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept = default;
+ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(ReadBuffersResponse_Slice&&) = default;
+
+bool ReadBuffersResponse_Slice::operator==(const ReadBuffersResponse_Slice& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_, other.data_)
+   && ::protozero::internal::gen_helpers::EqualsField(last_slice_for_packet_, other.last_slice_for_packet_);
+}
+
+bool ReadBuffersResponse_Slice::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data */:
+        field.get(&data_);
+        break;
+      case 2 /* last_slice_for_packet */:
+        field.get(&last_slice_for_packet_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ReadBuffersResponse_Slice::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ReadBuffersResponse_Slice::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ReadBuffersResponse_Slice::Serialize(::protozero::Message* msg) const {
+  // Field 1: data
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, data_, msg);
+  }
+
+  // Field 2: last_slice_for_packet
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, last_slice_for_packet_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ReadBuffersRequest::ReadBuffersRequest() = default;
+ReadBuffersRequest::~ReadBuffersRequest() = default;
+ReadBuffersRequest::ReadBuffersRequest(const ReadBuffersRequest&) = default;
+ReadBuffersRequest& ReadBuffersRequest::operator=(const ReadBuffersRequest&) = default;
+ReadBuffersRequest::ReadBuffersRequest(ReadBuffersRequest&&) noexcept = default;
+ReadBuffersRequest& ReadBuffersRequest::operator=(ReadBuffersRequest&&) = default;
+
+bool ReadBuffersRequest::operator==(const ReadBuffersRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool ReadBuffersRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ReadBuffersRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ReadBuffersRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ReadBuffersRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DisableTracingResponse::DisableTracingResponse() = default;
+DisableTracingResponse::~DisableTracingResponse() = default;
+DisableTracingResponse::DisableTracingResponse(const DisableTracingResponse&) = default;
+DisableTracingResponse& DisableTracingResponse::operator=(const DisableTracingResponse&) = default;
+DisableTracingResponse::DisableTracingResponse(DisableTracingResponse&&) noexcept = default;
+DisableTracingResponse& DisableTracingResponse::operator=(DisableTracingResponse&&) = default;
+
+bool DisableTracingResponse::operator==(const DisableTracingResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool DisableTracingResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DisableTracingResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DisableTracingResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DisableTracingResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+DisableTracingRequest::DisableTracingRequest() = default;
+DisableTracingRequest::~DisableTracingRequest() = default;
+DisableTracingRequest::DisableTracingRequest(const DisableTracingRequest&) = default;
+DisableTracingRequest& DisableTracingRequest::operator=(const DisableTracingRequest&) = default;
+DisableTracingRequest::DisableTracingRequest(DisableTracingRequest&&) noexcept = default;
+DisableTracingRequest& DisableTracingRequest::operator=(DisableTracingRequest&&) = default;
+
+bool DisableTracingRequest::operator==(const DisableTracingRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool DisableTracingRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string DisableTracingRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> DisableTracingRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void DisableTracingRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChangeTraceConfigResponse::ChangeTraceConfigResponse() = default;
+ChangeTraceConfigResponse::~ChangeTraceConfigResponse() = default;
+ChangeTraceConfigResponse::ChangeTraceConfigResponse(const ChangeTraceConfigResponse&) = default;
+ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(const ChangeTraceConfigResponse&) = default;
+ChangeTraceConfigResponse::ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept = default;
+ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(ChangeTraceConfigResponse&&) = default;
+
+bool ChangeTraceConfigResponse::operator==(const ChangeTraceConfigResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool ChangeTraceConfigResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChangeTraceConfigResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChangeTraceConfigResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChangeTraceConfigResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ChangeTraceConfigRequest::ChangeTraceConfigRequest() = default;
+ChangeTraceConfigRequest::~ChangeTraceConfigRequest() = default;
+ChangeTraceConfigRequest::ChangeTraceConfigRequest(const ChangeTraceConfigRequest&) = default;
+ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(const ChangeTraceConfigRequest&) = default;
+ChangeTraceConfigRequest::ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept = default;
+ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(ChangeTraceConfigRequest&&) = default;
+
+bool ChangeTraceConfigRequest::operator==(const ChangeTraceConfigRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_);
+}
+
+bool ChangeTraceConfigRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_config */:
+        (*trace_config_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ChangeTraceConfigRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ChangeTraceConfigRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ChangeTraceConfigRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+StartTracingResponse::StartTracingResponse() = default;
+StartTracingResponse::~StartTracingResponse() = default;
+StartTracingResponse::StartTracingResponse(const StartTracingResponse&) = default;
+StartTracingResponse& StartTracingResponse::operator=(const StartTracingResponse&) = default;
+StartTracingResponse::StartTracingResponse(StartTracingResponse&&) noexcept = default;
+StartTracingResponse& StartTracingResponse::operator=(StartTracingResponse&&) = default;
+
+bool StartTracingResponse::operator==(const StartTracingResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool StartTracingResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StartTracingResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StartTracingResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StartTracingResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+StartTracingRequest::StartTracingRequest() = default;
+StartTracingRequest::~StartTracingRequest() = default;
+StartTracingRequest::StartTracingRequest(const StartTracingRequest&) = default;
+StartTracingRequest& StartTracingRequest::operator=(const StartTracingRequest&) = default;
+StartTracingRequest::StartTracingRequest(StartTracingRequest&&) noexcept = default;
+StartTracingRequest& StartTracingRequest::operator=(StartTracingRequest&&) = default;
+
+bool StartTracingRequest::operator==(const StartTracingRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool StartTracingRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string StartTracingRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> StartTracingRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void StartTracingRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+EnableTracingResponse::EnableTracingResponse() = default;
+EnableTracingResponse::~EnableTracingResponse() = default;
+EnableTracingResponse::EnableTracingResponse(const EnableTracingResponse&) = default;
+EnableTracingResponse& EnableTracingResponse::operator=(const EnableTracingResponse&) = default;
+EnableTracingResponse::EnableTracingResponse(EnableTracingResponse&&) noexcept = default;
+EnableTracingResponse& EnableTracingResponse::operator=(EnableTracingResponse&&) = default;
+
+bool EnableTracingResponse::operator==(const EnableTracingResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(disabled_, other.disabled_)
+   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_);
+}
+
+bool EnableTracingResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* disabled */:
+        field.get(&disabled_);
+        break;
+      case 3 /* error */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EnableTracingResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnableTracingResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnableTracingResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: disabled
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, disabled_, msg);
+  }
+
+  // Field 3: error
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, error_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+EnableTracingRequest::EnableTracingRequest() = default;
+EnableTracingRequest::~EnableTracingRequest() = default;
+EnableTracingRequest::EnableTracingRequest(const EnableTracingRequest&) = default;
+EnableTracingRequest& EnableTracingRequest::operator=(const EnableTracingRequest&) = default;
+EnableTracingRequest::EnableTracingRequest(EnableTracingRequest&&) noexcept = default;
+EnableTracingRequest& EnableTracingRequest::operator=(EnableTracingRequest&&) = default;
+
+bool EnableTracingRequest::operator==(const EnableTracingRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
+   && ::protozero::internal::gen_helpers::EqualsField(attach_notification_only_, other.attach_notification_only_);
+}
+
+bool EnableTracingRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_config */:
+        (*trace_config_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* attach_notification_only */:
+        field.get(&attach_notification_only_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string EnableTracingRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> EnableTracingRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void EnableTracingRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_config
+  if (_has_field_[1]) {
+    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: attach_notification_only
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, attach_notification_only_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+SyncResponse::SyncResponse() = default;
+SyncResponse::~SyncResponse() = default;
+SyncResponse::SyncResponse(const SyncResponse&) = default;
+SyncResponse& SyncResponse::operator=(const SyncResponse&) = default;
+SyncResponse::SyncResponse(SyncResponse&&) noexcept = default;
+SyncResponse& SyncResponse::operator=(SyncResponse&&) = default;
+
+bool SyncResponse::operator==(const SyncResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool SyncResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SyncResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SyncResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SyncResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+SyncRequest::SyncRequest() = default;
+SyncRequest::~SyncRequest() = default;
+SyncRequest::SyncRequest(const SyncRequest&) = default;
+SyncRequest& SyncRequest::operator=(const SyncRequest&) = default;
+SyncRequest::SyncRequest(SyncRequest&&) noexcept = default;
+SyncRequest& SyncRequest::operator=(SyncRequest&&) = default;
+
+bool SyncRequest::operator==(const SyncRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool SyncRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string SyncRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> SyncRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void SyncRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse::GetAsyncCommandResponse() = default;
+GetAsyncCommandResponse::~GetAsyncCommandResponse() = default;
+GetAsyncCommandResponse::GetAsyncCommandResponse(const GetAsyncCommandResponse&) = default;
+GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(const GetAsyncCommandResponse&) = default;
+GetAsyncCommandResponse::GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept = default;
+GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(GetAsyncCommandResponse&&) = default;
+
+bool GetAsyncCommandResponse::operator==(const GetAsyncCommandResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(setup_tracing_, other.setup_tracing_)
+   && ::protozero::internal::gen_helpers::EqualsField(setup_data_source_, other.setup_data_source_)
+   && ::protozero::internal::gen_helpers::EqualsField(start_data_source_, other.start_data_source_)
+   && ::protozero::internal::gen_helpers::EqualsField(stop_data_source_, other.stop_data_source_)
+   && ::protozero::internal::gen_helpers::EqualsField(flush_, other.flush_)
+   && ::protozero::internal::gen_helpers::EqualsField(clear_incremental_state_, other.clear_incremental_state_);
+}
+
+bool GetAsyncCommandResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 3 /* setup_tracing */:
+        (*setup_tracing_).ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* setup_data_source */:
+        (*setup_data_source_).ParseFromArray(field.data(), field.size());
+        break;
+      case 1 /* start_data_source */:
+        (*start_data_source_).ParseFromArray(field.data(), field.size());
+        break;
+      case 2 /* stop_data_source */:
+        (*stop_data_source_).ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* flush */:
+        (*flush_).ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* clear_incremental_state */:
+        (*clear_incremental_state_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse::Serialize(::protozero::Message* msg) const {
+  // Field 3: setup_tracing
+  if (_has_field_[3]) {
+    (*setup_tracing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 6: setup_data_source
+  if (_has_field_[6]) {
+    (*setup_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 1: start_data_source
+  if (_has_field_[1]) {
+    (*start_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  // Field 2: stop_data_source
+  if (_has_field_[2]) {
+    (*stop_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  // Field 5: flush
+  if (_has_field_[5]) {
+    (*flush_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 7: clear_incremental_state
+  if (_has_field_[7]) {
+    (*clear_incremental_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState() = default;
+GetAsyncCommandResponse_ClearIncrementalState::~GetAsyncCommandResponse_ClearIncrementalState() = default;
+GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
+GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
+GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept = default;
+GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(GetAsyncCommandResponse_ClearIncrementalState&&) = default;
+
+bool GetAsyncCommandResponse_ClearIncrementalState::operator==(const GetAsyncCommandResponse_ClearIncrementalState& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_ids_, other.data_source_ids_);
+}
+
+bool GetAsyncCommandResponse_ClearIncrementalState::ParseFromArray(const void* raw, size_t size) {
+  data_source_ids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_ids */:
+        data_source_ids_.emplace_back();
+        field.get(&data_source_ids_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_ClearIncrementalState::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_ClearIncrementalState::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_ClearIncrementalState::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_ids
+  for (auto& it : data_source_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush() = default;
+GetAsyncCommandResponse_Flush::~GetAsyncCommandResponse_Flush() = default;
+GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&) = default;
+GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(const GetAsyncCommandResponse_Flush&) = default;
+GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept = default;
+GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(GetAsyncCommandResponse_Flush&&) = default;
+
+bool GetAsyncCommandResponse_Flush::operator==(const GetAsyncCommandResponse_Flush& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_ids_, other.data_source_ids_)
+   && ::protozero::internal::gen_helpers::EqualsField(request_id_, other.request_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(flags_, other.flags_);
+}
+
+bool GetAsyncCommandResponse_Flush::ParseFromArray(const void* raw, size_t size) {
+  data_source_ids_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_ids */:
+        data_source_ids_.emplace_back();
+        field.get(&data_source_ids_.back());
+        break;
+      case 2 /* request_id */:
+        field.get(&request_id_);
+        break;
+      case 3 /* flags */:
+        field.get(&flags_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_Flush::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_Flush::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_Flush::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_ids
+  for (auto& it : data_source_ids_) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
+  }
+
+  // Field 2: request_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, request_id_, msg);
+  }
+
+  // Field 3: flags
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(3, flags_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource() = default;
+GetAsyncCommandResponse_StopDataSource::~GetAsyncCommandResponse_StopDataSource() = default;
+GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&) = default;
+GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(const GetAsyncCommandResponse_StopDataSource&) = default;
+GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept = default;
+GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(GetAsyncCommandResponse_StopDataSource&&) = default;
+
+bool GetAsyncCommandResponse_StopDataSource::operator==(const GetAsyncCommandResponse_StopDataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(instance_id_, other.instance_id_);
+}
+
+bool GetAsyncCommandResponse_StopDataSource::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* instance_id */:
+        field.get(&instance_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_StopDataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_StopDataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_StopDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: instance_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, instance_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource() = default;
+GetAsyncCommandResponse_StartDataSource::~GetAsyncCommandResponse_StartDataSource() = default;
+GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&) = default;
+GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(const GetAsyncCommandResponse_StartDataSource&) = default;
+GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept = default;
+GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(GetAsyncCommandResponse_StartDataSource&&) = default;
+
+bool GetAsyncCommandResponse_StartDataSource::operator==(const GetAsyncCommandResponse_StartDataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(new_instance_id_, other.new_instance_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_);
+}
+
+bool GetAsyncCommandResponse_StartDataSource::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* new_instance_id */:
+        field.get(&new_instance_id_);
+        break;
+      case 2 /* config */:
+        (*config_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_StartDataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_StartDataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_StartDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: new_instance_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, new_instance_id_, msg);
+  }
+
+  // Field 2: config
+  if (_has_field_[2]) {
+    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource() = default;
+GetAsyncCommandResponse_SetupDataSource::~GetAsyncCommandResponse_SetupDataSource() = default;
+GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&) = default;
+GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(const GetAsyncCommandResponse_SetupDataSource&) = default;
+GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept = default;
+GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(GetAsyncCommandResponse_SetupDataSource&&) = default;
+
+bool GetAsyncCommandResponse_SetupDataSource::operator==(const GetAsyncCommandResponse_SetupDataSource& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(new_instance_id_, other.new_instance_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_);
+}
+
+bool GetAsyncCommandResponse_SetupDataSource::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* new_instance_id */:
+        field.get(&new_instance_id_);
+        break;
+      case 2 /* config */:
+        (*config_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_SetupDataSource::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_SetupDataSource::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_SetupDataSource::Serialize(::protozero::Message* msg) const {
+  // Field 1: new_instance_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, new_instance_id_, msg);
+  }
+
+  // Field 2: config
+  if (_has_field_[2]) {
+    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing() = default;
+GetAsyncCommandResponse_SetupTracing::~GetAsyncCommandResponse_SetupTracing() = default;
+GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&) = default;
+GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(const GetAsyncCommandResponse_SetupTracing&) = default;
+GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept = default;
+GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(GetAsyncCommandResponse_SetupTracing&&) = default;
+
+bool GetAsyncCommandResponse_SetupTracing::operator==(const GetAsyncCommandResponse_SetupTracing& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(shared_buffer_page_size_kb_, other.shared_buffer_page_size_kb_)
+   && ::protozero::internal::gen_helpers::EqualsField(shm_key_windows_, other.shm_key_windows_);
+}
+
+bool GetAsyncCommandResponse_SetupTracing::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* shared_buffer_page_size_kb */:
+        field.get(&shared_buffer_page_size_kb_);
+        break;
+      case 2 /* shm_key_windows */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &shm_key_windows_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandResponse_SetupTracing::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandResponse_SetupTracing::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandResponse_SetupTracing::Serialize(::protozero::Message* msg) const {
+  // Field 1: shared_buffer_page_size_kb
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, shared_buffer_page_size_kb_, msg);
+  }
+
+  // Field 2: shm_key_windows
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, shm_key_windows_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+GetAsyncCommandRequest::GetAsyncCommandRequest() = default;
+GetAsyncCommandRequest::~GetAsyncCommandRequest() = default;
+GetAsyncCommandRequest::GetAsyncCommandRequest(const GetAsyncCommandRequest&) = default;
+GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(const GetAsyncCommandRequest&) = default;
+GetAsyncCommandRequest::GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept = default;
+GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(GetAsyncCommandRequest&&) = default;
+
+bool GetAsyncCommandRequest::operator==(const GetAsyncCommandRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool GetAsyncCommandRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string GetAsyncCommandRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> GetAsyncCommandRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void GetAsyncCommandRequest::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ActivateTriggersResponse::ActivateTriggersResponse() = default;
+ActivateTriggersResponse::~ActivateTriggersResponse() = default;
+ActivateTriggersResponse::ActivateTriggersResponse(const ActivateTriggersResponse&) = default;
+ActivateTriggersResponse& ActivateTriggersResponse::operator=(const ActivateTriggersResponse&) = default;
+ActivateTriggersResponse::ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept = default;
+ActivateTriggersResponse& ActivateTriggersResponse::operator=(ActivateTriggersResponse&&) = default;
+
+bool ActivateTriggersResponse::operator==(const ActivateTriggersResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool ActivateTriggersResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ActivateTriggersResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ActivateTriggersResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ActivateTriggersResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+ActivateTriggersRequest::ActivateTriggersRequest() = default;
+ActivateTriggersRequest::~ActivateTriggersRequest() = default;
+ActivateTriggersRequest::ActivateTriggersRequest(const ActivateTriggersRequest&) = default;
+ActivateTriggersRequest& ActivateTriggersRequest::operator=(const ActivateTriggersRequest&) = default;
+ActivateTriggersRequest::ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept = default;
+ActivateTriggersRequest& ActivateTriggersRequest::operator=(ActivateTriggersRequest&&) = default;
+
+bool ActivateTriggersRequest::operator==(const ActivateTriggersRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trigger_names_, other.trigger_names_);
+}
+
+bool ActivateTriggersRequest::ParseFromArray(const void* raw, size_t size) {
+  trigger_names_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trigger_names */:
+        trigger_names_.emplace_back();
+        ::protozero::internal::gen_helpers::DeserializeString(field, &trigger_names_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string ActivateTriggersRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> ActivateTriggersRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void ActivateTriggersRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trigger_names
+  for (auto& it : trigger_names_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse() = default;
+NotifyDataSourceStoppedResponse::~NotifyDataSourceStoppedResponse() = default;
+NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&) = default;
+NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(const NotifyDataSourceStoppedResponse&) = default;
+NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept = default;
+NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(NotifyDataSourceStoppedResponse&&) = default;
+
+bool NotifyDataSourceStoppedResponse::operator==(const NotifyDataSourceStoppedResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool NotifyDataSourceStoppedResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NotifyDataSourceStoppedResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStoppedResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStoppedResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest() = default;
+NotifyDataSourceStoppedRequest::~NotifyDataSourceStoppedRequest() = default;
+NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&) = default;
+NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(const NotifyDataSourceStoppedRequest&) = default;
+NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept = default;
+NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(NotifyDataSourceStoppedRequest&&) = default;
+
+bool NotifyDataSourceStoppedRequest::operator==(const NotifyDataSourceStoppedRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_id_, other.data_source_id_);
+}
+
+bool NotifyDataSourceStoppedRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_id */:
+        field.get(&data_source_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NotifyDataSourceStoppedRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStoppedRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStoppedRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, data_source_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse() = default;
+NotifyDataSourceStartedResponse::~NotifyDataSourceStartedResponse() = default;
+NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&) = default;
+NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(const NotifyDataSourceStartedResponse&) = default;
+NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept = default;
+NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(NotifyDataSourceStartedResponse&&) = default;
+
+bool NotifyDataSourceStartedResponse::operator==(const NotifyDataSourceStartedResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool NotifyDataSourceStartedResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NotifyDataSourceStartedResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStartedResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStartedResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest() = default;
+NotifyDataSourceStartedRequest::~NotifyDataSourceStartedRequest() = default;
+NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&) = default;
+NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(const NotifyDataSourceStartedRequest&) = default;
+NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept = default;
+NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(NotifyDataSourceStartedRequest&&) = default;
+
+bool NotifyDataSourceStartedRequest::operator==(const NotifyDataSourceStartedRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_id_, other.data_source_id_);
+}
+
+bool NotifyDataSourceStartedRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_id */:
+        field.get(&data_source_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string NotifyDataSourceStartedRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> NotifyDataSourceStartedRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void NotifyDataSourceStartedRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, data_source_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+CommitDataResponse::CommitDataResponse() = default;
+CommitDataResponse::~CommitDataResponse() = default;
+CommitDataResponse::CommitDataResponse(const CommitDataResponse&) = default;
+CommitDataResponse& CommitDataResponse::operator=(const CommitDataResponse&) = default;
+CommitDataResponse::CommitDataResponse(CommitDataResponse&&) noexcept = default;
+CommitDataResponse& CommitDataResponse::operator=(CommitDataResponse&&) = default;
+
+bool CommitDataResponse::operator==(const CommitDataResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool CommitDataResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string CommitDataResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> CommitDataResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void CommitDataResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UnregisterTraceWriterResponse::UnregisterTraceWriterResponse() = default;
+UnregisterTraceWriterResponse::~UnregisterTraceWriterResponse() = default;
+UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&) = default;
+UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(const UnregisterTraceWriterResponse&) = default;
+UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept = default;
+UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(UnregisterTraceWriterResponse&&) = default;
+
+bool UnregisterTraceWriterResponse::operator==(const UnregisterTraceWriterResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool UnregisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnregisterTraceWriterResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterTraceWriterResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UnregisterTraceWriterRequest::UnregisterTraceWriterRequest() = default;
+UnregisterTraceWriterRequest::~UnregisterTraceWriterRequest() = default;
+UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&) = default;
+UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(const UnregisterTraceWriterRequest&) = default;
+UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept = default;
+UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(UnregisterTraceWriterRequest&&) = default;
+
+bool UnregisterTraceWriterRequest::operator==(const UnregisterTraceWriterRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_writer_id_, other.trace_writer_id_);
+}
+
+bool UnregisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_writer_id */:
+        field.get(&trace_writer_id_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnregisterTraceWriterRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterTraceWriterRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_writer_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_writer_id_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+RegisterTraceWriterResponse::RegisterTraceWriterResponse() = default;
+RegisterTraceWriterResponse::~RegisterTraceWriterResponse() = default;
+RegisterTraceWriterResponse::RegisterTraceWriterResponse(const RegisterTraceWriterResponse&) = default;
+RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(const RegisterTraceWriterResponse&) = default;
+RegisterTraceWriterResponse::RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept = default;
+RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(RegisterTraceWriterResponse&&) = default;
+
+bool RegisterTraceWriterResponse::operator==(const RegisterTraceWriterResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool RegisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string RegisterTraceWriterResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterTraceWriterResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+RegisterTraceWriterRequest::RegisterTraceWriterRequest() = default;
+RegisterTraceWriterRequest::~RegisterTraceWriterRequest() = default;
+RegisterTraceWriterRequest::RegisterTraceWriterRequest(const RegisterTraceWriterRequest&) = default;
+RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(const RegisterTraceWriterRequest&) = default;
+RegisterTraceWriterRequest::RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept = default;
+RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(RegisterTraceWriterRequest&&) = default;
+
+bool RegisterTraceWriterRequest::operator==(const RegisterTraceWriterRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(trace_writer_id_, other.trace_writer_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_);
+}
+
+bool RegisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* trace_writer_id */:
+        field.get(&trace_writer_id_);
+        break;
+      case 2 /* target_buffer */:
+        field.get(&target_buffer_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string RegisterTraceWriterRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterTraceWriterRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: trace_writer_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_writer_id_, msg);
+  }
+
+  // Field 2: target_buffer
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, target_buffer_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UnregisterDataSourceResponse::UnregisterDataSourceResponse() = default;
+UnregisterDataSourceResponse::~UnregisterDataSourceResponse() = default;
+UnregisterDataSourceResponse::UnregisterDataSourceResponse(const UnregisterDataSourceResponse&) = default;
+UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(const UnregisterDataSourceResponse&) = default;
+UnregisterDataSourceResponse::UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept = default;
+UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(UnregisterDataSourceResponse&&) = default;
+
+bool UnregisterDataSourceResponse::operator==(const UnregisterDataSourceResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool UnregisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnregisterDataSourceResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterDataSourceResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UnregisterDataSourceRequest::UnregisterDataSourceRequest() = default;
+UnregisterDataSourceRequest::~UnregisterDataSourceRequest() = default;
+UnregisterDataSourceRequest::UnregisterDataSourceRequest(const UnregisterDataSourceRequest&) = default;
+UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(const UnregisterDataSourceRequest&) = default;
+UnregisterDataSourceRequest::UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept = default;
+UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(UnregisterDataSourceRequest&&) = default;
+
+bool UnregisterDataSourceRequest::operator==(const UnregisterDataSourceRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_name_, other.data_source_name_);
+}
+
+bool UnregisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &data_source_name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UnregisterDataSourceRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UnregisterDataSourceRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UnregisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, data_source_name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UpdateDataSourceResponse::UpdateDataSourceResponse() = default;
+UpdateDataSourceResponse::~UpdateDataSourceResponse() = default;
+UpdateDataSourceResponse::UpdateDataSourceResponse(const UpdateDataSourceResponse&) = default;
+UpdateDataSourceResponse& UpdateDataSourceResponse::operator=(const UpdateDataSourceResponse&) = default;
+UpdateDataSourceResponse::UpdateDataSourceResponse(UpdateDataSourceResponse&&) noexcept = default;
+UpdateDataSourceResponse& UpdateDataSourceResponse::operator=(UpdateDataSourceResponse&&) = default;
+
+bool UpdateDataSourceResponse::operator==(const UpdateDataSourceResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
+}
+
+bool UpdateDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UpdateDataSourceResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UpdateDataSourceResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UpdateDataSourceResponse::Serialize(::protozero::Message* msg) const {
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+UpdateDataSourceRequest::UpdateDataSourceRequest() = default;
+UpdateDataSourceRequest::~UpdateDataSourceRequest() = default;
+UpdateDataSourceRequest::UpdateDataSourceRequest(const UpdateDataSourceRequest&) = default;
+UpdateDataSourceRequest& UpdateDataSourceRequest::operator=(const UpdateDataSourceRequest&) = default;
+UpdateDataSourceRequest::UpdateDataSourceRequest(UpdateDataSourceRequest&&) noexcept = default;
+UpdateDataSourceRequest& UpdateDataSourceRequest::operator=(UpdateDataSourceRequest&&) = default;
+
+bool UpdateDataSourceRequest::operator==(const UpdateDataSourceRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_descriptor_, other.data_source_descriptor_);
+}
+
+bool UpdateDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_descriptor */:
+        (*data_source_descriptor_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string UpdateDataSourceRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> UpdateDataSourceRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void UpdateDataSourceRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_descriptor
+  if (_has_field_[1]) {
+    (*data_source_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+RegisterDataSourceResponse::RegisterDataSourceResponse() = default;
+RegisterDataSourceResponse::~RegisterDataSourceResponse() = default;
+RegisterDataSourceResponse::RegisterDataSourceResponse(const RegisterDataSourceResponse&) = default;
+RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(const RegisterDataSourceResponse&) = default;
+RegisterDataSourceResponse::RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept = default;
+RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(RegisterDataSourceResponse&&) = default;
+
+bool RegisterDataSourceResponse::operator==(const RegisterDataSourceResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_);
+}
+
+bool RegisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* error */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string RegisterDataSourceResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterDataSourceResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: error
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, error_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+RegisterDataSourceRequest::RegisterDataSourceRequest() = default;
+RegisterDataSourceRequest::~RegisterDataSourceRequest() = default;
+RegisterDataSourceRequest::RegisterDataSourceRequest(const RegisterDataSourceRequest&) = default;
+RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(const RegisterDataSourceRequest&) = default;
+RegisterDataSourceRequest::RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept = default;
+RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(RegisterDataSourceRequest&&) = default;
+
+bool RegisterDataSourceRequest::operator==(const RegisterDataSourceRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_source_descriptor_, other.data_source_descriptor_);
+}
+
+bool RegisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* data_source_descriptor */:
+        (*data_source_descriptor_).ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string RegisterDataSourceRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> RegisterDataSourceRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void RegisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: data_source_descriptor
+  if (_has_field_[1]) {
+    (*data_source_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+InitializeConnectionResponse::InitializeConnectionResponse() = default;
+InitializeConnectionResponse::~InitializeConnectionResponse() = default;
+InitializeConnectionResponse::InitializeConnectionResponse(const InitializeConnectionResponse&) = default;
+InitializeConnectionResponse& InitializeConnectionResponse::operator=(const InitializeConnectionResponse&) = default;
+InitializeConnectionResponse::InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept = default;
+InitializeConnectionResponse& InitializeConnectionResponse::operator=(InitializeConnectionResponse&&) = default;
+
+bool InitializeConnectionResponse::operator==(const InitializeConnectionResponse& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(using_shmem_provided_by_producer_, other.using_shmem_provided_by_producer_)
+   && ::protozero::internal::gen_helpers::EqualsField(direct_smb_patching_supported_, other.direct_smb_patching_supported_)
+   && ::protozero::internal::gen_helpers::EqualsField(use_shmem_emulation_, other.use_shmem_emulation_);
+}
+
+bool InitializeConnectionResponse::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* using_shmem_provided_by_producer */:
+        field.get(&using_shmem_provided_by_producer_);
+        break;
+      case 2 /* direct_smb_patching_supported */:
+        field.get(&direct_smb_patching_supported_);
+        break;
+      case 3 /* use_shmem_emulation */:
+        field.get(&use_shmem_emulation_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InitializeConnectionResponse::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InitializeConnectionResponse::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InitializeConnectionResponse::Serialize(::protozero::Message* msg) const {
+  // Field 1: using_shmem_provided_by_producer
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, using_shmem_provided_by_producer_, msg);
+  }
+
+  // Field 2: direct_smb_patching_supported
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, direct_smb_patching_supported_, msg);
+  }
+
+  // Field 3: use_shmem_emulation
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, use_shmem_emulation_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+InitializeConnectionRequest::InitializeConnectionRequest() = default;
+InitializeConnectionRequest::~InitializeConnectionRequest() = default;
+InitializeConnectionRequest::InitializeConnectionRequest(const InitializeConnectionRequest&) = default;
+InitializeConnectionRequest& InitializeConnectionRequest::operator=(const InitializeConnectionRequest&) = default;
+InitializeConnectionRequest::InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept = default;
+InitializeConnectionRequest& InitializeConnectionRequest::operator=(InitializeConnectionRequest&&) = default;
+
+bool InitializeConnectionRequest::operator==(const InitializeConnectionRequest& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(shared_memory_page_size_hint_bytes_, other.shared_memory_page_size_hint_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(shared_memory_size_hint_bytes_, other.shared_memory_size_hint_bytes_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_name_, other.producer_name_)
+   && ::protozero::internal::gen_helpers::EqualsField(smb_scraping_mode_, other.smb_scraping_mode_)
+   && ::protozero::internal::gen_helpers::EqualsField(producer_provided_shmem_, other.producer_provided_shmem_)
+   && ::protozero::internal::gen_helpers::EqualsField(sdk_version_, other.sdk_version_)
+   && ::protozero::internal::gen_helpers::EqualsField(shm_key_windows_, other.shm_key_windows_);
+}
+
+bool InitializeConnectionRequest::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* shared_memory_page_size_hint_bytes */:
+        field.get(&shared_memory_page_size_hint_bytes_);
+        break;
+      case 2 /* shared_memory_size_hint_bytes */:
+        field.get(&shared_memory_size_hint_bytes_);
+        break;
+      case 3 /* producer_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_);
+        break;
+      case 4 /* smb_scraping_mode */:
+        field.get(&smb_scraping_mode_);
+        break;
+      case 6 /* producer_provided_shmem */:
+        field.get(&producer_provided_shmem_);
+        break;
+      case 8 /* sdk_version */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &sdk_version_);
+        break;
+      case 7 /* shm_key_windows */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &shm_key_windows_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string InitializeConnectionRequest::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> InitializeConnectionRequest::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void InitializeConnectionRequest::Serialize(::protozero::Message* msg) const {
+  // Field 1: shared_memory_page_size_hint_bytes
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, shared_memory_page_size_hint_bytes_, msg);
+  }
+
+  // Field 2: shared_memory_size_hint_bytes
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, shared_memory_size_hint_bytes_, msg);
+  }
+
+  // Field 3: producer_name
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, producer_name_, msg);
+  }
+
+  // Field 4: smb_scraping_mode
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(4, smb_scraping_mode_, msg);
+  }
+
+  // Field 6: producer_provided_shmem
+  if (_has_field_[6]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, producer_provided_shmem_, msg);
+  }
+
+  // Field 8: sdk_version
+  if (_has_field_[8]) {
+    ::protozero::internal::gen_helpers::SerializeString(8, sdk_version_, msg);
+  }
+
+  // Field 7: shm_key_windows
+  if (_has_field_[7]) {
+    ::protozero::internal::gen_helpers::SerializeString(7, shm_key_windows_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/wire_protocol.gen.cc
+// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#endif
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+IPCFrame::IPCFrame() = default;
+IPCFrame::~IPCFrame() = default;
+IPCFrame::IPCFrame(const IPCFrame&) = default;
+IPCFrame& IPCFrame::operator=(const IPCFrame&) = default;
+IPCFrame::IPCFrame(IPCFrame&&) noexcept = default;
+IPCFrame& IPCFrame::operator=(IPCFrame&&) = default;
+
+bool IPCFrame::operator==(const IPCFrame& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(request_id_, other.request_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_bind_service_, other.msg_bind_service_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_bind_service_reply_, other.msg_bind_service_reply_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_invoke_method_, other.msg_invoke_method_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_invoke_method_reply_, other.msg_invoke_method_reply_)
+   && ::protozero::internal::gen_helpers::EqualsField(msg_request_error_, other.msg_request_error_)
+   && ::protozero::internal::gen_helpers::EqualsField(set_peer_identity_, other.set_peer_identity_)
+   && ::protozero::internal::gen_helpers::EqualsField(data_for_testing_, other.data_for_testing_);
+}
+
+bool IPCFrame::ParseFromArray(const void* raw, size_t size) {
+  data_for_testing_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 2 /* request_id */:
+        field.get(&request_id_);
+        break;
+      case 3 /* msg_bind_service */:
+        (*msg_bind_service_).ParseFromArray(field.data(), field.size());
+        break;
+      case 4 /* msg_bind_service_reply */:
+        (*msg_bind_service_reply_).ParseFromArray(field.data(), field.size());
+        break;
+      case 5 /* msg_invoke_method */:
+        (*msg_invoke_method_).ParseFromArray(field.data(), field.size());
+        break;
+      case 6 /* msg_invoke_method_reply */:
+        (*msg_invoke_method_reply_).ParseFromArray(field.data(), field.size());
+        break;
+      case 7 /* msg_request_error */:
+        (*msg_request_error_).ParseFromArray(field.data(), field.size());
+        break;
+      case 8 /* set_peer_identity */:
+        (*set_peer_identity_).ParseFromArray(field.data(), field.size());
+        break;
+      case 1 /* data_for_testing */:
+        data_for_testing_.emplace_back();
+        field.get(&data_for_testing_.back());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame::Serialize(::protozero::Message* msg) const {
+  // Field 2: request_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, request_id_, msg);
+  }
+
+  // Field 3: msg_bind_service
+  if (_has_field_[3]) {
+    (*msg_bind_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  // Field 4: msg_bind_service_reply
+  if (_has_field_[4]) {
+    (*msg_bind_service_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
+  }
+
+  // Field 5: msg_invoke_method
+  if (_has_field_[5]) {
+    (*msg_invoke_method_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
+  }
+
+  // Field 6: msg_invoke_method_reply
+  if (_has_field_[6]) {
+    (*msg_invoke_method_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
+  }
+
+  // Field 7: msg_request_error
+  if (_has_field_[7]) {
+    (*msg_request_error_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
+  }
+
+  // Field 8: set_peer_identity
+  if (_has_field_[8]) {
+    (*set_peer_identity_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
+  }
+
+  // Field 1: data_for_testing
+  for (auto& it : data_for_testing_) {
+    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_SetPeerIdentity::IPCFrame_SetPeerIdentity() = default;
+IPCFrame_SetPeerIdentity::~IPCFrame_SetPeerIdentity() = default;
+IPCFrame_SetPeerIdentity::IPCFrame_SetPeerIdentity(const IPCFrame_SetPeerIdentity&) = default;
+IPCFrame_SetPeerIdentity& IPCFrame_SetPeerIdentity::operator=(const IPCFrame_SetPeerIdentity&) = default;
+IPCFrame_SetPeerIdentity::IPCFrame_SetPeerIdentity(IPCFrame_SetPeerIdentity&&) noexcept = default;
+IPCFrame_SetPeerIdentity& IPCFrame_SetPeerIdentity::operator=(IPCFrame_SetPeerIdentity&&) = default;
+
+bool IPCFrame_SetPeerIdentity::operator==(const IPCFrame_SetPeerIdentity& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
+   && ::protozero::internal::gen_helpers::EqualsField(uid_, other.uid_)
+   && ::protozero::internal::gen_helpers::EqualsField(machine_id_hint_, other.machine_id_hint_);
+}
+
+bool IPCFrame_SetPeerIdentity::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* pid */:
+        field.get(&pid_);
+        break;
+      case 2 /* uid */:
+        field.get(&uid_);
+        break;
+      case 3 /* machine_id_hint */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &machine_id_hint_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_SetPeerIdentity::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_SetPeerIdentity::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_SetPeerIdentity::Serialize(::protozero::Message* msg) const {
+  // Field 1: pid
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, pid_, msg);
+  }
+
+  // Field 2: uid
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, uid_, msg);
+  }
+
+  // Field 3: machine_id_hint
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, machine_id_hint_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_RequestError::IPCFrame_RequestError() = default;
+IPCFrame_RequestError::~IPCFrame_RequestError() = default;
+IPCFrame_RequestError::IPCFrame_RequestError(const IPCFrame_RequestError&) = default;
+IPCFrame_RequestError& IPCFrame_RequestError::operator=(const IPCFrame_RequestError&) = default;
+IPCFrame_RequestError::IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept = default;
+IPCFrame_RequestError& IPCFrame_RequestError::operator=(IPCFrame_RequestError&&) = default;
+
+bool IPCFrame_RequestError::operator==(const IPCFrame_RequestError& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_);
+}
+
+bool IPCFrame_RequestError::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* error */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_RequestError::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_RequestError::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_RequestError::Serialize(::protozero::Message* msg) const {
+  // Field 1: error
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, error_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply() = default;
+IPCFrame_InvokeMethodReply::~IPCFrame_InvokeMethodReply() = default;
+IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&) = default;
+IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(const IPCFrame_InvokeMethodReply&) = default;
+IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept = default;
+IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(IPCFrame_InvokeMethodReply&&) = default;
+
+bool IPCFrame_InvokeMethodReply::operator==(const IPCFrame_InvokeMethodReply& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
+   && ::protozero::internal::gen_helpers::EqualsField(has_more_, other.has_more_)
+   && ::protozero::internal::gen_helpers::EqualsField(reply_proto_, other.reply_proto_);
+}
+
+bool IPCFrame_InvokeMethodReply::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* success */:
+        field.get(&success_);
+        break;
+      case 2 /* has_more */:
+        field.get(&has_more_);
+        break;
+      case 3 /* reply_proto */:
+        field.get(&reply_proto_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_InvokeMethodReply::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_InvokeMethodReply::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_InvokeMethodReply::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
+  }
+
+  // Field 2: has_more
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, has_more_, msg);
+  }
+
+  // Field 3: reply_proto
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, reply_proto_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_InvokeMethod::IPCFrame_InvokeMethod() = default;
+IPCFrame_InvokeMethod::~IPCFrame_InvokeMethod() = default;
+IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&) = default;
+IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(const IPCFrame_InvokeMethod&) = default;
+IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept = default;
+IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(IPCFrame_InvokeMethod&&) = default;
+
+bool IPCFrame_InvokeMethod::operator==(const IPCFrame_InvokeMethod& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(service_id_, other.service_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(method_id_, other.method_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(args_proto_, other.args_proto_)
+   && ::protozero::internal::gen_helpers::EqualsField(drop_reply_, other.drop_reply_);
+}
+
+bool IPCFrame_InvokeMethod::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* service_id */:
+        field.get(&service_id_);
+        break;
+      case 2 /* method_id */:
+        field.get(&method_id_);
+        break;
+      case 3 /* args_proto */:
+        field.get(&args_proto_);
+        break;
+      case 4 /* drop_reply */:
+        field.get(&drop_reply_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_InvokeMethod::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_InvokeMethod::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_InvokeMethod::Serialize(::protozero::Message* msg) const {
+  // Field 1: service_id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, service_id_, msg);
+  }
+
+  // Field 2: method_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, method_id_, msg);
+  }
+
+  // Field 3: args_proto
+  if (_has_field_[3]) {
+    ::protozero::internal::gen_helpers::SerializeString(3, args_proto_, msg);
+  }
+
+  // Field 4: drop_reply
+  if (_has_field_[4]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, drop_reply_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_BindServiceReply::IPCFrame_BindServiceReply() = default;
+IPCFrame_BindServiceReply::~IPCFrame_BindServiceReply() = default;
+IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&) = default;
+IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(const IPCFrame_BindServiceReply&) = default;
+IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept = default;
+IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(IPCFrame_BindServiceReply&&) = default;
+
+bool IPCFrame_BindServiceReply::operator==(const IPCFrame_BindServiceReply& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
+   && ::protozero::internal::gen_helpers::EqualsField(service_id_, other.service_id_)
+   && ::protozero::internal::gen_helpers::EqualsField(methods_, other.methods_);
+}
+
+int IPCFrame_BindServiceReply::methods_size() const { return static_cast<int>(methods_.size()); }
+void IPCFrame_BindServiceReply::clear_methods() { methods_.clear(); }
+IPCFrame_BindServiceReply_MethodInfo* IPCFrame_BindServiceReply::add_methods() { methods_.emplace_back(); return &methods_.back(); }
+bool IPCFrame_BindServiceReply::ParseFromArray(const void* raw, size_t size) {
+  methods_.clear();
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* success */:
+        field.get(&success_);
+        break;
+      case 2 /* service_id */:
+        field.get(&service_id_);
+        break;
+      case 3 /* methods */:
+        methods_.emplace_back();
+        methods_.back().ParseFromArray(field.data(), field.size());
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_BindServiceReply::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_BindServiceReply::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_BindServiceReply::Serialize(::protozero::Message* msg) const {
+  // Field 1: success
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
+  }
+
+  // Field 2: service_id
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(2, service_id_, msg);
+  }
+
+  // Field 3: methods
+  for (auto& it : methods_) {
+    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo() = default;
+IPCFrame_BindServiceReply_MethodInfo::~IPCFrame_BindServiceReply_MethodInfo() = default;
+IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&) = default;
+IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(const IPCFrame_BindServiceReply_MethodInfo&) = default;
+IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept = default;
+IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(IPCFrame_BindServiceReply_MethodInfo&&) = default;
+
+bool IPCFrame_BindServiceReply_MethodInfo::operator==(const IPCFrame_BindServiceReply_MethodInfo& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
+   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
+}
+
+bool IPCFrame_BindServiceReply_MethodInfo::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* id */:
+        field.get(&id_);
+        break;
+      case 2 /* name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_BindServiceReply_MethodInfo::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_BindServiceReply_MethodInfo::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_BindServiceReply_MethodInfo::Serialize(::protozero::Message* msg) const {
+  // Field 1: id
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeVarInt(1, id_, msg);
+  }
+
+  // Field 2: name
+  if (_has_field_[2]) {
+    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+
+IPCFrame_BindService::IPCFrame_BindService() = default;
+IPCFrame_BindService::~IPCFrame_BindService() = default;
+IPCFrame_BindService::IPCFrame_BindService(const IPCFrame_BindService&) = default;
+IPCFrame_BindService& IPCFrame_BindService::operator=(const IPCFrame_BindService&) = default;
+IPCFrame_BindService::IPCFrame_BindService(IPCFrame_BindService&&) noexcept = default;
+IPCFrame_BindService& IPCFrame_BindService::operator=(IPCFrame_BindService&&) = default;
+
+bool IPCFrame_BindService::operator==(const IPCFrame_BindService& other) const {
+  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
+   && ::protozero::internal::gen_helpers::EqualsField(service_name_, other.service_name_);
+}
+
+bool IPCFrame_BindService::ParseFromArray(const void* raw, size_t size) {
+  unknown_fields_.clear();
+  bool packed_error = false;
+
+  ::protozero::ProtoDecoder dec(raw, size);
+  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
+    if (field.id() < _has_field_.size()) {
+      _has_field_.set(field.id());
+    }
+    switch (field.id()) {
+      case 1 /* service_name */:
+        ::protozero::internal::gen_helpers::DeserializeString(field, &service_name_);
+        break;
+      default:
+        field.SerializeAndAppendTo(&unknown_fields_);
+        break;
+    }
+  }
+  return !packed_error && !dec.bytes_left();
+}
+
+std::string IPCFrame_BindService::SerializeAsString() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsString();
+}
+
+std::vector<uint8_t> IPCFrame_BindService::SerializeAsArray() const {
+  ::protozero::internal::gen_helpers::MessageSerializer msg;
+  Serialize(msg.get());
+  return msg.SerializeAsArray();
+}
+
+void IPCFrame_BindService::Serialize(::protozero::Message* msg) const {
+  // Field 1: service_name
+  if (_has_field_[1]) {
+    ::protozero::internal::gen_helpers::SerializeString(1, service_name_, msg);
+  }
+
+  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
+}
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+// gen_amalgamated begin source: src/base/unix_socket.cc
+// gen_amalgamated begin header: include/perfetto/ext/base/unix_socket.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
+#define INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+
+struct msghdr;
+
+namespace perfetto {
+namespace base {
+
+// Define the ScopedSocketHandle type.
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+int CloseSocket(SocketHandle);   // A wrapper around ::closesocket().
+using ScopedSocketHandle =
+    ScopedResource<SocketHandle, CloseSocket, static_cast<SocketHandle>(-1)>;
+#else
+using ScopedSocketHandle = ScopedFile;
+#endif
+
+class TaskRunner;
+
+// Use arbitrarily high values to avoid that some code accidentally ends up
+// assuming that these enum values match the sysroot's SOCK_xxx defines rather
+// than using MkSockType() / MkSockFamily().
+enum class SockType { kStream = 100, kDgram, kSeqPacket };
+enum class SockFamily { kUnspec = 0, kUnix = 200, kInet, kInet6, kVsock };
+
+// Controls the getsockopt(SO_PEERCRED) behavior, which allows to obtain the
+// peer credentials.
+enum class SockPeerCredMode {
+  // Obtain the peer credentials immediately after connection and cache them.
+  kReadOnConnect = 0,
+
+  // Don't read peer credentials at all. Calls to peer_uid()/peer_pid() will
+  // hit a DCHECK and return kInvalidUid/Pid in release builds.
+  kIgnore = 1,
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  kDefault = kIgnore,
+#else
+  kDefault = kReadOnConnect,
+#endif
+};
+
+// Returns the socket family from the full addres that perfetto uses.
+// Addr can be:
+// - /path/to/socket : for linked AF_UNIX sockets.
+// - @abstract_name  : for abstract AF_UNIX sockets.
+// - 1.2.3.4:8080    : for Inet sockets.
+// - [::1]:8080      : for Inet6 sockets.
+// - vsock://-1:3000 : for VM sockets.
+SockFamily GetSockFamily(const char* addr);
+
+// Returns whether inter-process shared memory is supported for the socket.
+inline bool SockShmemSupported(SockFamily sock_family) {
+  return sock_family == SockFamily::kUnix;
+}
+inline bool SockShmemSupported(const char* addr) {
+  return SockShmemSupported(GetSockFamily(addr));
+}
+
+// UnixSocketRaw is a basic wrapper around sockets. It exposes wrapper
+// methods that take care of most common pitfalls (e.g., marking fd as
+// O_CLOEXEC, avoiding SIGPIPE, properly handling partial writes). It is used as
+// a building block for the more sophisticated UnixSocket class which depends
+// on base::TaskRunner.
+class UnixSocketRaw {
+ public:
+  // Creates a new unconnected unix socket.
+  static UnixSocketRaw CreateMayFail(SockFamily family, SockType type);
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Crates a pair of connected sockets.
+  static std::pair<UnixSocketRaw, UnixSocketRaw> CreatePairPosix(SockFamily,
+                                                                 SockType);
+#endif
+
+  // Creates an uninitialized unix socket.
+  UnixSocketRaw();
+
+  // Creates a unix socket adopting an existing file descriptor. This is
+  // typically used to inherit fds from init via environment variables.
+  UnixSocketRaw(ScopedSocketHandle, SockFamily, SockType);
+
+  ~UnixSocketRaw() = default;
+  UnixSocketRaw(UnixSocketRaw&&) noexcept = default;
+  UnixSocketRaw& operator=(UnixSocketRaw&&) = default;
+
+  bool Bind(const std::string& socket_name);
+  bool Listen();
+  bool Connect(const std::string& socket_name);
+  bool SetTxTimeout(uint32_t timeout_ms);
+  bool SetRxTimeout(uint32_t timeout_ms);
+  void Shutdown();
+  void SetBlocking(bool);
+  void DcheckIsBlocking(bool expected) const;  // No-op on release and Win.
+  void SetRetainOnExec(bool retain);
+  std::string GetSockAddr() const;
+  SockType type() const { return type_; }
+  SockFamily family() const { return family_; }
+  SocketHandle fd() const { return *fd_; }
+  explicit operator bool() const { return !!fd_; }
+
+  // This is the handle that passed to TaskRunner.AddFileDescriptorWatch().
+  // On UNIX this is just the socket FD. On Windows, we need to create a
+  // dedicated event object.
+  PlatformHandle watch_handle() const {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    return *event_handle_;
+#else
+    return *fd_;
+#endif
+  }
+
+  ScopedSocketHandle ReleaseFd() { return std::move(fd_); }
+
+  // |send_fds| and |num_fds| are ignored on Windows.
+  ssize_t Send(const void* msg,
+               size_t len,
+               const int* send_fds = nullptr,
+               size_t num_fds = 0);
+
+  ssize_t SendStr(const std::string& str) {
+    return Send(str.data(), str.size());
+  }
+
+  // |fd_vec| and |max_files| are ignored on Windows.
+  ssize_t Receive(void* msg,
+                  size_t len,
+                  ScopedFile* fd_vec = nullptr,
+                  size_t max_files = 0);
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // UNIX-specific helpers to deal with SCM_RIGHTS.
+
+  // Re-enter sendmsg until all the data has been sent or an error occurs.
+  // TODO(fmayer): Figure out how to do timeouts here for heapprofd.
+  ssize_t SendMsgAllPosix(struct msghdr* msg);
+
+  // Exposed for testing only.
+  // Update msghdr so subsequent sendmsg will send data that remains after n
+  // bytes have already been sent.
+  static void ShiftMsgHdrPosix(size_t n, struct msghdr* msg);
+#endif
+
+ private:
+  UnixSocketRaw(SockFamily, SockType);
+
+  UnixSocketRaw(const UnixSocketRaw&) = delete;
+  UnixSocketRaw& operator=(const UnixSocketRaw&) = delete;
+
+  ScopedSocketHandle fd_;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  ScopedPlatformHandle event_handle_;
+#endif
+  SockFamily family_ = SockFamily::kUnix;
+  SockType type_ = SockType::kStream;
+  uint32_t tx_timeout_ms_ = 0;
+};
+
+// A non-blocking UNIX domain socket. Allows also to transfer file descriptors.
+// None of the methods in this class are blocking.
+// The main design goal is making strong guarantees on the EventListener
+// callbacks, in order to avoid ending in some undefined state.
+// In case of any error it will aggressively just shut down the socket and
+// notify the failure with OnConnect(false) or OnDisconnect() depending on the
+// state of the socket (see below).
+// EventListener callbacks stop happening as soon as the instance is destroyed.
+//
+// Lifecycle of a client socket:
+//
+//                           Connect()
+//                               |
+//            +------------------+------------------+
+//            | (success)                           | (failure or Shutdown())
+//            V                                     V
+//     OnConnect(true)                         OnConnect(false)
+//            |
+//            V
+//    OnDataAvailable()
+//            |
+//            V
+//     OnDisconnect()  (failure or shutdown)
+//
+//
+// Lifecycle of a server socket:
+//
+//                          Listen()  --> returns false in case of errors.
+//                             |
+//                             V
+//              OnNewIncomingConnection(new_socket)
+//
+//          (|new_socket| inherits the same EventListener)
+//                             |
+//                             V
+//                     OnDataAvailable()
+//                             | (failure or Shutdown())
+//                             V
+//                       OnDisconnect()
+class PERFETTO_EXPORT_COMPONENT UnixSocket {
+ public:
+  class EventListener {
+   public:
+    EventListener() = default;
+    virtual ~EventListener();
+
+    EventListener(const EventListener&) = delete;
+    EventListener& operator=(const EventListener&) = delete;
+
+    EventListener(EventListener&&) noexcept = default;
+    EventListener& operator=(EventListener&&) noexcept = default;
+
+    // After Listen().
+    // |self| may be null if the connection was not accepted via a listen
+    // socket.
+    virtual void OnNewIncomingConnection(
+        UnixSocket* self,
+        std::unique_ptr<UnixSocket> new_connection);
+
+    // After Connect(), whether successful or not.
+    virtual void OnConnect(UnixSocket* self, bool connected);
+
+    // After a successful Connect() or OnNewIncomingConnection(). Either the
+    // other endpoint did disconnect or some other error happened.
+    virtual void OnDisconnect(UnixSocket* self);
+
+    // Whenever there is data available to Receive(). Note that spurious FD
+    // watch events are possible, so it is possible that Receive() soon after
+    // OnDataAvailable() returns 0 (just ignore those).
+    virtual void OnDataAvailable(UnixSocket* self);
+  };
+
+  enum class State {
+    kDisconnected = 0,  // Failed connection, peer disconnection or Shutdown().
+    kConnecting,  // Soon after Connect(), before it either succeeds or fails.
+    kConnected,   // After a successful Connect().
+    kListening    // After Listen(), until Shutdown().
+  };
+
+  // Creates a socket and starts listening. If SockFamily::kUnix and
+  // |socket_name| starts with a '@', an abstract UNIX dmoain socket will be
+  // created instead of a filesystem-linked UNIX socket (Linux/Android only).
+  // If SockFamily::kInet, |socket_name| is host:port (e.g., "1.2.3.4:8000").
+  // If SockFamily::kInet6, |socket_name| is [host]:port (e.g., "[::1]:8000").
+  // Returns nullptr if the socket creation or bind fails. If listening fails,
+  // (e.g. if another socket with the same name is already listening) the
+  // returned socket will have is_listening() == false.
+  static std::unique_ptr<UnixSocket> Listen(const std::string& socket_name,
+                                            EventListener*,
+                                            TaskRunner*,
+                                            SockFamily,
+                                            SockType);
+
+  // Attaches to a pre-existing socket. The socket must have been created in
+  // SOCK_STREAM mode and the caller must have called bind() on it.
+  static std::unique_ptr<UnixSocket> Listen(ScopedSocketHandle,
+                                            EventListener*,
+                                            TaskRunner*,
+                                            SockFamily,
+                                            SockType);
+
+  // Creates a Unix domain socket and connects to the listening endpoint.
+  // Returns always an instance. EventListener::OnConnect(bool success) will
+  // be called always, whether the connection succeeded or not.
+  static std::unique_ptr<UnixSocket> Connect(
+      const std::string& socket_name,
+      EventListener*,
+      TaskRunner*,
+      SockFamily,
+      SockType,
+      SockPeerCredMode = SockPeerCredMode::kDefault);
+
+  // Constructs a UnixSocket using the given connected socket.
+  static std::unique_ptr<UnixSocket> AdoptConnected(
+      ScopedSocketHandle,
+      EventListener*,
+      TaskRunner*,
+      SockFamily,
+      SockType,
+      SockPeerCredMode = SockPeerCredMode::kDefault);
+
+  UnixSocket(const UnixSocket&) = delete;
+  UnixSocket& operator=(const UnixSocket&) = delete;
+  // Cannot be easily moved because of tasks from the FileDescriptorWatch.
+  UnixSocket(UnixSocket&&) = delete;
+  UnixSocket& operator=(UnixSocket&&) = delete;
+
+  // This class gives the hard guarantee that no callback is called on the
+  // passed EventListener immediately after the object has been destroyed.
+  // Any queued callback will be silently dropped.
+  ~UnixSocket();
+
+  // Shuts down the current connection, if any. If the socket was Listen()-ing,
+  // stops listening. The socket goes back to kNotInitialized state, so it can
+  // be reused with Listen() or Connect().
+  void Shutdown(bool notify);
+
+  void SetTxTimeout(uint32_t timeout_ms) {
+    PERFETTO_CHECK(sock_raw_.SetTxTimeout(timeout_ms));
+  }
+  void SetRxTimeout(uint32_t timeout_ms) {
+    PERFETTO_CHECK(sock_raw_.SetRxTimeout(timeout_ms));
+  }
+
+  std::string GetSockAddr() const { return sock_raw_.GetSockAddr(); }
+
+  // Returns true is the message was queued, false if there was no space in the
+  // output buffer, in which case the client should retry or give up.
+  // If any other error happens the socket will be shutdown and
+  // EventListener::OnDisconnect() will be called.
+  // If the socket is not connected, Send() will just return false.
+  // Does not append a null string terminator to msg in any case.
+  bool Send(const void* msg, size_t len, const int* send_fds, size_t num_fds);
+
+  inline bool Send(const void* msg, size_t len, int send_fd = -1) {
+    if (send_fd != -1)
+      return Send(msg, len, &send_fd, 1);
+    return Send(msg, len, nullptr, 0);
+  }
+
+  inline bool SendStr(const std::string& msg) {
+    return Send(msg.data(), msg.size(), -1);
+  }
+
+  // Returns the number of bytes (<= |len|) written in |msg| or 0 if there
+  // is no data in the buffer to read or an error occurs (in which case a
+  // EventListener::OnDisconnect() will follow).
+  // If the ScopedFile pointer is not null and a FD is received, it moves the
+  // received FD into that. If a FD is received but the ScopedFile pointer is
+  // null, the FD will be automatically closed.
+  size_t Receive(void* msg, size_t len, ScopedFile*, size_t max_files = 1);
+
+  inline size_t Receive(void* msg, size_t len) {
+    return Receive(msg, len, nullptr, 0);
+  }
+
+  // Only for tests. This is slower than Receive() as it requires a heap
+  // allocation and a copy for the std::string. Guarantees that the returned
+  // string is null terminated even if the underlying message sent by the peer
+  // is not.
+  std::string ReceiveString(size_t max_length = 1024);
+
+  bool is_connected() const { return state_ == State::kConnected; }
+  bool is_listening() const { return state_ == State::kListening; }
+  SocketHandle fd() const { return sock_raw_.fd(); }
+  SockFamily family() const { return sock_raw_.family(); }
+
+  // User ID of the peer, as returned by the kernel. If the client disconnects
+  // and the socket goes into the kDisconnected state, it retains the uid of
+  // the last peer.
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  uid_t peer_uid_posix(bool skip_check_for_testing = false) const {
+    PERFETTO_DCHECK((!is_listening() && peer_uid_ != kInvalidUid) ||
+                    skip_check_for_testing);
+
+    return peer_uid_;
+  }
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // Process ID of the peer, as returned by the kernel. If the client
+  // disconnects and the socket goes into the kDisconnected state, it
+  // retains the pid of the last peer.
+  //
+  // This is only available on Linux / Android.
+  pid_t peer_pid_linux(bool skip_check_for_testing = false) const {
+    PERFETTO_DCHECK((!is_listening() && peer_pid_ != kInvalidPid) ||
+                    skip_check_for_testing);
+    return peer_pid_;
+  }
+#endif
+
+  // This makes the UnixSocket unusable.
+  UnixSocketRaw ReleaseSocket();
+
+ private:
+  UnixSocket(EventListener*,
+             TaskRunner*,
+             SockFamily,
+             SockType,
+             SockPeerCredMode);
+  UnixSocket(EventListener*,
+             TaskRunner*,
+             ScopedSocketHandle,
+             State,
+             SockFamily,
+             SockType,
+             SockPeerCredMode);
+
+  // Called once by the corresponding public static factory methods.
+  void DoConnect(const std::string& socket_name);
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  void ReadPeerCredentialsPosix();
+#endif
+
+  void OnEvent();
+  void NotifyConnectionState(bool success);
+
+  UnixSocketRaw sock_raw_;
+  State state_ = State::kDisconnected;
+  SockPeerCredMode peer_cred_mode_ = SockPeerCredMode::kDefault;
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  uid_t peer_uid_ = kInvalidUid;
+#endif
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  pid_t peer_pid_ = kInvalidPid;
+#endif
+  EventListener* const event_listener_;
+  TaskRunner* const task_runner_;
+  WeakPtrFactory<UnixSocket> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
+// gen_amalgamated begin header: src/base/vm_sockets.h
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef SRC_BASE_VM_SOCKETS_H_
+#define SRC_BASE_VM_SOCKETS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+#include <sys/socket.h>
+
+#ifdef AF_VSOCK
+// Use system vm_socket.h if avaialbe.
+#include <linux/vm_sockets.h>
+#else  // defined(AF_SOCK)
+// Fallback and use the stripped copy from the UAPI vm_sockets.h.
+
+#include <stdint.h>  // For uint8_t.
+
+#define AF_VSOCK 40
+
+struct sockaddr_vm {
+  sa_family_t svm_family;
+  unsigned short svm_reserved1;
+  unsigned int svm_port;
+  unsigned int svm_cid;
+  uint8_t svm_flags;
+  unsigned char svm_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) -
+                         sizeof(unsigned short) - sizeof(unsigned int) -
+                         sizeof(unsigned int) - sizeof(uint8_t)];
+};
+
+#endif  // defined(AF_SOCK)
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||
+        // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+
+#endif  // SRC_BASE_VM_SOCKETS_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// The include order matters on these three Windows header groups.
+#include <Windows.h>
+
+#include <WS2tcpip.h>
+#include <WinSock2.h>
+
+#include <afunix.h>
+#else
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <sys/ucred.h>
+#endif
+
+#include <algorithm>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+// Use a local stripped copy of vm_sockets.h from UAPI.
+// gen_amalgamated expanded: #include "src/base/vm_sockets.h"
+#endif
+
+namespace perfetto {
+namespace base {
+
+// The CMSG_* macros use NULL instead of nullptr.
+// Note: MSVC doesn't have #pragma GCC diagnostic, hence the if __GNUC__.
+#if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
+#endif
+
+namespace {
+
+// Android takes an int instead of socklen_t for the control buffer size.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+using CBufLenType = size_t;
+#else
+using CBufLenType = socklen_t;
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+constexpr char kVsockNamePrefix[] = "vsock://";
+#endif
+
+// A wrapper around variable-size sockaddr structs.
+// This is solving the following problem: when calling connect() or bind(), the
+// caller needs to take care to allocate the right struct (sockaddr_un for
+// AF_UNIX, sockaddr_in for AF_INET).   Those structs have different sizes and,
+// more importantly, are bigger than the base struct sockaddr.
+struct SockaddrAny {
+  SockaddrAny() : size() {}
+  SockaddrAny(const void* addr, socklen_t sz)
+      : data(new char[static_cast<size_t>(sz)]), size(sz) {
+    memcpy(data.get(), addr, static_cast<size_t>(size));
+  }
+
+  const struct sockaddr* addr() const {
+    return reinterpret_cast<const struct sockaddr*>(data.get());
+  }
+
+  std::unique_ptr<char[]> data;
+  socklen_t size;
+};
+
+inline int MkSockFamily(SockFamily family) {
+  switch (family) {
+    case SockFamily::kUnix:
+      return AF_UNIX;
+    case SockFamily::kInet:
+      return AF_INET;
+    case SockFamily::kInet6:
+      return AF_INET6;
+    case SockFamily::kVsock:
+#ifdef AF_VSOCK
+      return AF_VSOCK;
+#else
+      return AF_UNSPEC;  // Return AF_UNSPEC on unsupported platforms.
+#endif
+    case SockFamily::kUnspec:
+      return AF_UNSPEC;
+  }
+  PERFETTO_CHECK(false);  // For GCC.
+}
+
+inline int MkSockType(SockType type) {
+#if defined(SOCK_CLOEXEC)
+  constexpr int kSockCloExec = SOCK_CLOEXEC;
+#else
+  constexpr int kSockCloExec = 0;
+#endif
+  switch (type) {
+    case SockType::kStream:
+      return SOCK_STREAM | kSockCloExec;
+    case SockType::kDgram:
+      return SOCK_DGRAM | kSockCloExec;
+    case SockType::kSeqPacket:
+      return SOCK_SEQPACKET | kSockCloExec;
+  }
+  PERFETTO_CHECK(false);  // For GCC.
+}
+
+SockaddrAny MakeSockAddr(SockFamily family, const std::string& socket_name) {
+  switch (family) {
+    case SockFamily::kUnix: {
+      struct sockaddr_un saddr {};
+      const size_t name_len = socket_name.size();
+      if (name_len + 1 /* for trailing \0 */ >= sizeof(saddr.sun_path)) {
+        errno = ENAMETOOLONG;
+        return SockaddrAny();
+      }
+      memcpy(saddr.sun_path, socket_name.data(), name_len);
+      if (saddr.sun_path[0] == '@') {
+        saddr.sun_path[0] = '\0';
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+        // The MSDN blog claims that abstract (non-filesystem based) AF_UNIX
+        // socket are supported, but that doesn't seem true.
+        PERFETTO_ELOG(
+            "Abstract AF_UNIX sockets are not supported on Windows, see "
+            "https://github.com/microsoft/WSL/issues/4240");
+        return SockaddrAny();
+#endif
+      }
+      saddr.sun_family = AF_UNIX;
+      auto size = static_cast<socklen_t>(
+          __builtin_offsetof(sockaddr_un, sun_path) + name_len + 1);
+
+      // Abstract sockets do NOT require a trailing null terminator (which is
+      // instad mandatory for filesystem sockets). Any byte up to `size`,
+      // including '\0' will become part of the socket name.
+      if (saddr.sun_path[0] == '\0')
+        --size;
+      PERFETTO_CHECK(static_cast<size_t>(size) <= sizeof(saddr));
+      return SockaddrAny(&saddr, size);
+    }
+    case SockFamily::kInet: {
+      auto parts = SplitString(socket_name, ":");
+      PERFETTO_CHECK(parts.size() == 2);
+      struct addrinfo* addr_info = nullptr;
+      struct addrinfo hints {};
+      hints.ai_family = AF_INET;
+      PERFETTO_CHECK(getaddrinfo(parts[0].c_str(), parts[1].c_str(), &hints,
+                                 &addr_info) == 0);
+      PERFETTO_CHECK(addr_info->ai_family == AF_INET);
+      SockaddrAny res(addr_info->ai_addr,
+                      static_cast<socklen_t>(addr_info->ai_addrlen));
+      freeaddrinfo(addr_info);
+      return res;
+    }
+    case SockFamily::kInet6: {
+      auto parts = SplitString(socket_name, "]");
+      PERFETTO_CHECK(parts.size() == 2);
+      auto address = SplitString(parts[0], "[");
+      PERFETTO_CHECK(address.size() == 1);
+      auto port = SplitString(parts[1], ":");
+      PERFETTO_CHECK(port.size() == 1);
+      struct addrinfo* addr_info = nullptr;
+      struct addrinfo hints {};
+      hints.ai_family = AF_INET6;
+      PERFETTO_CHECK(getaddrinfo(address[0].c_str(), port[0].c_str(), &hints,
+                                 &addr_info) == 0);
+      PERFETTO_CHECK(addr_info->ai_family == AF_INET6);
+      SockaddrAny res(addr_info->ai_addr,
+                      static_cast<socklen_t>(addr_info->ai_addrlen));
+      freeaddrinfo(addr_info);
+      return res;
+    }
+    case SockFamily::kVsock: {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+      PERFETTO_CHECK(StartsWith(socket_name, kVsockNamePrefix));
+      auto address_port = StripPrefix(socket_name, kVsockNamePrefix);
+      auto parts = SplitString(address_port, ":");
+      PERFETTO_CHECK(parts.size() == 2);
+      sockaddr_vm addr;
+      memset(&addr, 0, sizeof(addr));
+      addr.svm_family = AF_VSOCK;
+      addr.svm_cid = *base::StringToUInt32(parts[0]);
+      addr.svm_port = *base::StringToUInt32(parts[1]);
+      SockaddrAny res(&addr, sizeof(addr));
+      return res;
+#else
+      errno = ENOTSOCK;
+      return SockaddrAny();
+#endif
+    }
+    case SockFamily::kUnspec:
+      errno = ENOTSOCK;
+      return SockaddrAny();
+  }
+  PERFETTO_CHECK(false);  // For GCC.
+}
+
+ScopedSocketHandle CreateSocketHandle(SockFamily family, SockType type) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  static bool init_winsock_once = [] {
+    WSADATA ignored{};
+    return WSAStartup(MAKEWORD(2, 2), &ignored) == 0;
+  }();
+  PERFETTO_CHECK(init_winsock_once);
+#endif
+  return ScopedSocketHandle(socket(MkSockFamily(family), MkSockType(type), 0));
+}
+
+}  // namespace
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+int CloseSocket(SocketHandle s) {
+  return ::closesocket(s);
+}
+#endif
+
+SockFamily GetSockFamily(const char* addr) {
+  if (strlen(addr) == 0)
+    return SockFamily::kUnspec;
+
+  if (addr[0] == '@')
+    return SockFamily::kUnix;  // Abstract AF_UNIX sockets.
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  // Vsock address starts with vsock://.
+  if (strncmp(addr, kVsockNamePrefix, strlen(kVsockNamePrefix)) == 0)
+    return SockFamily::kVsock;
+#endif
+
+  // If `addr` ends in :NNNN it's either a kInet or kInet6 socket.
+  const char* col = strrchr(addr, ':');
+  if (col && CStringToInt32(col + 1).has_value()) {
+    return addr[0] == '[' ? SockFamily::kInet6 : SockFamily::kInet;
+  }
+
+  return SockFamily::kUnix;  // For anything else assume it's a linked AF_UNIX.
+}
+
+// +-----------------------+
+// | UnixSocketRaw methods |
+// +-----------------------+
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// static
+void UnixSocketRaw::ShiftMsgHdrPosix(size_t n, struct msghdr* msg) {
+  using LenType = decltype(msg->msg_iovlen);  // Mac and Linux don't agree.
+  for (LenType i = 0; i < msg->msg_iovlen; ++i) {
+    struct iovec* vec = &msg->msg_iov[i];
+    if (n < vec->iov_len) {
+      // We sent a part of this iovec.
+      vec->iov_base = reinterpret_cast<char*>(vec->iov_base) + n;
+      vec->iov_len -= n;
+      msg->msg_iov = vec;
+      msg->msg_iovlen -= i;
+      return;
+    }
+    // We sent the whole iovec.
+    n -= vec->iov_len;
+  }
+  // We sent all the iovecs.
+  PERFETTO_CHECK(n == 0);
+  msg->msg_iovlen = 0;
+  msg->msg_iov = nullptr;
+}
+
+// static
+std::pair<UnixSocketRaw, UnixSocketRaw> UnixSocketRaw::CreatePairPosix(
+    SockFamily family,
+    SockType type) {
+  int fds[2];
+  if (socketpair(MkSockFamily(family), MkSockType(type), 0, fds) != 0) {
+    return std::make_pair(UnixSocketRaw(), UnixSocketRaw());
+  }
+  return std::make_pair(UnixSocketRaw(ScopedFile(fds[0]), family, type),
+                        UnixSocketRaw(ScopedFile(fds[1]), family, type));
+}
+#endif
+
+// static
+UnixSocketRaw UnixSocketRaw::CreateMayFail(SockFamily family, SockType type) {
+  auto fd = CreateSocketHandle(family, type);
+  if (!fd)
+    return UnixSocketRaw();
+  return UnixSocketRaw(std::move(fd), family, type);
+}
+
+UnixSocketRaw::UnixSocketRaw() = default;
+
+UnixSocketRaw::UnixSocketRaw(SockFamily family, SockType type)
+    : UnixSocketRaw(CreateSocketHandle(family, type), family, type) {}
+
+UnixSocketRaw::UnixSocketRaw(ScopedSocketHandle fd,
+                             SockFamily family,
+                             SockType type)
+    : fd_(std::move(fd)), family_(family), type_(type) {
+  PERFETTO_CHECK(fd_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  const int no_sigpipe = 1;
+  setsockopt(*fd_, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe));
+#endif
+
+  if (family == SockFamily::kInet || family == SockFamily::kInet6 ||
+      family == SockFamily::kVsock) {
+    int flag = 1;
+    // The reinterpret_cast<const char*> is needed for Windows, where the 4th
+    // arg is a const char* (on other POSIX system is a const void*).
+    PERFETTO_CHECK(!setsockopt(*fd_, SOL_SOCKET, SO_REUSEADDR,
+                               reinterpret_cast<const char*>(&flag),
+                               sizeof(flag)));
+  }
+
+  if (family == SockFamily::kInet || family == SockFamily::kInet6) {
+    int flag = 1;
+    // Disable Nagle's algorithm, optimize for low-latency.
+    // See https://github.com/google/perfetto/issues/70.
+    setsockopt(*fd_, IPPROTO_TCP, TCP_NODELAY,
+               reinterpret_cast<const char*>(&flag), sizeof(flag));
+  }
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // We use one event handle for all socket events, to stay consistent to what
+  // we do on UNIX with the base::TaskRunner's poll().
+  event_handle_.reset(WSACreateEvent());
+  PERFETTO_CHECK(event_handle_);
+#else
+  // There is no reason why a socket should outlive the process in case of
+  // exec() by default, this is just working around a broken unix design.
+  SetRetainOnExec(false);
+#endif
+}
+
+void UnixSocketRaw::SetBlocking(bool is_blocking) {
+  PERFETTO_DCHECK(fd_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  unsigned long flag = is_blocking ? 0 : 1;  // FIONBIO has reverse logic.
+  if (is_blocking) {
+    // When switching between non-blocking -> blocking mode, we need to reset
+    // the event handle registration, otherwise the call will fail.
+    PERFETTO_CHECK(WSAEventSelect(*fd_, *event_handle_, 0) == 0);
+  }
+  PERFETTO_CHECK(ioctlsocket(*fd_, static_cast<long>(FIONBIO), &flag) == 0);
+  if (!is_blocking) {
+    PERFETTO_CHECK(
+        WSAEventSelect(*fd_, *event_handle_,
+                       FD_ACCEPT | FD_CONNECT | FD_READ | FD_CLOSE) == 0);
+  }
+#else
+  int flags = fcntl(*fd_, F_GETFL, 0);
+  if (!is_blocking) {
+    flags |= O_NONBLOCK;
+  } else {
+    flags &= ~static_cast<int>(O_NONBLOCK);
+  }
+  int fcntl_res = fcntl(*fd_, F_SETFL, flags);
+  PERFETTO_CHECK(fcntl_res == 0);
+#endif
+}
+
+void UnixSocketRaw::SetRetainOnExec(bool retain) {
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
+    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+  PERFETTO_DCHECK(fd_);
+  int flags = fcntl(*fd_, F_GETFD, 0);
+  if (retain) {
+    flags &= ~static_cast<int>(FD_CLOEXEC);
+  } else {
+    flags |= FD_CLOEXEC;
+  }
+  int fcntl_res = fcntl(*fd_, F_SETFD, flags);
+  PERFETTO_CHECK(fcntl_res == 0);
+#else
+  ignore_result(retain);
+#endif
+}
+
+void UnixSocketRaw::DcheckIsBlocking(bool expected) const {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  ignore_result(expected);
+#else
+  PERFETTO_DCHECK(fd_);
+  bool is_blocking = (fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0;
+  PERFETTO_DCHECK(is_blocking == expected);
+#endif
+}
+
+bool UnixSocketRaw::Bind(const std::string& socket_name) {
+  PERFETTO_DCHECK(fd_);
+  SockaddrAny addr = MakeSockAddr(family_, socket_name);
+  if (addr.size == 0)
+    return false;
+
+  if (bind(*fd_, addr.addr(), addr.size)) {
+    PERFETTO_DPLOG("bind(%s)", socket_name.c_str());
+    return false;
+  }
+
+  return true;
+}
+
+bool UnixSocketRaw::Listen() {
+  PERFETTO_DCHECK(fd_);
+  PERFETTO_DCHECK(type_ == SockType::kStream || type_ == SockType::kSeqPacket);
+  return listen(*fd_, SOMAXCONN) == 0;
+}
+
+bool UnixSocketRaw::Connect(const std::string& socket_name) {
+  PERFETTO_DCHECK(fd_);
+  SockaddrAny addr = MakeSockAddr(family_, socket_name);
+  if (addr.size == 0)
+    return false;
+
+  int res = PERFETTO_EINTR(connect(*fd_, addr.addr(), addr.size));
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  bool continue_async = WSAGetLastError() == WSAEWOULDBLOCK;
+#else
+  bool continue_async = errno == EINPROGRESS;
+#endif
+  if (res && !continue_async)
+    return false;
+
+  return true;
+}
+
+void UnixSocketRaw::Shutdown() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  // Somebody felt very strongly about the naming of this constant.
+  shutdown(*fd_, SD_BOTH);
+#else
+  shutdown(*fd_, SHUT_RDWR);
+#endif
+  fd_.reset();
+}
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+ssize_t UnixSocketRaw::Send(const void* msg,
+                            size_t len,
+                            const int* /*send_fds*/,
+                            size_t num_fds) {
+  PERFETTO_DCHECK(num_fds == 0);
+  return sendto(*fd_, static_cast<const char*>(msg), static_cast<int>(len), 0,
+                nullptr, 0);
+}
+
+ssize_t UnixSocketRaw::Receive(void* msg,
+                               size_t len,
+                               ScopedFile* /*fd_vec*/,
+                               size_t /*max_files*/) {
+  return recv(*fd_, static_cast<char*>(msg), static_cast<int>(len), 0);
+}
+
+#else
+// For the interested reader, Linux kernel dive to verify this is not only a
+// theoretical possibility: sock_stream_sendmsg, if sock_alloc_send_pskb returns
+// NULL [1] (which it does when it gets interrupted [2]), returns early with the
+// amount of bytes already sent.
+//
+// [1]:
+// https://elixir.bootlin.com/linux/v4.18.10/source/net/unix/af_unix.c#L1872
+// [2]: https://elixir.bootlin.com/linux/v4.18.10/source/net/core/sock.c#L2101
+ssize_t UnixSocketRaw::SendMsgAllPosix(struct msghdr* msg) {
+  // This does not make sense on non-blocking sockets.
+  PERFETTO_DCHECK(fd_);
+
+  const bool is_blocking_with_timeout =
+      tx_timeout_ms_ > 0 && ((fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0);
+  const int64_t start_ms = GetWallTimeMs().count();
+
+  // Waits until some space is available in the tx buffer.
+  // Returns true if some buffer space is available, false if times out.
+  auto poll_or_timeout = [&] {
+    PERFETTO_DCHECK(is_blocking_with_timeout);
+    const int64_t deadline = start_ms + tx_timeout_ms_;
+    const int64_t now_ms = GetWallTimeMs().count();
+    if (now_ms >= deadline)
+      return false;  // Timed out
+    const int timeout_ms = static_cast<int>(deadline - now_ms);
+    pollfd pfd{*fd_, POLLOUT, 0};
+    return PERFETTO_EINTR(poll(&pfd, 1, timeout_ms)) > 0;
+  };
+
+// We implement blocking sends that require a timeout as non-blocking + poll.
+// This is because SO_SNDTIMEO doesn't work as expected (b/193234818). On linux
+// we can just pass MSG_DONTWAIT to force the send to be non-blocking. On Mac,
+// instead we need to flip the O_NONBLOCK flag back and forth.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  // MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
+  // created with SO_NOSIGPIPE (See InitializeSocket()).
+  int send_flags = 0;
+
+  if (is_blocking_with_timeout)
+    SetBlocking(false);
+
+  auto reset_nonblock_on_exit = OnScopeExit([&] {
+    if (is_blocking_with_timeout)
+      SetBlocking(true);
+  });
+#else
+  int send_flags = MSG_NOSIGNAL | (is_blocking_with_timeout ? MSG_DONTWAIT : 0);
+#endif
+
+  ssize_t total_sent = 0;
+  while (msg->msg_iov) {
+    ssize_t send_res = PERFETTO_EINTR(sendmsg(*fd_, msg, send_flags));
+    if (send_res == -1 && IsAgain(errno)) {
+      if (is_blocking_with_timeout && poll_or_timeout()) {
+        continue;  // Tx buffer unblocked, repeat the loop.
+      }
+      return total_sent;
+    } else if (send_res <= 0) {
+      return send_res;  // An error occurred.
+    } else {
+      total_sent += send_res;
+      ShiftMsgHdrPosix(static_cast<size_t>(send_res), msg);
+      // Only send the ancillary data with the first sendmsg call.
+      msg->msg_control = nullptr;
+      msg->msg_controllen = 0;
+    }
+  }
+  return total_sent;
+}
+
+ssize_t UnixSocketRaw::Send(const void* msg,
+                            size_t len,
+                            const int* send_fds,
+                            size_t num_fds) {
+  PERFETTO_DCHECK(fd_);
+  msghdr msg_hdr = {};
+  iovec iov = {const_cast<void*>(msg), len};
+  msg_hdr.msg_iov = &iov;
+  msg_hdr.msg_iovlen = 1;
+  alignas(cmsghdr) char control_buf[256];
+
+  if (num_fds > 0) {
+    const auto raw_ctl_data_sz = num_fds * sizeof(int);
+    const CBufLenType control_buf_len =
+        static_cast<CBufLenType>(CMSG_SPACE(raw_ctl_data_sz));
+    PERFETTO_CHECK(control_buf_len <= sizeof(control_buf));
+    memset(control_buf, 0, sizeof(control_buf));
+    msg_hdr.msg_control = control_buf;
+    msg_hdr.msg_controllen = control_buf_len;  // used by CMSG_FIRSTHDR
+    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr);
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_RIGHTS;
+    cmsg->cmsg_len = static_cast<CBufLenType>(CMSG_LEN(raw_ctl_data_sz));
+    memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
+    // note: if we were to send multiple cmsghdr structures, then
+    // msg_hdr.msg_controllen would need to be adjusted, see "man 3 cmsg".
+  }
+
+  return SendMsgAllPosix(&msg_hdr);
+}
+
+ssize_t UnixSocketRaw::Receive(void* msg,
+                               size_t len,
+                               ScopedFile* fd_vec,
+                               size_t max_files) {
+  PERFETTO_DCHECK(fd_);
+  msghdr msg_hdr = {};
+  iovec iov = {msg, len};
+  msg_hdr.msg_iov = &iov;
+  msg_hdr.msg_iovlen = 1;
+  alignas(cmsghdr) char control_buf[256];
+
+  if (max_files > 0) {
+    msg_hdr.msg_control = control_buf;
+    msg_hdr.msg_controllen =
+        static_cast<CBufLenType>(CMSG_SPACE(max_files * sizeof(int)));
+    PERFETTO_CHECK(msg_hdr.msg_controllen <= sizeof(control_buf));
+  }
+  const ssize_t sz = PERFETTO_EINTR(recvmsg(*fd_, &msg_hdr, 0));
+  if (sz <= 0) {
+    return sz;
+  }
+  PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
+
+  int* fds = nullptr;
+  uint32_t fds_len = 0;
+
+  if (max_files > 0) {
+    for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr); cmsg;
+         cmsg = CMSG_NXTHDR(&msg_hdr, cmsg)) {
+      const size_t payload_len = cmsg->cmsg_len - CMSG_LEN(0);
+      if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
+        PERFETTO_DCHECK(payload_len % sizeof(int) == 0u);
+        PERFETTO_CHECK(fds == nullptr);
+        fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
+        fds_len = static_cast<uint32_t>(payload_len / sizeof(int));
+      }
+    }
+  }
+
+  if (msg_hdr.msg_flags & MSG_TRUNC || msg_hdr.msg_flags & MSG_CTRUNC) {
+    for (size_t i = 0; fds && i < fds_len; ++i)
+      close(fds[i]);
+    PERFETTO_ELOG(
+        "Socket message truncated. This might be due to a SELinux denial on "
+        "fd:use.");
+    errno = EMSGSIZE;
+    return -1;
+  }
+
+  for (size_t i = 0; fds && i < fds_len; ++i) {
+    if (i < max_files)
+      fd_vec[i].reset(fds[i]);
+    else
+      close(fds[i]);
+  }
+
+  return sz;
+}
+#endif  // OS_WIN
+
+bool UnixSocketRaw::SetTxTimeout(uint32_t timeout_ms) {
+  PERFETTO_DCHECK(fd_);
+  // On Unix-based systems, SO_SNDTIMEO isn't used for Send() because it's
+  // unreliable (b/193234818). Instead we use non-blocking sendmsg() + poll().
+  // See SendMsgAllPosix(). We still make the setsockopt call because
+  // SO_SNDTIMEO also affects connect().
+  tx_timeout_ms_ = timeout_ms;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  DWORD timeout = timeout_ms;
+  ignore_result(tx_timeout_ms_);
+#else
+  struct timeval timeout {};
+  uint32_t timeout_sec = timeout_ms / 1000;
+  timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
+  timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
+      (timeout_ms - (timeout_sec * 1000)) * 1000);
+#endif
+  return setsockopt(*fd_, SOL_SOCKET, SO_SNDTIMEO,
+                    reinterpret_cast<const char*>(&timeout),
+                    sizeof(timeout)) == 0;
+}
+
+bool UnixSocketRaw::SetRxTimeout(uint32_t timeout_ms) {
+  PERFETTO_DCHECK(fd_);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  DWORD timeout = timeout_ms;
+#else
+  struct timeval timeout {};
+  uint32_t timeout_sec = timeout_ms / 1000;
+  timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
+  timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
+      (timeout_ms - (timeout_sec * 1000)) * 1000);
+#endif
+  return setsockopt(*fd_, SOL_SOCKET, SO_RCVTIMEO,
+                    reinterpret_cast<const char*>(&timeout),
+                    sizeof(timeout)) == 0;
+}
+
+std::string UnixSocketRaw::GetSockAddr() const {
+  struct sockaddr_storage stg {};
+  socklen_t slen = sizeof(stg);
+  PERFETTO_CHECK(
+      getsockname(*fd_, reinterpret_cast<struct sockaddr*>(&stg), &slen) == 0);
+  char addr[255]{};
+
+  if (stg.ss_family == AF_UNIX) {
+    auto* saddr = reinterpret_cast<struct sockaddr_un*>(&stg);
+    static_assert(sizeof(addr) >= sizeof(saddr->sun_path), "addr too small");
+    memcpy(addr, saddr->sun_path, sizeof(saddr->sun_path));
+    addr[0] = addr[0] == '\0' ? '@' : addr[0];
+    addr[sizeof(saddr->sun_path) - 1] = '\0';
+    return std::string(addr);
+  }
+
+  if (stg.ss_family == AF_INET) {
+    auto* saddr = reinterpret_cast<struct sockaddr_in*>(&stg);
+    PERFETTO_CHECK(inet_ntop(AF_INET, &saddr->sin_addr, addr, sizeof(addr)));
+    uint16_t port = ntohs(saddr->sin_port);
+    base::StackString<255> addr_and_port("%s:%" PRIu16, addr, port);
+    return addr_and_port.ToStdString();
+  }
+
+  if (stg.ss_family == AF_INET6) {
+    auto* saddr = reinterpret_cast<struct sockaddr_in6*>(&stg);
+    PERFETTO_CHECK(inet_ntop(AF_INET6, &saddr->sin6_addr, addr, sizeof(addr)));
+    auto port = ntohs(saddr->sin6_port);
+    base::StackString<255> addr_and_port("[%s]:%" PRIu16, addr, port);
+    return addr_and_port.ToStdString();
+  }
+
+#if defined(AF_VSOCK) && (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+                          PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
+  if (stg.ss_family == AF_VSOCK) {
+    auto* saddr = reinterpret_cast<struct sockaddr_vm*>(&stg);
+    base::StackString<255> addr_and_port("%s%d:%d", kVsockNamePrefix,
+                                         saddr->svm_cid, saddr->svm_port);
+    return addr_and_port.ToStdString();
+  }
+#endif
+
+  PERFETTO_FATAL("GetSockAddr() unsupported on family %d", stg.ss_family);
+}
+
+#if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#pragma GCC diagnostic pop
+#endif
+
+// +--------------------+
+// | UnixSocket methods |
+// +--------------------+
+
+// TODO(primiano): Add ThreadChecker to methods of this class.
+
+// static
+std::unique_ptr<UnixSocket> UnixSocket::Listen(const std::string& socket_name,
+                                               EventListener* event_listener,
+                                               TaskRunner* task_runner,
+                                               SockFamily sock_family,
+                                               SockType sock_type) {
+  auto sock_raw = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
+  if (!sock_raw || !sock_raw.Bind(socket_name))
+    return nullptr;
+
+  // Forward the call to the Listen() overload below.
+  return Listen(sock_raw.ReleaseFd(), event_listener, task_runner, sock_family,
+                sock_type);
+}
+
+// static
+std::unique_ptr<UnixSocket> UnixSocket::Listen(ScopedSocketHandle fd,
+                                               EventListener* event_listener,
+                                               TaskRunner* task_runner,
+                                               SockFamily sock_family,
+                                               SockType sock_type) {
+  return std::unique_ptr<UnixSocket>(new UnixSocket(
+      event_listener, task_runner, std::move(fd), State::kListening,
+      sock_family, sock_type, SockPeerCredMode::kDefault));
+}
+
+// static
+std::unique_ptr<UnixSocket> UnixSocket::Connect(
+    const std::string& socket_name,
+    EventListener* event_listener,
+    TaskRunner* task_runner,
+    SockFamily sock_family,
+    SockType sock_type,
+    SockPeerCredMode peer_cred_mode) {
+  std::unique_ptr<UnixSocket> sock(new UnixSocket(
+      event_listener, task_runner, sock_family, sock_type, peer_cred_mode));
+  sock->DoConnect(socket_name);
+  return sock;
+}
+
+// static
+std::unique_ptr<UnixSocket> UnixSocket::AdoptConnected(
+    ScopedSocketHandle fd,
+    EventListener* event_listener,
+    TaskRunner* task_runner,
+    SockFamily sock_family,
+    SockType sock_type,
+    SockPeerCredMode peer_cred_mode) {
+  return std::unique_ptr<UnixSocket>(new UnixSocket(
+      event_listener, task_runner, std::move(fd), State::kConnected,
+      sock_family, sock_type, peer_cred_mode));
+}
+
+UnixSocket::UnixSocket(EventListener* event_listener,
+                       TaskRunner* task_runner,
+                       SockFamily sock_family,
+                       SockType sock_type,
+                       SockPeerCredMode peer_cred_mode)
+    : UnixSocket(event_listener,
+                 task_runner,
+                 ScopedSocketHandle(),
+                 State::kDisconnected,
+                 sock_family,
+                 sock_type,
+                 peer_cred_mode) {}
+
+UnixSocket::UnixSocket(EventListener* event_listener,
+                       TaskRunner* task_runner,
+                       ScopedSocketHandle adopt_fd,
+                       State adopt_state,
+                       SockFamily sock_family,
+                       SockType sock_type,
+                       SockPeerCredMode peer_cred_mode)
+    : peer_cred_mode_(peer_cred_mode),
+      event_listener_(event_listener),
+      task_runner_(task_runner),
+      weak_ptr_factory_(this) {
+  state_ = State::kDisconnected;
+  if (adopt_state == State::kDisconnected) {
+    PERFETTO_DCHECK(!adopt_fd);
+    sock_raw_ = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
+    if (!sock_raw_)
+      return;
+  } else if (adopt_state == State::kConnected) {
+    PERFETTO_DCHECK(adopt_fd);
+    sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
+    state_ = State::kConnected;
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
+      ReadPeerCredentialsPosix();
+#endif
+  } else if (adopt_state == State::kListening) {
+    // We get here from Listen().
+
+    // |adopt_fd| might genuinely be invalid if the bind() failed.
+    if (!adopt_fd)
+      return;
+
+    sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
+    if (!sock_raw_.Listen()) {
+      PERFETTO_DPLOG("listen() failed");
+      return;
+    }
+    state_ = State::kListening;
+  } else {
+    PERFETTO_FATAL("Unexpected adopt_state");  // Unfeasible.
+  }
+
+  PERFETTO_CHECK(sock_raw_);
+
+  sock_raw_.SetBlocking(false);
+
+  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+
+  task_runner_->AddFileDescriptorWatch(sock_raw_.watch_handle(), [weak_ptr] {
+    if (weak_ptr)
+      weak_ptr->OnEvent();
+  });
+}
+
+UnixSocket::~UnixSocket() {
+  // The implicit dtor of |weak_ptr_factory_| will no-op pending callbacks.
+  Shutdown(true);
+}
+
+UnixSocketRaw UnixSocket::ReleaseSocket() {
+  // This will invalidate any pending calls to OnEvent.
+  state_ = State::kDisconnected;
+  if (sock_raw_)
+    task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
+
+  return std::move(sock_raw_);
+}
+
+// Called only by the Connect() static constructor.
+void UnixSocket::DoConnect(const std::string& socket_name) {
+  PERFETTO_DCHECK(state_ == State::kDisconnected);
+
+  // This is the only thing that can gracefully fail in the ctor.
+  if (!sock_raw_)
+    return NotifyConnectionState(false);
+
+  if (!sock_raw_.Connect(socket_name))
+    return NotifyConnectionState(false);
+
+  // At this point either connect() succeeded or started asynchronously
+  // (errno = EINPROGRESS).
+  state_ = State::kConnecting;
+
+  // Even if the socket is non-blocking, connecting to a UNIX socket can be
+  // acknowledged straight away rather than returning EINPROGRESS.
+  // The decision here is to deal with the two cases uniformly, at the cost of
+  // delaying the straight-away-connect() case by one task, to avoid depending
+  // on implementation details of UNIX socket on the various OSes.
+  // Posting the OnEvent() below emulates a wakeup of the FD watch. OnEvent(),
+  // which knows how to deal with spurious wakeups, will poll the SO_ERROR and
+  // evolve, if necessary, the state into either kConnected or kDisconnected.
+  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_ptr] {
+    if (weak_ptr)
+      weak_ptr->OnEvent();
+  });
+}
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+void UnixSocket::ReadPeerCredentialsPosix() {
+  // Peer credentials are supported only on AF_UNIX sockets.
+  if (sock_raw_.family() != SockFamily::kUnix)
+    return;
+  PERFETTO_CHECK(peer_cred_mode_ != SockPeerCredMode::kIgnore);
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  struct ucred user_cred;
+  socklen_t len = sizeof(user_cred);
+  int fd = sock_raw_.fd();
+  int res = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &user_cred, &len);
+  PERFETTO_CHECK(res == 0);
+  peer_uid_ = user_cred.uid;
+  peer_pid_ = user_cred.pid;
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  struct xucred user_cred;
+  socklen_t len = sizeof(user_cred);
+  int res = getsockopt(sock_raw_.fd(), 0, LOCAL_PEERCRED, &user_cred, &len);
+  PERFETTO_CHECK(res == 0 && user_cred.cr_version == XUCRED_VERSION);
+  peer_uid_ = static_cast<uid_t>(user_cred.cr_uid);
+  // There is no pid in the LOCAL_PEERCREDS for MacOS / FreeBSD.
+#endif
+}
+#endif  // !OS_WIN
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+void UnixSocket::OnEvent() {
+  WSANETWORKEVENTS evts{};
+  PERFETTO_CHECK(WSAEnumNetworkEvents(sock_raw_.fd(), sock_raw_.watch_handle(),
+                                      &evts) == 0);
+  if (state_ == State::kDisconnected)
+    return;  // Some spurious event, typically queued just before Shutdown().
+
+  if (state_ == State::kConnecting && (evts.lNetworkEvents & FD_CONNECT)) {
+    PERFETTO_DCHECK(sock_raw_);
+    int err = evts.iErrorCode[FD_CONNECT_BIT];
+    if (err) {
+      PERFETTO_DPLOG("Connection error: %d", err);
+      Shutdown(false);
+      event_listener_->OnConnect(this, false /* connected */);
+      return;
+    }
+
+    // kReadOnConnect is not supported on Windows.
+    PERFETTO_DCHECK(peer_cred_mode_ != SockPeerCredMode::kReadOnConnect);
+    state_ = State::kConnected;
+    event_listener_->OnConnect(this, true /* connected */);
+  }
+
+  // This is deliberately NOT an else-if. When a client socket connects and
+  // there is already data queued, the following will happen within the same
+  // OnEvent() call:
+  // 1. The block above will transition kConnecting -> kConnected.
+  // 2. This block will cause an OnDataAvailable() call.
+  // Unlike UNIX, where poll() keeps signalling the event until the client
+  // does a recv(), Windows is more picky and stops signalling the event until
+  // the next call to recv() is made. In other words, in Windows we cannot
+  // miss an OnDataAvailable() call or the event pump will stop.
+  if (state_ == State::kConnected) {
+    if (evts.lNetworkEvents & FD_READ) {
+      event_listener_->OnDataAvailable(this);
+      // TODO(primiano): I am very conflicted here. Because of the behavior
+      // described above, if the event listener doesn't do a Recv() call in
+      // the OnDataAvailable() callback, WinSock won't notify the event ever
+      // again. On one side, I don't see any reason why a client should decide
+      // to not do a Recv() in OnDataAvailable. On the other side, the
+      // behavior here diverges from UNIX, where OnDataAvailable() would be
+      // re-posted immediately. In both cases, not doing a Recv() in
+      // OnDataAvailable, leads to something bad (getting stuck on Windows,
+      // getting in a hot loop on Linux), so doesn't feel we should worry too
+      // much about this. If we wanted to keep the behavrior consistent, here
+      // we should do something like: `if (sock_raw_)
+      // sock_raw_.SetBlocking(false)` (Note that the socket might be closed
+      // by the time we come back here, hence the if part).
+      return;
+    }
+    // Could read EOF and disconnect here.
+    if (evts.lNetworkEvents & FD_CLOSE) {
+      Shutdown(true);
+      return;
+    }
+  }
+
+  // New incoming connection.
+  if (state_ == State::kListening && (evts.lNetworkEvents & FD_ACCEPT)) {
+    // There could be more than one incoming connection behind each FD watch
+    // notification. Drain'em all.
+    for (;;) {
+      // Note: right now we don't need the remote endpoint, hence we pass
+      // nullptr to |addr| and |addrlen|. If we ever need to do so, be
+      // extremely careful. Windows' WinSock API will happily write more than
+      // |addrlen| (hence corrupt the stack) if the |addr| argument passed is
+      // not big enough (e.g. passing a struct sockaddr_in to a AF_UNIX
+      // socket, where sizeof(sockaddr_un) is >> sizef(sockaddr_in)). It seems
+      // a Windows / CRT bug in the AF_UNIX implementation.
+      ScopedSocketHandle new_fd(accept(sock_raw_.fd(), nullptr, nullptr));
+      if (!new_fd)
+        return;
+      std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
+          event_listener_, task_runner_, std::move(new_fd), State::kConnected,
+          sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
+      event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
+    }
+  }
+}
+#else
+void UnixSocket::OnEvent() {
+  if (state_ == State::kDisconnected)
+    return;  // Some spurious event, typically queued just before Shutdown().
+
+  if (state_ == State::kConnected)
+    return event_listener_->OnDataAvailable(this);
+
+  if (state_ == State::kConnecting) {
+    PERFETTO_DCHECK(sock_raw_);
+    int sock_err = EINVAL;
+    socklen_t err_len = sizeof(sock_err);
+    int res =
+        getsockopt(sock_raw_.fd(), SOL_SOCKET, SO_ERROR, &sock_err, &err_len);
+
+    if (res == 0 && sock_err == EINPROGRESS)
+      return;  // Not connected yet, just a spurious FD watch wakeup.
+    if (res == 0 && sock_err == 0) {
+      if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
+        ReadPeerCredentialsPosix();
+      state_ = State::kConnected;
+      return event_listener_->OnConnect(this, true /* connected */);
+    }
+    PERFETTO_DLOG("Connection error: %s", strerror(sock_err));
+    Shutdown(false);
+    return event_listener_->OnConnect(this, false /* connected */);
+  }
+
+  // New incoming connection.
+  if (state_ == State::kListening) {
+    // There could be more than one incoming connection behind each FD watch
+    // notification. Drain'em all.
+    for (;;) {
+      ScopedFile new_fd(
+          PERFETTO_EINTR(accept(sock_raw_.fd(), nullptr, nullptr)));
+      if (!new_fd)
+        return;
+      std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
+          event_listener_, task_runner_, std::move(new_fd), State::kConnected,
+          sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
+      event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
+    }
+  }
+}
+#endif
+
+bool UnixSocket::Send(const void* msg,
+                      size_t len,
+                      const int* send_fds,
+                      size_t num_fds) {
+  if (state_ != State::kConnected) {
+    errno = ENOTCONN;
+    return false;
+  }
+
+  sock_raw_.SetBlocking(true);
+  const ssize_t sz = sock_raw_.Send(msg, len, send_fds, num_fds);
+  sock_raw_.SetBlocking(false);
+
+  if (sz == static_cast<ssize_t>(len)) {
+    return true;
+  }
+
+  // If we ever decide to support non-blocking sends again, here we should
+  // watch for both EAGAIN and EWOULDBLOCK (see base::IsAgain()).
+
+  // If sendmsg() succeeds but the returned size is >= 0 and < |len| it means
+  // that the endpoint disconnected in the middle of the read, and we managed
+  // to send only a portion of the buffer.
+  // If sz < 0, either the other endpoint disconnected (ECONNRESET) or some
+  // other error happened. In both cases we should just give up.
+  PERFETTO_DPLOG("sendmsg() failed");
+  Shutdown(true);
+  return false;
+}
+
+void UnixSocket::Shutdown(bool notify) {
+  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  if (notify) {
+    if (state_ == State::kConnected) {
+      task_runner_->PostTask([weak_ptr] {
+        if (weak_ptr)
+          weak_ptr->event_listener_->OnDisconnect(weak_ptr.get());
+      });
+    } else if (state_ == State::kConnecting) {
+      task_runner_->PostTask([weak_ptr] {
+        if (weak_ptr)
+          weak_ptr->event_listener_->OnConnect(weak_ptr.get(), false);
+      });
+    }
+  }
+
+  if (sock_raw_) {
+    task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
+    sock_raw_.Shutdown();
+  }
+  state_ = State::kDisconnected;
+}
+
+size_t UnixSocket::Receive(void* msg,
+                           size_t len,
+                           ScopedFile* fd_vec,
+                           size_t max_files) {
+  if (state_ != State::kConnected)
+    return 0;
+
+  const ssize_t sz = sock_raw_.Receive(msg, len, fd_vec, max_files);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  bool async_would_block = WSAGetLastError() == WSAEWOULDBLOCK;
+#else
+  bool async_would_block = IsAgain(errno);
+#endif
+  if (sz < 0 && async_would_block)
+    return 0;
+
+  if (sz <= 0) {
+    Shutdown(true);
+    return 0;
+  }
+  PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
+  return static_cast<size_t>(sz);
+}
+
+std::string UnixSocket::ReceiveString(size_t max_length) {
+  std::unique_ptr<char[]> buf(new char[max_length + 1]);
+  size_t rsize = Receive(buf.get(), max_length);
+  PERFETTO_CHECK(rsize <= max_length);
+  buf[rsize] = '\0';
+  return std::string(buf.get());
+}
+
+void UnixSocket::NotifyConnectionState(bool success) {
+  if (!success)
+    Shutdown(false);
+
+  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_ptr, success] {
+    if (weak_ptr)
+      weak_ptr->event_listener_->OnConnect(weak_ptr.get(), success);
+  });
+}
+
+UnixSocket::EventListener::~EventListener() {}
+void UnixSocket::EventListener::OnNewIncomingConnection(
+    UnixSocket*,
+    std::unique_ptr<UnixSocket>) {}
+void UnixSocket::EventListener::OnConnect(UnixSocket*, bool) {}
+void UnixSocket::EventListener::OnDisconnect(UnixSocket*) {}
+void UnixSocket::EventListener::OnDataAvailable(UnixSocket*) {}
+
+}  // namespace base
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/buffered_frame_deserializer.cc
+// gen_amalgamated begin header: src/ipc/buffered_frame_deserializer.h
+// gen_amalgamated begin header: include/perfetto/ext/ipc/basic_types.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
+#define INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+
+namespace perfetto {
+namespace ipc {
+
+using ProtoMessage = ::protozero::CppMessageObj;
+using ServiceID = uint32_t;
+using MethodID = uint32_t;
+using ClientID = uint64_t;
+using RequestID = uint64_t;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// AF_UNIX on Windows is supported only on Windows 10 from build 17063.
+// Also it doesn't bring major advantages compared to a TCP socket.
+// See go/perfetto-win .
+constexpr bool kUseTCPSocket = true;
+#else
+// Android, Linux, Mac, Fuchsia use local sockets.
+constexpr bool kUseTCPSocket = false;
+#endif
+
+// This determines the maximum size allowed for an IPC message. Trying to send
+// or receive a larger message will hit DCHECK(s) and auto-disconnect.
+constexpr size_t kIPCBufferSize = 128 * 1024;
+
+constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
+#define SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
+
+#include <stddef.h>
+
+#include <list>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+
+namespace protos {
+namespace gen {
+class IPCFrame;
+}  // namespace gen
+}  // namespace protos
+
+namespace ipc {
+
+using Frame = ::perfetto::protos::gen::IPCFrame;
+
+// Deserializes incoming frames, taking care of buffering and tokenization.
+// Used by both host and client to decode incoming frames.
+//
+// Which problem does it solve?
+// ----------------------------
+// The wire protocol is as follows:
+// [32-bit frame size][proto-encoded Frame], e.g:
+// [06 00 00 00][00 11 22 33 44 55 66]
+// [02 00 00 00][AA BB]
+// [04 00 00 00][CC DD EE FF]
+// However, given that the socket works in SOCK_STREAM mode, the recv() calls
+// might see the following:
+// 06 00 00
+// 00 00 11 22 33 44 55
+// 66 02 00 00 00 ...
+// This class takes care of buffering efficiently the data received, without
+// making any assumption on how the incoming data will be chunked by the socket.
+// For instance, it is possible that a recv() doesn't produce any frame (because
+// it received only a part of the frame) or produces more than one frame.
+//
+// Usage
+// -----
+// Both host and client use this as follows:
+//
+// auto buf = rpc_frame_decoder.BeginReceive();
+// size_t rsize = socket.recv(buf.first, buf.second);
+// rpc_frame_decoder.EndReceive(rsize);
+// while (Frame frame = rpc_frame_decoder.PopNextFrame()) {
+//   ... process |frame|
+// }
+//
+// Design goals:
+// -------------
+// - Optimize for the realistic case of each recv() receiving one or more
+//   whole frames. In this case no memmove is performed.
+// - Guarantee that frames lay in a virtually contiguous memory area.
+//   This allows to use the protobuf-lite deserialization API (scattered
+//   deserialization is supported only by libprotobuf-full).
+// - Put a hard boundary to the size of the incoming buffer. This is to prevent
+//   that a malicious sends an abnormally large frame and OOMs us.
+// - Simplicity: just use a linear mmap region. No reallocations or scattering.
+//   Takes care of madvise()-ing unused memory.
+
+class BufferedFrameDeserializer {
+ public:
+  struct ReceiveBuffer {
+    char* data;
+    size_t size;
+  };
+
+  // |max_capacity| is overridable only for tests.
+  explicit BufferedFrameDeserializer(size_t max_capacity = kIPCBufferSize);
+  ~BufferedFrameDeserializer();
+
+  // This function doesn't really belong here as it does Serialization, unlike
+  // the rest of this class. However it is so small and has so many dependencies
+  // in common that doesn't justify having its own class.
+  static std::string Serialize(const Frame&);
+
+  // Returns a buffer that can be passed to recv(). The buffer is deliberately
+  // not initialized.
+  ReceiveBuffer BeginReceive();
+
+  // Must be called soon after BeginReceive().
+  // |recv_size| is the number of valid bytes that have been written into the
+  // buffer previously returned by BeginReceive() (the return value of recv()).
+  // Returns false if a header > |max_capacity| is received, in which case the
+  // caller is expected to shutdown the socket and terminate the ipc.
+  bool EndReceive(size_t recv_size) PERFETTO_WARN_UNUSED_RESULT;
+
+  // Decodes and returns the next decoded frame in the buffer if any, nullptr
+  // if no further frames have been decoded.
+  std::unique_ptr<Frame> PopNextFrame();
+
+  size_t capacity() const { return capacity_; }
+  size_t size() const { return size_; }
+
+ private:
+  BufferedFrameDeserializer(const BufferedFrameDeserializer&) = delete;
+  BufferedFrameDeserializer& operator=(const BufferedFrameDeserializer&) =
+      delete;
+
+  // If a valid frame is decoded it is added to |decoded_frames_|.
+  void DecodeFrame(const char*, size_t);
+
+  char* buf() { return reinterpret_cast<char*>(buf_.Get()); }
+
+  base::PagedMemory buf_;
+  const size_t capacity_ = 0;  // sizeof(|buf_|).
+
+  // THe number of bytes in |buf_| that contain valid data (as a result of
+  // EndReceive()). This is always <= |capacity_|.
+  size_t size_ = 0;
+
+  std::list<std::unique_ptr<Frame>> decoded_frames_;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
+
+#include <algorithm>
+#include <cinttypes>
+#include <type_traits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
+
+namespace perfetto {
+namespace ipc {
+
+namespace {
+
+// The header is just the number of bytes of the Frame protobuf message.
+constexpr size_t kHeaderSize = sizeof(uint32_t);
+}  // namespace
+
+BufferedFrameDeserializer::BufferedFrameDeserializer(size_t max_capacity)
+    : capacity_(max_capacity) {
+  PERFETTO_CHECK(max_capacity % base::GetSysPageSize() == 0);
+  PERFETTO_CHECK(max_capacity >= base::GetSysPageSize());
+}
+
+BufferedFrameDeserializer::~BufferedFrameDeserializer() = default;
+
+BufferedFrameDeserializer::ReceiveBuffer
+BufferedFrameDeserializer::BeginReceive() {
+  // Upon the first recv initialize the buffer to the max message size but
+  // release the physical memory for all but the first page. The kernel will
+  // automatically give us physical pages back as soon as we page-fault on them.
+  if (!buf_.IsValid()) {
+    PERFETTO_DCHECK(size_ == 0);
+    // TODO(eseckler): Don't commit all of the buffer at once on Windows.
+    buf_ = base::PagedMemory::Allocate(capacity_);
+
+    // Surely we are going to use at least the first page, but we may not need
+    // the rest for a bit.
+    const auto page_size = base::GetSysPageSize();
+    buf_.AdviseDontNeed(buf() + page_size, capacity_ - page_size);
+  }
+
+  PERFETTO_CHECK(capacity_ > size_);
+  return ReceiveBuffer{buf() + size_, capacity_ - size_};
+}
+
+bool BufferedFrameDeserializer::EndReceive(size_t recv_size) {
+  const auto page_size = base::GetSysPageSize();
+  PERFETTO_CHECK(recv_size + size_ <= capacity_);
+  size_ += recv_size;
+
+  // At this point the contents buf_ can contain:
+  // A) Only a fragment of the header (the size of the frame). E.g.,
+  //    03 00 00 (the header is 4 bytes, one is missing).
+  //
+  // B) A header and a part of the frame. E.g.,
+  //     05 00 00 00         11 22 33
+  //    [ header, size=5 ]  [ Partial frame ]
+  //
+  // C) One or more complete header+frame. E.g.,
+  //     05 00 00 00         11 22 33 44 55   03 00 00 00        AA BB CC
+  //    [ header, size=5 ]  [ Whole frame ]  [ header, size=3 ] [ Whole frame ]
+  //
+  // D) Some complete header+frame(s) and a partial header or frame (C + A/B).
+  //
+  // C Is the more likely case and the one we are optimizing for. A, B, D can
+  // happen because of the streaming nature of the socket.
+  // The invariant of this function is that, when it returns, buf_ is either
+  // empty (we drained all the complete frames) or starts with the header of the
+  // next, still incomplete, frame.
+
+  size_t consumed_size = 0;
+  for (;;) {
+    if (size_ < consumed_size + kHeaderSize)
+      break;  // Case A, not enough data to read even the header.
+
+    // Read the header into |payload_size|.
+    uint32_t payload_size = 0;
+    const char* rd_ptr = buf() + consumed_size;
+    memcpy(base::AssumeLittleEndian(&payload_size), rd_ptr, kHeaderSize);
+
+    // Saturate the |payload_size| to prevent overflows. The > capacity_ check
+    // below will abort the parsing.
+    size_t next_frame_size =
+        std::min(static_cast<size_t>(payload_size), capacity_);
+    next_frame_size += kHeaderSize;
+    rd_ptr += kHeaderSize;
+
+    if (size_ < consumed_size + next_frame_size) {
+      // Case B. We got the header but not the whole frame.
+      if (next_frame_size > capacity_) {
+        // The caller is expected to shut down the socket and give up at this
+        // point. If it doesn't do that and insists going on at some point it
+        // will hit the capacity check in BeginReceive().
+        PERFETTO_LOG("IPC Frame too large (size %zu)", next_frame_size);
+        return false;
+      }
+      break;
+    }
+
+    // Case C. We got at least one header and whole frame.
+    DecodeFrame(rd_ptr, payload_size);
+    consumed_size += next_frame_size;
+  }
+
+  PERFETTO_DCHECK(consumed_size <= size_);
+  if (consumed_size > 0) {
+    // Shift out the consumed data from the buffer. In the typical case (C)
+    // there is nothing to shift really, just setting size_ = 0 is enough.
+    // Shifting is only for the (unlikely) case D.
+    size_ -= consumed_size;
+    if (size_ > 0) {
+      // Case D. We consumed some frames but there is a leftover at the end of
+      // the buffer. Shift out the consumed bytes, so that on the next round
+      // |buf_| starts with the header of the next unconsumed frame.
+      const char* move_begin = buf() + consumed_size;
+      PERFETTO_CHECK(move_begin > buf());
+      PERFETTO_CHECK(move_begin + size_ <= buf() + capacity_);
+      memmove(buf(), move_begin, size_);
+    }
+    // If we just finished decoding a large frame that used more than one page,
+    // release the extra memory in the buffer. Large frames should be quite
+    // rare.
+    if (consumed_size > page_size) {
+      size_t size_rounded_up = (size_ / page_size + 1) * page_size;
+      if (size_rounded_up < capacity_) {
+        char* madvise_begin = buf() + size_rounded_up;
+        const size_t madvise_size = capacity_ - size_rounded_up;
+        PERFETTO_CHECK(madvise_begin > buf() + size_);
+        PERFETTO_CHECK(madvise_begin + madvise_size <= buf() + capacity_);
+        buf_.AdviseDontNeed(madvise_begin, madvise_size);
+      }
+    }
+  }
+  // At this point |size_| == 0 for case C, > 0 for cases A, B, D.
+  return true;
+}
+
+std::unique_ptr<Frame> BufferedFrameDeserializer::PopNextFrame() {
+  if (decoded_frames_.empty())
+    return nullptr;
+  std::unique_ptr<Frame> frame = std::move(decoded_frames_.front());
+  decoded_frames_.pop_front();
+  return frame;
+}
+
+void BufferedFrameDeserializer::DecodeFrame(const char* data, size_t size) {
+  if (size == 0)
+    return;
+  std::unique_ptr<Frame> frame(new Frame);
+  if (frame->ParseFromArray(data, size))
+    decoded_frames_.push_back(std::move(frame));
+}
+
+// static
+std::string BufferedFrameDeserializer::Serialize(const Frame& frame) {
+  std::vector<uint8_t> payload = frame.SerializeAsArray();
+  const uint32_t payload_size = static_cast<uint32_t>(payload.size());
+  std::string buf;
+  buf.resize(kHeaderSize + payload_size);
+  memcpy(&buf[0], base::AssumeLittleEndian(&payload_size), kHeaderSize);
+  memcpy(&buf[kHeaderSize], payload.data(), payload.size());
+  return buf;
+}
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/deferred.cc
+// gen_amalgamated begin header: include/perfetto/ext/ipc/deferred.h
+// gen_amalgamated begin header: include/perfetto/ext/ipc/async_result.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
+#define INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
+
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+namespace ipc {
+
+// Wraps the result of an asynchronous invocation. This is the equivalent of a
+// std::pair<unique_ptr<T>, bool> with syntactic sugar. It is used as callback
+// argument by Deferred<T>. T is a ProtoMessage subclass (i.e. generated .pb.h).
+template <typename T>
+class AsyncResult {
+ public:
+  static AsyncResult Create() {
+    return AsyncResult(std::unique_ptr<T>(new T()));
+  }
+
+  AsyncResult(std::unique_ptr<T> msg = nullptr,
+              bool has_more = false,
+              int fd = -1)
+      : msg_(std::move(msg)), has_more_(has_more), fd_(fd) {
+    static_assert(std::is_base_of<ProtoMessage, T>::value, "T->ProtoMessage");
+  }
+  AsyncResult(AsyncResult&&) noexcept = default;
+  AsyncResult& operator=(AsyncResult&&) = default;
+
+  bool success() const { return !!msg_; }
+  explicit operator bool() const { return success(); }
+
+  bool has_more() const { return has_more_; }
+  void set_has_more(bool has_more) { has_more_ = has_more; }
+
+  void set_msg(std::unique_ptr<T> msg) { msg_ = std::move(msg); }
+  T* release_msg() { return msg_.release(); }
+  T* operator->() { return msg_.get(); }
+  T& operator*() { return *msg_; }
+
+  void set_fd(int fd) { fd_ = fd; }
+  int fd() const { return fd_; }
+
+ private:
+  std::unique_ptr<T> msg_;
+  bool has_more_ = false;
+
+  // Optional. Only for messages that convey a file descriptor, for sharing
+  // memory across processes.
+  int fd_ = -1;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
+#define INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
+
+#include <functional>
+#include <memory>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/async_result.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+namespace ipc {
+
+// This class is a wrapper for a callback handling async results.
+// The problem this is solving is the following: For each result argument of the
+// methods generated from the .proto file:
+// - The client wants to see something on which it can Bind() a callback, which
+//   is invoked asynchronously once reply is received from the host.
+// - The host wants to expose something to user code that implements the IPC
+//   methods to allow them to provide an asynchronous reply back to the client.
+//   Eventually even more than once, for the case streaming replies.
+//
+// In both cases we want to make sure that callbacks don't get lost along the
+// way. To address this, this class will automatically reject the callbacks
+// if they are not resolved at destructor time (or the object is std::move()'d).
+//
+// The client is supposed to use this class as follows:
+//   class GreeterProxy {
+//      void SayHello(const HelloRequest&, Deferred<HelloReply> reply)
+//   }
+//  ...
+//  Deferred<HelloReply> reply;
+//  reply.Bind([] (AsyncResult<HelloReply> reply) {
+//    std::cout << reply.success() ? reply->message : "failure";
+//  });
+//  host_proxy_instance.SayHello(req, std::move(reply));
+//
+// The host instead is supposed to use this as follows:
+//   class GreeterImpl : public Greeter {
+//     void SayHello(const HelloRequest& req, Deferred<HelloReply> reply) {
+//        AsyncResult<HelloReply> reply = AsyncResult<HelloReply>::Create();
+//        reply->set_greeting("Hello " + req.name)
+//        reply.Resolve(std::move(reply));
+//     }
+//   }
+// Or for more complex cases, the deferred object can be std::move()'d outside
+// and the reply can continue asynchronously later.
+
+template <typename T>
+class Deferred;
+
+class DeferredBase {
+ public:
+  explicit DeferredBase(
+      std::function<void(AsyncResult<ProtoMessage>)> callback = nullptr);
+
+  ~DeferredBase();
+  DeferredBase(DeferredBase&&) noexcept;
+  DeferredBase& operator=(DeferredBase&&);
+  void Bind(std::function<void(AsyncResult<ProtoMessage>)> callback);
+  bool IsBound() const;
+  void Resolve(AsyncResult<ProtoMessage>);
+  void Reject();
+
+ protected:
+  template <typename T>
+  friend class Deferred;
+  void Move(DeferredBase&);
+
+  std::function<void(AsyncResult<ProtoMessage>)> callback_;
+};
+
+template <typename T>  // T : ProtoMessage subclass
+class Deferred : public DeferredBase {
+ public:
+  explicit Deferred(std::function<void(AsyncResult<T>)> callback = nullptr) {
+    Bind(std::move(callback));
+  }
+
+  // This move constructor (and the similar one in DeferredBase) is meant to be
+  // called only by the autogenerated code. The caller has to guarantee that the
+  // moved-from and moved-to types match. The behavior is otherwise undefined.
+  explicit Deferred(DeferredBase&& other) {
+    callback_ = std::move(other.callback_);
+    other.callback_ = nullptr;
+  }
+
+  void Bind(std::function<void(AsyncResult<T>)> callback) {
+    if (!callback)
+      return;
+
+    // Here we need a callback adapter to downcast the callback to a generic
+    // callback that takes an AsyncResult<ProtoMessage>, so that it can be
+    // stored in the base class |callback_|.
+    auto callback_adapter = [callback](
+                                AsyncResult<ProtoMessage> async_result_base) {
+      // Upcast the async_result from <ProtoMessage> -> <T : ProtoMessage>.
+      static_assert(std::is_base_of<ProtoMessage, T>::value, "T:ProtoMessage");
+      AsyncResult<T> async_result(
+          std::unique_ptr<T>(static_cast<T*>(async_result_base.release_msg())),
+          async_result_base.has_more(), async_result_base.fd());
+      callback(std::move(async_result));
+    };
+    DeferredBase::Bind(callback_adapter);
+  }
+
+  // If no more messages are expected, |callback_| is released.
+  void Resolve(AsyncResult<T> async_result) {
+    // Convert the |async_result| to the generic base one (T -> ProtoMessage).
+    AsyncResult<ProtoMessage> async_result_base(
+        std::unique_ptr<ProtoMessage>(async_result.release_msg()),
+        async_result.has_more(), async_result.fd());
+    DeferredBase::Resolve(std::move(async_result_base));
+  }
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+
+namespace perfetto {
+namespace ipc {
+
+DeferredBase::DeferredBase(
+    std::function<void(AsyncResult<ProtoMessage>)> callback)
+    : callback_(std::move(callback)) {}
+
+DeferredBase::~DeferredBase() {
+  if (callback_)
+    Reject();
+}
+
+// Can't just use "= default" here because the default move operator for
+// std::function doesn't necessarily swap and hence can leave a copy of the
+// bind state around, which is undesirable.
+DeferredBase::DeferredBase(DeferredBase&& other) noexcept {
+  Move(other);
+}
+
+DeferredBase& DeferredBase::operator=(DeferredBase&& other) {
+  if (callback_)
+    Reject();
+  Move(other);
+  return *this;
+}
+
+void DeferredBase::Move(DeferredBase& other) {
+  callback_ = std::move(other.callback_);
+  other.callback_ = nullptr;
+}
+
+void DeferredBase::Bind(
+    std::function<void(AsyncResult<ProtoMessage>)> callback) {
+  callback_ = std::move(callback);
+}
+
+bool DeferredBase::IsBound() const {
+  return !!callback_;
+}
+
+void DeferredBase::Resolve(AsyncResult<ProtoMessage> async_result) {
+  if (!callback_) {
+    PERFETTO_DFATAL("No callback set.");
+    return;
+  }
+  bool has_more = async_result.has_more();
+  callback_(std::move(async_result));
+  if (!has_more)
+    callback_ = nullptr;
+}
+
+// Resolves with a nullptr |msg_|, signalling failure to |callback_|.
+void DeferredBase::Reject() {
+  Resolve(AsyncResult<ProtoMessage>());
+}
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/virtual_destructors.cc
+// gen_amalgamated begin header: include/perfetto/ext/ipc/client.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
+#define INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
+
+#include <functional>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace ipc {
+class ServiceProxy;
+
+// The client-side class that talks to the host over the socket and multiplexes
+// requests coming from the various autogenerated ServiceProxy stubs.
+// This is meant to be used by the user code as follows:
+// auto client = Client::CreateInstance("socket_name", task_runner);
+// std::unique_ptr<GreeterService> svc(new GreeterService());
+// client.BindService(svc);
+// svc.OnConnect([] () {
+//    svc.SayHello(..., ...);
+// });
+class Client {
+ public:
+  // struct ConnArgs is used for creating a client in 2 connection modes:
+  // 1. Connect using a socket name with the option to retry the connection on
+  //    connection failure.
+  // 2. Adopt a connected socket.
+  struct ConnArgs {
+    ConnArgs(const char* sock_name, bool sock_retry)
+        : socket_name(sock_name), retry(sock_retry) {}
+    explicit ConnArgs(base::ScopedSocketHandle sock_fd)
+        : socket_fd(std::move(sock_fd)) {}
+
+    // Disallow copy. Only supports move.
+    ConnArgs(const ConnArgs& other) = delete;
+    ConnArgs(ConnArgs&& other) = default;
+
+    base::ScopedSocketHandle socket_fd;
+    const char* socket_name = nullptr;
+    bool retry = false;  // Only for connecting with |socket_name|.
+    std::function<int(void)> receive_shmem_fd_cb_fuchsia;
+  };
+
+  static std::unique_ptr<Client> CreateInstance(ConnArgs, base::TaskRunner*);
+  virtual ~Client();
+
+  virtual void BindService(base::WeakPtr<ServiceProxy>) = 0;
+
+  // There is no need to call this method explicitly. Destroying the
+  // ServiceProxy instance is sufficient and will automatically unbind it. This
+  // method is exposed only for the ServiceProxy destructor.
+  virtual void UnbindService(ServiceID) = 0;
+
+  // Returns (with move semantics) the last file descriptor received on the IPC
+  // channel. No buffering is performed: if a service sends two file descriptors
+  // and the caller doesn't read them immediately, the first one will be
+  // automatically closed when the second is received (and will hit a DCHECK in
+  // debug builds).
+  virtual base::ScopedFile TakeReceivedFD() = 0;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
+// gen_amalgamated begin header: include/perfetto/ext/ipc/host.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_HOST_H_
+#define INCLUDE_PERFETTO_EXT_IPC_HOST_H_
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace ipc {
+
+class Service;
+
+// The host-side of the IPC layer. This class acts as a registry and request
+// dispatcher. It listen on the UnixSocket |socket_name| for incoming requests
+// (coming Client instances) and dispatches their requests to the various
+// Services exposed.
+class Host {
+ public:
+  // Creates an instance and starts listening on the given |socket_name|.
+  // Returns nullptr if listening on the socket fails.
+  static std::unique_ptr<Host> CreateInstance(const char* socket_name,
+                                              base::TaskRunner*);
+
+  // Like the above but takes a file descriptor to a pre-bound unix socket.
+  // Returns nullptr if listening on the socket fails.
+  static std::unique_ptr<Host> CreateInstance(base::ScopedSocketHandle,
+                                              base::TaskRunner*);
+
+  // Creates a Host which is not backed by a POSIX listening socket.
+  // Instead, it accepts sockets passed in via AdoptConnectedSocket_Fuchsia().
+  // See go/fuchsetto for more details.
+  static std::unique_ptr<Host> CreateInstance_Fuchsia(base::TaskRunner*);
+
+  virtual ~Host();
+
+  // Registers a new service and makes it available to remote IPC peers.
+  // All the exposed Service instances will be destroyed when destroying the
+  // Host instance if ExposeService succeeds and returns true, or immediately
+  // after the call in case of failure.
+  // Returns true if the register has been successfully registered, false in
+  // case of errors (e.g., another service with the same name is already
+  // registered).
+  virtual bool ExposeService(std::unique_ptr<Service>) = 0;
+
+  // Accepts a pre-connected socket handle and a callback used to send a
+  // shared memory FD to the remote client.
+  // The callback returns false if the FD could not be sent.
+  // Should only be used in conjunction with CreateInstance_Fuchsia().
+  virtual void AdoptConnectedSocket_Fuchsia(
+      base::ScopedSocketHandle,
+      std::function<bool(int)> send_fd_cb) = 0;
+
+  // Overrides the default send timeout for the per-connection sockets.
+  virtual void SetSocketSendTimeoutMs(uint32_t timeout_ms) = 0;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_HOST_H_
+// gen_amalgamated begin header: include/perfetto/ext/ipc/service.h
+// gen_amalgamated begin header: include/perfetto/ext/ipc/client_info.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
+#define INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+namespace perfetto {
+namespace ipc {
+
+// Passed to Service(s) to identify remote clients.
+class ClientInfo {
+ public:
+  ClientInfo() = default;
+  ClientInfo(ClientID client_id,
+             uid_t uid,
+             pid_t pid,
+             base::MachineID machine_id)
+      : client_id_(client_id), uid_(uid), pid_(pid), machine_id_(machine_id) {}
+
+  bool operator==(const ClientInfo& other) const {
+    return std::tie(client_id_, uid_, pid_, machine_id_) ==
+           std::tie(other.client_id_, other.uid_, other.pid_,
+                    other.machine_id_);
+  }
+  bool operator!=(const ClientInfo& other) const { return !(*this == other); }
+
+  // For map<> and other sorted containers.
+  bool operator<(const ClientInfo& other) const {
+    PERFETTO_DCHECK(client_id_ != other.client_id_ || *this == other);
+    return client_id_ < other.client_id_;
+  }
+
+  bool is_valid() const { return client_id_ != 0; }
+
+  // A monotonic counter.
+  ClientID client_id() const { return client_id_; }
+
+  // Posix User ID. Comes from the kernel, can be trusted.
+  uid_t uid() const { return uid_; }
+
+  // Posix process ID. Comes from the kernel and can be trusted.
+  int32_t pid() const { return pid_; }
+
+  // An integral ID that identifies the machine the client is on.
+  base::MachineID machine_id() const { return machine_id_; }
+
+ private:
+  ClientID client_id_ = 0;
+  // The following fields are emitted to trace packets and should be kept in
+  // sync with perfetto::ClientIdentity.
+  uid_t uid_ = kInvalidUid;
+  pid_t pid_ = base::kInvalidPid;
+  base::MachineID machine_id_ = base::kDefaultMachineID;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
+#define INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client_info.h"
+
+namespace perfetto {
+namespace ipc {
+
+class ServiceDescriptor;
+
+// The base class for all the autogenerated host-side service interfaces.
+class Service {
+ public:
+  virtual ~Service();
+
+  // Overridden by the auto-generated class. Provides the list of methods and
+  // the protobuf (de)serialization functions for their arguments.
+  virtual const ServiceDescriptor& GetDescriptor() = 0;
+
+  // Invoked when a remote client disconnects. Use client_info() to obtain
+  // details about the client that disconnected.
+  virtual void OnClientDisconnected() {}
+
+  // Returns the ClientInfo for the current IPC request. Returns an invalid
+  // ClientInfo if called outside the scope of an IPC method.
+  const ClientInfo& client_info() {
+    PERFETTO_DCHECK(client_info_.is_valid());
+    return client_info_;
+  }
+
+  base::ScopedFile TakeReceivedFD() {
+    if (received_fd_)
+      return std::move(*received_fd_);
+    return base::ScopedFile();
+  }
+
+  bool use_shmem_emulation() { return use_shmem_emulation_; }
+
+ private:
+  friend class HostImpl;
+  ClientInfo client_info_;
+  // This is a pointer because the received fd needs to remain owned by the
+  // ClientConnection, as we will provide it to all method invocations
+  // for that client until one of them calls Service::TakeReceivedFD.
+  //
+  // Different clients might have sent different FDs so this cannot be owned
+  // here.
+  //
+  // Note that this means that there can always only be one outstanding
+  // invocation per client that supplies an FD and the client needs to
+  // wait for this one to return before calling another one.
+  base::ScopedFile* received_fd_;
+
+  // Whether the socket needs to emulate shared memory buffer. Set by HostImpl
+  // when the service is exposed.
+  bool use_shmem_emulation_ = false;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
+// gen_amalgamated begin header: include/perfetto/ext/ipc/service_proxy.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
+#define INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+
+#include <assert.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+
+namespace perfetto {
+namespace ipc {
+
+class Client;
+class ServiceDescriptor;
+
+// The base class for the client-side autogenerated stubs that forward method
+// invocations to the host. All the methods of this class are meant to be called
+// only by the autogenerated code.
+class PERFETTO_EXPORT_COMPONENT ServiceProxy {
+ public:
+  class EventListener {
+   public:
+    virtual ~EventListener();
+
+    // Called once after Client::BindService() if the ServiceProxy has been
+    // successfully bound to the host. It is possible to start sending IPC
+    // requests soon after this.
+    virtual void OnConnect() {}
+
+    // Called if the connection fails to be established or drops after having
+    // been established.
+    virtual void OnDisconnect() {}
+  };
+
+  // Guarantees that no callback will happen after this object has been
+  // destroyed. The caller has to guarantee that the |event_listener| stays
+  // alive at least as long as the ServiceProxy instance.
+  explicit ServiceProxy(EventListener*);
+  virtual ~ServiceProxy();
+
+  void InitializeBinding(base::WeakPtr<Client>,
+                         ServiceID,
+                         std::map<std::string, MethodID>);
+
+  // Called by the IPC methods in the autogenerated classes.
+  void BeginInvoke(const std::string& method_name,
+                   const ProtoMessage& request,
+                   DeferredBase reply,
+                   int fd = -1);
+
+  // Called by ClientImpl.
+  // |reply_args| == nullptr means request failure.
+  void EndInvoke(RequestID,
+                 std::unique_ptr<ProtoMessage> reply_arg,
+                 bool has_more);
+
+  // Called by ClientImpl.
+  void OnConnect(bool success);
+  void OnDisconnect();
+  bool connected() const { return service_id_ != 0; }
+
+  base::WeakPtr<ServiceProxy> GetWeakPtr() const;
+
+  // Implemented by the autogenerated class.
+  virtual const ServiceDescriptor& GetDescriptor() = 0;
+
+ private:
+  base::WeakPtr<Client> client_;
+  ServiceID service_id_ = 0;
+  std::map<std::string, MethodID> remote_method_ids_;
+  std::map<RequestID, DeferredBase> pending_callbacks_;
+  EventListener* const event_listener_;
+  base::WeakPtrFactory<ServiceProxy> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+// This translation unit contains the definitions for the destructor of pure
+// virtual interfaces for the current build target. The alternative would be
+// introducing a one-liner .cc file for each pure virtual interface, which is
+// overkill. This is for compliance with -Wweak-vtables.
+
+namespace perfetto {
+namespace ipc {
+
+Client::~Client() = default;
+Host::~Host() = default;
+Service::~Service() = default;
+ServiceProxy::EventListener::~EventListener() = default;
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/client_impl.cc
+// gen_amalgamated begin header: src/ipc/client_impl.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_IPC_CLIENT_IMPL_H_
+#define SRC_IPC_CLIENT_IMPL_H_
+
+#include <list>
+#include <map>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
+
+namespace perfetto {
+
+namespace protos {
+namespace gen {
+class IPCFrame_BindServiceReply;
+class IPCFrame_InvokeMethodReply;
+}  // namespace gen
+}  // namespace protos
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace ipc {
+
+class ServiceDescriptor;
+
+class ClientImpl : public Client, public base::UnixSocket::EventListener {
+ public:
+  ClientImpl(ConnArgs, base::TaskRunner*);
+  ~ClientImpl() override;
+
+  // Client implementation.
+  void BindService(base::WeakPtr<ServiceProxy>) override;
+  void UnbindService(ServiceID) override;
+  base::ScopedFile TakeReceivedFD() override;
+
+  // base::UnixSocket::EventListener implementation.
+  void OnConnect(base::UnixSocket*, bool connected) override;
+  void OnDisconnect(base::UnixSocket*) override;
+  void OnDataAvailable(base::UnixSocket*) override;
+
+  RequestID BeginInvoke(ServiceID,
+                        const std::string& method_name,
+                        MethodID remote_method_id,
+                        const ProtoMessage& method_args,
+                        bool drop_reply,
+                        base::WeakPtr<ServiceProxy>,
+                        int fd = -1);
+
+  base::UnixSocket* GetUnixSocketForTesting() { return sock_.get(); }
+
+ private:
+  struct QueuedRequest {
+    QueuedRequest();
+    int type = 0;  // From Frame::msg_case(), see wire_protocol.proto.
+    RequestID request_id = 0;
+    base::WeakPtr<ServiceProxy> service_proxy;
+
+    // Only for type == kMsgInvokeMethod.
+    std::string method_name;
+  };
+
+  ClientImpl(const ClientImpl&) = delete;
+  ClientImpl& operator=(const ClientImpl&) = delete;
+
+  void TryConnect();
+  bool SendFrame(const Frame&, int fd = -1);
+  void OnFrameReceived(const Frame&);
+  void OnBindServiceReply(QueuedRequest,
+                          const protos::gen::IPCFrame_BindServiceReply&);
+  void OnInvokeMethodReply(QueuedRequest,
+                           const protos::gen::IPCFrame_InvokeMethodReply&);
+
+  bool invoking_method_reply_ = false;
+  const char* socket_name_ = nullptr;
+  bool socket_retry_ = false;
+  uint32_t socket_backoff_ms_ = 0;
+  std::unique_ptr<base::UnixSocket> sock_;
+  base::TaskRunner* const task_runner_;
+  RequestID last_request_id_ = 0;
+  BufferedFrameDeserializer frame_deserializer_;
+  base::ScopedFile received_fd_;
+  std::map<RequestID, QueuedRequest> queued_requests_;
+  std::map<ServiceID, base::WeakPtr<ServiceProxy>> service_bindings_;
+
+  // Queue of calls to BindService() that happened before the socket connected.
+  std::list<base::WeakPtr<ServiceProxy>> queued_bindings_;
+
+  base::WeakPtrFactory<Client> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // SRC_IPC_CLIENT_IMPL_H_
+// gen_amalgamated begin header: include/perfetto/ext/ipc/service_descriptor.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
+#define INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
+
+#include <functional>
+#include <string>
+#include <utility>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+
+namespace perfetto {
+namespace ipc {
+
+class Service;
+
+// This is a pure data structure which holds factory methods and strings for the
+// services and their methods that get generated in the .h/.cc files.
+// Each autogenerated class has a GetDescriptor() method that returns one
+// instance of these and allows both client and hosts to map service and method
+// names to IDs and provide function pointers to the protobuf decoder fuctions.
+class ServiceDescriptor {
+ public:
+  struct Method {
+    const char* name;
+
+    // DecoderFunc is pointer to a function that takes a string in input
+    // containing protobuf encoded data and returns a decoded protobuf message.
+    using DecoderFunc = std::unique_ptr<ProtoMessage> (*)(const std::string&);
+
+    // Function pointer to decode the request argument of the method.
+    DecoderFunc request_proto_decoder;
+
+    // Function pointer to decoded the reply argument of the method.
+    DecoderFunc reply_proto_decoder;
+
+    // Function pointer that dispatches the generic request to the corresponding
+    // method implementation.
+    using InvokerFunc = void (*)(Service*,
+                                 const ProtoMessage& /* request_args */,
+                                 DeferredBase /* deferred_reply */);
+    InvokerFunc invoker;
+  };
+
+  const char* service_name = nullptr;
+
+  // Note that methods order is not stable. Client and Host might have different
+  // method indexes, depending on their versions. The Client can't just rely
+  // on the indexes and has to keep a [string -> remote index] translation map.
+  std::vector<Method> methods;
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/ipc/client_impl.h"
+
+#include <fcntl.h>
+
+#include <cinttypes>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
+
+// TODO(primiano): Add ThreadChecker everywhere.
+
+// TODO(primiano): Add timeouts.
+
+namespace perfetto {
+namespace ipc {
+
+namespace {
+constexpr base::SockFamily kClientSockFamily =
+    kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
+}  // namespace
+
+// static
+std::unique_ptr<Client> Client::CreateInstance(ConnArgs conn_args,
+                                               base::TaskRunner* task_runner) {
+  std::unique_ptr<Client> client(
+      new ClientImpl(std::move(conn_args), task_runner));
+  return client;
+}
+
+ClientImpl::ClientImpl(ConnArgs conn_args, base::TaskRunner* task_runner)
+    : socket_name_(conn_args.socket_name),
+      socket_retry_(conn_args.retry),
+      task_runner_(task_runner),
+      weak_ptr_factory_(this) {
+  if (conn_args.socket_fd) {
+    // Create the client using a connected socket. This code path will never hit
+    // OnConnect().
+    sock_ = base::UnixSocket::AdoptConnected(
+        std::move(conn_args.socket_fd), this, task_runner_, kClientSockFamily,
+        base::SockType::kStream, base::SockPeerCredMode::kIgnore);
+  } else {
+    // Connect using the socket name.
+    TryConnect();
+  }
+}
+
+ClientImpl::~ClientImpl() {
+  // Ensure we are not destroyed in the middle of invoking a reply.
+  PERFETTO_DCHECK(!invoking_method_reply_);
+  OnDisconnect(
+      nullptr);  // The base::UnixSocket* ptr is not used in OnDisconnect().
+}
+
+void ClientImpl::TryConnect() {
+  PERFETTO_DCHECK(socket_name_);
+  sock_ = base::UnixSocket::Connect(
+      socket_name_, this, task_runner_, base::GetSockFamily(socket_name_),
+      base::SockType::kStream, base::SockPeerCredMode::kIgnore);
+}
+
+void ClientImpl::BindService(base::WeakPtr<ServiceProxy> service_proxy) {
+  if (!service_proxy)
+    return;
+  if (!sock_->is_connected()) {
+    queued_bindings_.emplace_back(service_proxy);
+    return;
+  }
+  RequestID request_id = ++last_request_id_;
+  Frame frame;
+  frame.set_request_id(request_id);
+  Frame::BindService* req = frame.mutable_msg_bind_service();
+  const char* const service_name = service_proxy->GetDescriptor().service_name;
+  req->set_service_name(service_name);
+  if (!SendFrame(frame)) {
+    PERFETTO_DLOG("BindService(%s) failed", service_name);
+    return service_proxy->OnConnect(false /* success */);
+  }
+  QueuedRequest qr;
+  qr.type = Frame::kMsgBindServiceFieldNumber;
+  qr.request_id = request_id;
+  qr.service_proxy = service_proxy;
+  queued_requests_.emplace(request_id, std::move(qr));
+}
+
+void ClientImpl::UnbindService(ServiceID service_id) {
+  service_bindings_.erase(service_id);
+}
+
+RequestID ClientImpl::BeginInvoke(ServiceID service_id,
+                                  const std::string& method_name,
+                                  MethodID remote_method_id,
+                                  const ProtoMessage& method_args,
+                                  bool drop_reply,
+                                  base::WeakPtr<ServiceProxy> service_proxy,
+                                  int fd) {
+  RequestID request_id = ++last_request_id_;
+  Frame frame;
+  frame.set_request_id(request_id);
+  Frame::InvokeMethod* req = frame.mutable_msg_invoke_method();
+  req->set_service_id(service_id);
+  req->set_method_id(remote_method_id);
+  req->set_drop_reply(drop_reply);
+  req->set_args_proto(method_args.SerializeAsString());
+  if (!SendFrame(frame, fd)) {
+    PERFETTO_DLOG("BeginInvoke() failed while sending the frame");
+    return 0;
+  }
+  if (drop_reply)
+    return 0;
+  QueuedRequest qr;
+  qr.type = Frame::kMsgInvokeMethodFieldNumber;
+  qr.request_id = request_id;
+  qr.method_name = method_name;
+  qr.service_proxy = std::move(service_proxy);
+  queued_requests_.emplace(request_id, std::move(qr));
+  return request_id;
+}
+
+bool ClientImpl::SendFrame(const Frame& frame, int fd) {
+  // Serialize the frame into protobuf, add the size header, and send it.
+  std::string buf = BufferedFrameDeserializer::Serialize(frame);
+
+  // TODO(primiano): this should do non-blocking I/O. But then what if the
+  // socket buffer is full? We might want to either drop the request or throttle
+  // the send and PostTask the reply later? Right now we are making Send()
+  // blocking as a workaround. Propagate bakpressure to the caller instead.
+  bool res = sock_->Send(buf.data(), buf.size(), fd);
+  PERFETTO_CHECK(res || !sock_->is_connected());
+  return res;
+}
+
+void ClientImpl::OnConnect(base::UnixSocket*, bool connected) {
+  if (!connected && socket_retry_) {
+    socket_backoff_ms_ =
+        (socket_backoff_ms_ < 10000) ? socket_backoff_ms_ + 1000 : 30000;
+    PERFETTO_DLOG(
+        "Connection to traced's UNIX socket failed, retrying in %u seconds",
+        socket_backoff_ms_ / 1000);
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+    task_runner_->PostDelayedTask(
+        [weak_this] {
+          if (weak_this)
+            static_cast<ClientImpl&>(*weak_this).TryConnect();
+        },
+        socket_backoff_ms_);
+    return;
+  }
+
+  // Drain the BindService() calls that were queued before establishing the
+  // connection with the host. Note that if we got disconnected, the call to
+  // OnConnect below might delete |this|, so move everything on the stack first.
+  auto queued_bindings = std::move(queued_bindings_);
+  queued_bindings_.clear();
+  for (base::WeakPtr<ServiceProxy>& service_proxy : queued_bindings) {
+    if (connected) {
+      BindService(service_proxy);
+    } else if (service_proxy) {
+      service_proxy->OnConnect(false /* success */);
+    }
+  }
+  // Don't access |this| below here.
+}
+
+void ClientImpl::OnDisconnect(base::UnixSocket*) {
+  for (const auto& it : service_bindings_) {
+    base::WeakPtr<ServiceProxy> service_proxy = it.second;
+    task_runner_->PostTask([service_proxy] {
+      if (service_proxy)
+        service_proxy->OnDisconnect();
+    });
+  }
+  for (const auto& it : queued_requests_) {
+    const QueuedRequest& queued_request = it.second;
+    if (queued_request.type != Frame::kMsgBindServiceFieldNumber) {
+      continue;
+    }
+    base::WeakPtr<ServiceProxy> service_proxy = queued_request.service_proxy;
+    task_runner_->PostTask([service_proxy] {
+      if (service_proxy)
+        service_proxy->OnConnect(false);
+    });
+  }
+  service_bindings_.clear();
+  queued_bindings_.clear();
+}
+
+void ClientImpl::OnDataAvailable(base::UnixSocket*) {
+  size_t rsize;
+  do {
+    auto buf = frame_deserializer_.BeginReceive();
+    base::ScopedFile fd;
+    rsize = sock_->Receive(buf.data, buf.size, &fd);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    PERFETTO_DCHECK(!fd);
+#else
+    if (fd) {
+      PERFETTO_DCHECK(!received_fd_);
+      int res = fcntl(*fd, F_SETFD, FD_CLOEXEC);
+      PERFETTO_DCHECK(res == 0);
+      received_fd_ = std::move(fd);
+    }
+#endif
+    if (!frame_deserializer_.EndReceive(rsize)) {
+      // The endpoint tried to send a frame that is way too large.
+      return sock_->Shutdown(true);  // In turn will trigger an OnDisconnect().
+      // TODO(fmayer): check this.
+    }
+  } while (rsize > 0);
+
+  while (std::unique_ptr<Frame> frame = frame_deserializer_.PopNextFrame())
+    OnFrameReceived(*frame);
+}
+
+void ClientImpl::OnFrameReceived(const Frame& frame) {
+  auto queued_requests_it = queued_requests_.find(frame.request_id());
+  if (queued_requests_it == queued_requests_.end()) {
+    PERFETTO_DLOG("OnFrameReceived(): got invalid request_id=%" PRIu64,
+                  static_cast<uint64_t>(frame.request_id()));
+    return;
+  }
+  QueuedRequest req = std::move(queued_requests_it->second);
+  queued_requests_.erase(queued_requests_it);
+
+  if (req.type == Frame::kMsgBindServiceFieldNumber &&
+      frame.has_msg_bind_service_reply()) {
+    return OnBindServiceReply(std::move(req), frame.msg_bind_service_reply());
+  }
+  if (req.type == Frame::kMsgInvokeMethodFieldNumber &&
+      frame.has_msg_invoke_method_reply()) {
+    return OnInvokeMethodReply(std::move(req), frame.msg_invoke_method_reply());
+  }
+  if (frame.has_msg_request_error()) {
+    PERFETTO_DLOG("Host error: %s", frame.msg_request_error().error().c_str());
+    return;
+  }
+
+  PERFETTO_DLOG(
+      "OnFrameReceived() request type=%d, received unknown frame in reply to "
+      "request_id=%" PRIu64,
+      req.type, static_cast<uint64_t>(frame.request_id()));
+}
+
+void ClientImpl::OnBindServiceReply(QueuedRequest req,
+                                    const Frame::BindServiceReply& reply) {
+  base::WeakPtr<ServiceProxy>& service_proxy = req.service_proxy;
+  if (!service_proxy)
+    return;
+  const char* svc_name = service_proxy->GetDescriptor().service_name;
+  if (!reply.success()) {
+    PERFETTO_DLOG("BindService(): unknown service_name=\"%s\"", svc_name);
+    return service_proxy->OnConnect(false /* success */);
+  }
+
+  auto prev_service = service_bindings_.find(reply.service_id());
+  if (prev_service != service_bindings_.end() && prev_service->second.get()) {
+    PERFETTO_DLOG(
+        "BindService(): Trying to bind service \"%s\" but another service "
+        "named \"%s\" is already bound with the same ID.",
+        svc_name, prev_service->second->GetDescriptor().service_name);
+    return service_proxy->OnConnect(false /* success */);
+  }
+
+  // Build the method [name] -> [remote_id] map.
+  std::map<std::string, MethodID> methods;
+  for (const auto& method : reply.methods()) {
+    if (method.name().empty() || method.id() <= 0) {
+      PERFETTO_DLOG("OnBindServiceReply(): invalid method \"%s\" -> %" PRIu64,
+                    method.name().c_str(), static_cast<uint64_t>(method.id()));
+      continue;
+    }
+    methods[method.name()] = method.id();
+  }
+  service_proxy->InitializeBinding(weak_ptr_factory_.GetWeakPtr(),
+                                   reply.service_id(), std::move(methods));
+  service_bindings_[reply.service_id()] = service_proxy;
+  service_proxy->OnConnect(true /* success */);
+}
+
+void ClientImpl::OnInvokeMethodReply(QueuedRequest req,
+                                     const Frame::InvokeMethodReply& reply) {
+  base::WeakPtr<ServiceProxy> service_proxy = req.service_proxy;
+  if (!service_proxy)
+    return;
+  std::unique_ptr<ProtoMessage> decoded_reply;
+  if (reply.success()) {
+    // If this becomes a hotspot, optimize by maintaining a dedicated hashtable.
+    for (const auto& method : service_proxy->GetDescriptor().methods) {
+      if (req.method_name == method.name) {
+        decoded_reply = method.reply_proto_decoder(reply.reply_proto());
+        break;
+      }
+    }
+  }
+  const RequestID request_id = req.request_id;
+  invoking_method_reply_ = true;
+  service_proxy->EndInvoke(request_id, std::move(decoded_reply),
+                           reply.has_more());
+  invoking_method_reply_ = false;
+
+  // If this is a streaming method and future replies will be resolved, put back
+  // the |req| with the callback into the set of active requests.
+  if (reply.has_more())
+    queued_requests_.emplace(request_id, std::move(req));
+}
+
+ClientImpl::QueuedRequest::QueuedRequest() = default;
+
+base::ScopedFile ClientImpl::TakeReceivedFD() {
+  return std::move(received_fd_);
+}
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/service_proxy.cc
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+// gen_amalgamated expanded: #include "src/ipc/client_impl.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
+
+namespace perfetto {
+namespace ipc {
+
+ServiceProxy::ServiceProxy(EventListener* event_listener)
+    : event_listener_(event_listener), weak_ptr_factory_(this) {}
+
+ServiceProxy::~ServiceProxy() {
+  if (client_ && connected())
+    client_->UnbindService(service_id_);
+}
+
+void ServiceProxy::InitializeBinding(
+    base::WeakPtr<Client> client,
+    ServiceID service_id,
+    std::map<std::string, MethodID> remote_method_ids) {
+  client_ = std::move(client);
+  service_id_ = service_id;
+  remote_method_ids_ = std::move(remote_method_ids);
+}
+
+void ServiceProxy::BeginInvoke(const std::string& method_name,
+                               const ProtoMessage& request,
+                               DeferredBase reply,
+                               int fd) {
+  // |reply| will auto-resolve if it gets out of scope early.
+  if (!connected()) {
+    PERFETTO_DFATAL("Not connected.");
+    return;
+  }
+  if (!client_)
+    return;  // The Client object has been destroyed in the meantime.
+
+  auto remote_method_it = remote_method_ids_.find(method_name);
+  RequestID request_id = 0;
+  const bool drop_reply = !reply.IsBound();
+  if (remote_method_it != remote_method_ids_.end()) {
+    request_id =
+        static_cast<ClientImpl*>(client_.get())
+            ->BeginInvoke(service_id_, method_name, remote_method_it->second,
+                          request, drop_reply, weak_ptr_factory_.GetWeakPtr(),
+                          fd);
+  } else {
+    PERFETTO_DLOG("Cannot find method \"%s\" on the host", method_name.c_str());
+  }
+
+  // When passing |drop_reply| == true, the returned |request_id| should be 0.
+  PERFETTO_DCHECK(!drop_reply || !request_id);
+
+  if (!request_id)
+    return;
+  PERFETTO_DCHECK(pending_callbacks_.count(request_id) == 0);
+  pending_callbacks_.emplace(request_id, std::move(reply));
+}
+
+void ServiceProxy::EndInvoke(RequestID request_id,
+                             std::unique_ptr<ProtoMessage> result,
+                             bool has_more) {
+  auto callback_it = pending_callbacks_.find(request_id);
+  if (callback_it == pending_callbacks_.end()) {
+    // Either we are getting a reply for a method we never invoked, or we are
+    // getting a reply to a method marked drop_reply (that has been invoked
+    // without binding any callback in the Defererd response object).
+    PERFETTO_DFATAL("Unexpected reply received.");
+    return;
+  }
+  DeferredBase& reply_callback = callback_it->second;
+  AsyncResult<ProtoMessage> reply(std::move(result), has_more);
+  reply_callback.Resolve(std::move(reply));
+  if (!has_more)
+    pending_callbacks_.erase(callback_it);
+}
+
+void ServiceProxy::OnConnect(bool success) {
+  if (success) {
+    PERFETTO_DCHECK(service_id_);
+    return event_listener_->OnConnect();
+  }
+  return event_listener_->OnDisconnect();
+}
+
+void ServiceProxy::OnDisconnect() {
+  pending_callbacks_.clear();  // Will Reject() all the pending callbacks.
+  event_listener_->OnDisconnect();
+}
+
+base::WeakPtr<ServiceProxy> ServiceProxy::GetWeakPtr() const {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: src/ipc/host_impl.cc
+// gen_amalgamated begin header: src/ipc/host_impl.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_IPC_HOST_IMPL_H_
+#define SRC_IPC_HOST_IMPL_H_
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
+// gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
+
+namespace perfetto {
+namespace ipc {
+
+constexpr uint32_t kDefaultIpcTxTimeoutMs = 10000;
+
+class HostImpl : public Host, public base::UnixSocket::EventListener {
+ public:
+  HostImpl(const char* socket_name, base::TaskRunner*);
+  HostImpl(base::ScopedSocketHandle, base::TaskRunner*);
+  HostImpl(base::TaskRunner* task_runner);
+  ~HostImpl() override;
+
+  // Host implementation.
+  bool ExposeService(std::unique_ptr<Service>) override;
+  void AdoptConnectedSocket_Fuchsia(
+      base::ScopedSocketHandle,
+      std::function<bool(int)> send_fd_cb) override;
+  void SetSocketSendTimeoutMs(uint32_t timeout_ms) override;
+
+  // base::UnixSocket::EventListener implementation.
+  void OnNewIncomingConnection(base::UnixSocket*,
+                               std::unique_ptr<base::UnixSocket>) override;
+  void OnDisconnect(base::UnixSocket*) override;
+  void OnDataAvailable(base::UnixSocket*) override;
+
+  const base::UnixSocket* sock() const { return sock_.get(); }
+
+ private:
+  // Owns the per-client receive buffer (BufferedFrameDeserializer).
+  struct ClientConnection {
+    ~ClientConnection();
+    ClientID id;
+    std::unique_ptr<base::UnixSocket> sock;
+    BufferedFrameDeserializer frame_deserializer;
+    base::ScopedFile received_fd;
+    std::function<bool(int)> send_fd_cb_fuchsia;
+    // Peer identity set using IPCFrame sent by the client. These 3 fields
+    // should be used only for non-AF_UNIX connections AF_UNIX connections
+    // should only rely on the peer identity obtained from the socket.
+    uid_t uid_override = base::kInvalidUid;
+    pid_t pid_override = base::kInvalidPid;
+
+    // |machine_id| is mapped from machine_id_hint (or socket hostname if
+    // |the client doesn't support machine_id_hint).
+    base::MachineID machine_id = base::kDefaultMachineID;
+
+    pid_t GetLinuxPeerPid() const;
+    uid_t GetPosixPeerUid() const;
+    base::MachineID GetMachineID() const { return machine_id; }
+  };
+  struct ExposedService {
+    ExposedService(ServiceID, const std::string&, std::unique_ptr<Service>);
+    ~ExposedService();
+    ExposedService(ExposedService&&) noexcept;
+    ExposedService& operator=(ExposedService&&);
+
+    ServiceID id;
+    std::string name;
+    std::unique_ptr<Service> instance;
+  };
+
+  HostImpl(const HostImpl&) = delete;
+  HostImpl& operator=(const HostImpl&) = delete;
+
+  bool Initialize(const char* socket_name);
+  void OnReceivedFrame(ClientConnection*, const Frame&);
+  void OnBindService(ClientConnection*, const Frame&);
+  void OnInvokeMethod(ClientConnection*, const Frame&);
+  void OnSetPeerIdentity(ClientConnection*, const Frame&);
+
+  void ReplyToMethodInvocation(ClientID, RequestID, AsyncResult<ProtoMessage>);
+  const ExposedService* GetServiceByName(const std::string&);
+
+  static void SendFrame(ClientConnection*, const Frame&, int fd = -1);
+
+  base::TaskRunner* const task_runner_;
+  std::map<ServiceID, ExposedService> services_;
+  std::unique_ptr<base::UnixSocket> sock_;  // The listening socket.
+  std::map<ClientID, std::unique_ptr<ClientConnection>> clients_;
+  std::map<base::UnixSocket*, ClientConnection*> clients_by_socket_;
+  ServiceID last_service_id_ = 0;
+  ClientID last_client_id_ = 0;
+  uint32_t socket_tx_timeout_ms_ = kDefaultIpcTxTimeoutMs;
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+  base::WeakPtrFactory<HostImpl> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace ipc
+}  // namespace perfetto
+
+#endif  // SRC_IPC_HOST_IMPL_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/ipc/host_impl.h"
+
+#include <algorithm>
+#include <cinttypes>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
+
+// TODO(primiano): put limits on #connections/uid and req. queue (b/69093705).
+
+namespace perfetto {
+namespace ipc {
+
+namespace {
+
+constexpr base::SockFamily kHostSockFamily =
+    kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
+
+base::CrashKey g_crash_key_uid("ipc_uid");
+
+base::MachineID GenerateMachineID(base::UnixSocket* sock,
+                                  const std::string& machine_id_hint) {
+  // The special value of base::kDefaultMachineID is reserved for local
+  // producers.
+  if (!sock->is_connected() || sock->family() == base::SockFamily::kUnix)
+    return base::kDefaultMachineID;
+
+  base::Hasher hasher;
+  // Use the hint from the client, or fallback to hostname if the client
+  // doesn't provide a hint.
+  if (!machine_id_hint.empty()) {
+    hasher.Update(machine_id_hint);
+  } else {
+    // Use the socket address without the port number part as the hint.
+    auto host_id = sock->GetSockAddr();
+    auto pos = std::string::npos;
+    switch (sock->family()) {
+      case base::SockFamily::kInet:
+        PERFETTO_FALLTHROUGH;
+      case base::SockFamily::kInet6:
+        PERFETTO_FALLTHROUGH;
+      case base::SockFamily::kVsock:
+        pos = host_id.rfind(":");
+        if (pos != std::string::npos)
+          host_id.resize(pos);
+        break;
+      case base::SockFamily::kUnspec:
+        PERFETTO_FALLTHROUGH;
+      case base::SockFamily::kUnix:
+        PERFETTO_DFATAL("Should be unreachable.");
+        return base::kDefaultMachineID;
+    }
+    hasher.Update(host_id);
+  }
+
+  // Take the lower 32-bit from the hash.
+  uint32_t digest = static_cast<uint32_t>(hasher.digest());
+  // Avoid the extremely unlikely case that the hasher digest happens to be 0.
+  return digest == base::kDefaultMachineID ? 1 : digest;
+}
+}  // namespace
+
+uid_t HostImpl::ClientConnection::GetPosixPeerUid() const {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  if (sock->family() == base::SockFamily::kUnix)
+    return sock->peer_uid_posix();
+#endif
+
+  // For non-unix sockets, check if the UID is set in OnSetPeerIdentity().
+  if (uid_override != base::kInvalidUid)
+    return uid_override;
+  // Must be != kInvalidUid or the PacketValidator will fail.
+  return 0;
+}
+
+pid_t HostImpl::ClientConnection::GetLinuxPeerPid() const {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  if (sock->family() == base::SockFamily::kUnix)
+    return sock->peer_pid_linux();
+#endif
+
+  // For non-unix sockets, return the PID set in OnSetPeerIdentity().
+  return pid_override;
+}
+
+// static
+std::unique_ptr<Host> Host::CreateInstance(const char* socket_name,
+                                           base::TaskRunner* task_runner) {
+  std::unique_ptr<HostImpl> host(new HostImpl(socket_name, task_runner));
+  if (!host->sock() || !host->sock()->is_listening())
+    return nullptr;
+  return std::unique_ptr<Host>(std::move(host));
+}
+
+// static
+std::unique_ptr<Host> Host::CreateInstance(base::ScopedSocketHandle socket_fd,
+                                           base::TaskRunner* task_runner) {
+  std::unique_ptr<HostImpl> host(
+      new HostImpl(std::move(socket_fd), task_runner));
+  if (!host->sock() || !host->sock()->is_listening())
+    return nullptr;
+  return std::unique_ptr<Host>(std::move(host));
+}
+
+// static
+std::unique_ptr<Host> Host::CreateInstance_Fuchsia(
+    base::TaskRunner* task_runner) {
+  return std::unique_ptr<HostImpl>(new HostImpl(task_runner));
+}
+
+HostImpl::HostImpl(base::ScopedSocketHandle socket_fd,
+                   base::TaskRunner* task_runner)
+    : task_runner_(task_runner), weak_ptr_factory_(this) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  sock_ = base::UnixSocket::Listen(std::move(socket_fd), this, task_runner_,
+                                   kHostSockFamily, base::SockType::kStream);
+}
+
+HostImpl::HostImpl(const char* socket_name, base::TaskRunner* task_runner)
+    : task_runner_(task_runner), weak_ptr_factory_(this) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  sock_ = base::UnixSocket::Listen(socket_name, this, task_runner_,
+                                   base::GetSockFamily(socket_name),
+                                   base::SockType::kStream);
+  if (!sock_) {
+    PERFETTO_PLOG("Failed to create %s", socket_name);
+  }
+}
+
+HostImpl::HostImpl(base::TaskRunner* task_runner)
+    : task_runner_(task_runner), weak_ptr_factory_(this) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+}
+
+HostImpl::~HostImpl() = default;
+
+bool HostImpl::ExposeService(std::unique_ptr<Service> service) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  const std::string& service_name = service->GetDescriptor().service_name;
+  if (GetServiceByName(service_name)) {
+    PERFETTO_DLOG("Duplicate ExposeService(): %s", service_name.c_str());
+    return false;
+  }
+  service->use_shmem_emulation_ =
+      sock() && !base::SockShmemSupported(sock()->family());
+  ServiceID sid = ++last_service_id_;
+  ExposedService exposed_service(sid, service_name, std::move(service));
+  services_.emplace(sid, std::move(exposed_service));
+  return true;
+}
+
+void HostImpl::AdoptConnectedSocket_Fuchsia(
+    base::ScopedSocketHandle connected_socket,
+    std::function<bool(int)> send_fd_cb) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DCHECK(connected_socket);
+  // Should not be used in conjunction with listen sockets.
+  PERFETTO_DCHECK(!sock_);
+
+  auto unix_socket = base::UnixSocket::AdoptConnected(
+      std::move(connected_socket), this, task_runner_, kHostSockFamily,
+      base::SockType::kStream);
+
+  auto* unix_socket_ptr = unix_socket.get();
+  OnNewIncomingConnection(nullptr, std::move(unix_socket));
+  ClientConnection* client_connection = clients_by_socket_[unix_socket_ptr];
+  client_connection->send_fd_cb_fuchsia = std::move(send_fd_cb);
+  PERFETTO_DCHECK(client_connection->send_fd_cb_fuchsia);
+}
+
+void HostImpl::SetSocketSendTimeoutMs(uint32_t timeout_ms) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // Should be less than the watchdog period (30s).
+  socket_tx_timeout_ms_ = timeout_ms;
+}
+
+void HostImpl::OnNewIncomingConnection(
+    base::UnixSocket*,
+    std::unique_ptr<base::UnixSocket> new_conn) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  std::unique_ptr<ClientConnection> client(new ClientConnection());
+  ClientID client_id = ++last_client_id_;
+  clients_by_socket_[new_conn.get()] = client.get();
+  client->id = client_id;
+  client->sock = std::move(new_conn);
+  client->sock->SetTxTimeout(socket_tx_timeout_ms_);
+  clients_[client_id] = std::move(client);
+}
+
+void HostImpl::OnDataAvailable(base::UnixSocket* sock) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto it = clients_by_socket_.find(sock);
+  if (it == clients_by_socket_.end())
+    return;
+  ClientConnection* client = it->second;
+  BufferedFrameDeserializer& frame_deserializer = client->frame_deserializer;
+
+  auto peer_uid = client->GetPosixPeerUid();
+  auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
+
+  size_t rsize;
+  do {
+    auto buf = frame_deserializer.BeginReceive();
+    base::ScopedFile fd;
+    rsize = client->sock->Receive(buf.data, buf.size, &fd);
+    if (fd) {
+      PERFETTO_DCHECK(!client->received_fd);
+      client->received_fd = std::move(fd);
+    }
+    if (!frame_deserializer.EndReceive(rsize))
+      return OnDisconnect(client->sock.get());
+  } while (rsize > 0);
+
+  for (;;) {
+    std::unique_ptr<Frame> frame = frame_deserializer.PopNextFrame();
+    if (!frame)
+      break;
+    OnReceivedFrame(client, *frame);
+  }
+}
+
+void HostImpl::OnReceivedFrame(ClientConnection* client,
+                               const Frame& req_frame) {
+  if (req_frame.has_msg_bind_service())
+    return OnBindService(client, req_frame);
+  if (req_frame.has_msg_invoke_method())
+    return OnInvokeMethod(client, req_frame);
+  if (req_frame.has_set_peer_identity())
+    return OnSetPeerIdentity(client, req_frame);
+
+  PERFETTO_DLOG("Received invalid RPC frame from client %" PRIu64, client->id);
+  Frame reply_frame;
+  reply_frame.set_request_id(req_frame.request_id());
+  reply_frame.mutable_msg_request_error()->set_error("unknown request");
+  SendFrame(client, reply_frame);
+}
+
+void HostImpl::OnBindService(ClientConnection* client, const Frame& req_frame) {
+  // Binding a service doesn't do anything major. It just returns back the
+  // service id and its method map.
+  const Frame::BindService& req = req_frame.msg_bind_service();
+  Frame reply_frame;
+  reply_frame.set_request_id(req_frame.request_id());
+  auto* reply = reply_frame.mutable_msg_bind_service_reply();
+  const ExposedService* service = GetServiceByName(req.service_name());
+  if (service) {
+    reply->set_success(true);
+    reply->set_service_id(service->id);
+    uint32_t method_id = 1;  // method ids start at index 1.
+    for (const auto& desc_method : service->instance->GetDescriptor().methods) {
+      Frame::BindServiceReply::MethodInfo* method_info = reply->add_methods();
+      method_info->set_name(desc_method.name);
+      method_info->set_id(method_id++);
+    }
+  }
+  SendFrame(client, reply_frame);
+}
+
+void HostImpl::OnInvokeMethod(ClientConnection* client,
+                              const Frame& req_frame) {
+  const Frame::InvokeMethod& req = req_frame.msg_invoke_method();
+  Frame reply_frame;
+  RequestID request_id = req_frame.request_id();
+  reply_frame.set_request_id(request_id);
+  reply_frame.mutable_msg_invoke_method_reply()->set_success(false);
+  auto svc_it = services_.find(req.service_id());
+  if (svc_it == services_.end())
+    return SendFrame(client, reply_frame);  // |success| == false by default.
+
+  Service* service = svc_it->second.instance.get();
+  const ServiceDescriptor& svc = service->GetDescriptor();
+  const auto& methods = svc.methods;
+  const uint32_t method_id = req.method_id();
+  if (method_id == 0 || method_id > methods.size())
+    return SendFrame(client, reply_frame);
+
+  const ServiceDescriptor::Method& method = methods[method_id - 1];
+  std::unique_ptr<ProtoMessage> decoded_req_args(
+      method.request_proto_decoder(req.args_proto()));
+  if (!decoded_req_args)
+    return SendFrame(client, reply_frame);
+
+  Deferred<ProtoMessage> deferred_reply;
+  base::WeakPtr<HostImpl> host_weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  ClientID client_id = client->id;
+
+  if (!req.drop_reply()) {
+    deferred_reply.Bind([host_weak_ptr, client_id,
+                         request_id](AsyncResult<ProtoMessage> reply) {
+      if (!host_weak_ptr)
+        return;  // The reply came too late, the HostImpl has gone.
+      host_weak_ptr->ReplyToMethodInvocation(client_id, request_id,
+                                             std::move(reply));
+    });
+  }
+
+  auto peer_uid = client->GetPosixPeerUid();
+  auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
+  service->client_info_ = ClientInfo(
+      client->id, peer_uid, client->GetLinuxPeerPid(), client->GetMachineID());
+  service->received_fd_ = &client->received_fd;
+  method.invoker(service, *decoded_req_args, std::move(deferred_reply));
+  service->received_fd_ = nullptr;
+  service->client_info_ = ClientInfo();
+}
+
+void HostImpl::OnSetPeerIdentity(ClientConnection* client,
+                                 const Frame& req_frame) {
+  if (client->sock->family() == base::SockFamily::kUnix) {
+    PERFETTO_DLOG("SetPeerIdentity is ignored for unix socket connections.");
+    return;
+  }
+
+  // This is can only be set once by the relay service.
+  if (client->pid_override != base::kInvalidPid ||
+      client->uid_override != base::kInvalidUid) {
+    PERFETTO_DLOG("Already received SetPeerIdentity.");
+    return;
+  }
+
+  const auto& set_peer_identity = req_frame.set_peer_identity();
+  client->pid_override = set_peer_identity.pid();
+  client->uid_override = static_cast<uid_t>(set_peer_identity.uid());
+
+  client->machine_id = GenerateMachineID(client->sock.get(),
+                                         set_peer_identity.machine_id_hint());
+}
+
+void HostImpl::ReplyToMethodInvocation(ClientID client_id,
+                                       RequestID request_id,
+                                       AsyncResult<ProtoMessage> reply) {
+  auto client_iter = clients_.find(client_id);
+  if (client_iter == clients_.end())
+    return;  // client has disconnected by the time we got the async reply.
+
+  ClientConnection* client = client_iter->second.get();
+  Frame reply_frame;
+  reply_frame.set_request_id(request_id);
+
+  // TODO(fmayer): add a test to guarantee that the reply is consumed within the
+  // same call stack and not kept around. ConsumerIPCService::OnTraceData()
+  // relies on this behavior.
+  auto* reply_frame_data = reply_frame.mutable_msg_invoke_method_reply();
+  reply_frame_data->set_has_more(reply.has_more());
+  if (reply.success()) {
+    std::string reply_proto = reply->SerializeAsString();
+    reply_frame_data->set_reply_proto(reply_proto);
+    reply_frame_data->set_success(true);
+  }
+  SendFrame(client, reply_frame, reply.fd());
+}
+
+// static
+void HostImpl::SendFrame(ClientConnection* client, const Frame& frame, int fd) {
+  auto peer_uid = client->GetPosixPeerUid();
+  auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
+
+  std::string buf = BufferedFrameDeserializer::Serialize(frame);
+
+  // On Fuchsia, |send_fd_cb_fuchsia_| is used to send the FD to the client
+  // and therefore must be set.
+  PERFETTO_DCHECK(!PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) ||
+                  client->send_fd_cb_fuchsia);
+  if (client->send_fd_cb_fuchsia && fd != base::ScopedFile::kInvalid) {
+    if (!client->send_fd_cb_fuchsia(fd)) {
+      client->sock->Shutdown(true);
+      return;
+    }
+    fd = base::ScopedFile::kInvalid;
+  }
+
+  // When a new Client connects in OnNewClientConnection we set a timeout on
+  // Send (see call to SetTxTimeout).
+  //
+  // The old behaviour was to do a blocking I/O call, which caused crashes from
+  // misbehaving producers (see b/169051440).
+  bool res = client->sock->Send(buf.data(), buf.size(), fd);
+  // If we timeout |res| will be false, but the UnixSocket will have called
+  // UnixSocket::ShutDown() and thus |is_connected()| is false.
+  PERFETTO_CHECK(res || !client->sock->is_connected());
+}
+
+void HostImpl::OnDisconnect(base::UnixSocket* sock) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  auto it = clients_by_socket_.find(sock);
+  if (it == clients_by_socket_.end())
+    return;
+  auto* client = it->second;
+  ClientID client_id = client->id;
+
+  ClientInfo client_info(client_id, client->GetPosixPeerUid(),
+                         client->GetLinuxPeerPid(), client->GetMachineID());
+
+  clients_by_socket_.erase(it);
+  PERFETTO_DCHECK(clients_.count(client_id));
+  clients_.erase(client_id);
+
+  for (const auto& service_it : services_) {
+    Service& service = *service_it.second.instance;
+    service.client_info_ = client_info;
+    service.OnClientDisconnected();
+    service.client_info_ = ClientInfo();
+  }
+}
+
+const HostImpl::ExposedService* HostImpl::GetServiceByName(
+    const std::string& name) {
+  // This could be optimized by using another map<name,ServiceID>. However this
+  // is used only by Bind/ExposeService that are quite rare (once per client
+  // connection and once per service instance), not worth it.
+  for (const auto& it : services_) {
+    if (it.second.name == name)
+      return &it.second;
+  }
+  return nullptr;
+}
+
+HostImpl::ExposedService::ExposedService(ServiceID id_,
+                                         const std::string& name_,
+                                         std::unique_ptr<Service> instance_)
+    : id(id_), name(name_), instance(std::move(instance_)) {}
+
+HostImpl::ExposedService::ExposedService(ExposedService&&) noexcept = default;
+HostImpl::ExposedService& HostImpl::ExposedService::operator=(
+    HostImpl::ExposedService&&) = default;
+HostImpl::ExposedService::~ExposedService() = default;
+
+HostImpl::ClientConnection::~ClientConnection() = default;
+
+}  // namespace ipc
+}  // namespace perfetto
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.ipc.cc
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.ipc.h
+// DO NOT EDIT. Autogenerated by Perfetto IPC
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class ConsumerPort : public ::perfetto::ipc::Service {
+ private:
+  static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
+
+ public:
+  ~ConsumerPort() override;
+
+  static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
+
+  // Service implementation.
+  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
+
+  // Methods from the .proto file
+  using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
+  virtual void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse) = 0;
+
+  using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
+  virtual void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse) = 0;
+
+  using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
+  virtual void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse) = 0;
+
+  using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
+  virtual void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse) = 0;
+
+  using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
+  virtual void Flush(const FlushRequest&, DeferredFlushResponse) = 0;
+
+  using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
+  virtual void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse) = 0;
+
+  using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
+  virtual void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse) = 0;
+
+  using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
+  virtual void Detach(const DetachRequest&, DeferredDetachResponse) = 0;
+
+  using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
+  virtual void Attach(const AttachRequest&, DeferredAttachResponse) = 0;
+
+  using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
+  virtual void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse) = 0;
+
+  using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
+  virtual void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse) = 0;
+
+  using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
+  virtual void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse) = 0;
+
+  using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
+  virtual void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse) = 0;
+
+  using DeferredSaveTraceForBugreportResponse = ::perfetto::ipc::Deferred<SaveTraceForBugreportResponse>;
+  virtual void SaveTraceForBugreport(const SaveTraceForBugreportRequest&, DeferredSaveTraceForBugreportResponse) = 0;
+
+  using DeferredCloneSessionResponse = ::perfetto::ipc::Deferred<CloneSessionResponse>;
+  virtual void CloneSession(const CloneSessionRequest&, DeferredCloneSessionResponse) = 0;
+
+};
+
+
+class ConsumerPortProxy : public ::perfetto::ipc::ServiceProxy {
+ public:
+   explicit ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
+   ~ConsumerPortProxy() override;
+
+  // ServiceProxy implementation.
+  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
+
+  // Methods from the .proto file
+  using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
+  void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse, int fd = -1);
+
+  using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
+  void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse, int fd = -1);
+
+  using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
+  void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse, int fd = -1);
+
+  using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
+  void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse, int fd = -1);
+
+  using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
+  void Flush(const FlushRequest&, DeferredFlushResponse, int fd = -1);
+
+  using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
+  void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse, int fd = -1);
+
+  using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
+  void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse, int fd = -1);
+
+  using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
+  void Detach(const DetachRequest&, DeferredDetachResponse, int fd = -1);
+
+  using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
+  void Attach(const AttachRequest&, DeferredAttachResponse, int fd = -1);
+
+  using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
+  void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse, int fd = -1);
+
+  using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
+  void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse, int fd = -1);
+
+  using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
+  void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse, int fd = -1);
+
+  using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
+  void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse, int fd = -1);
+
+  using DeferredSaveTraceForBugreportResponse = ::perfetto::ipc::Deferred<SaveTraceForBugreportResponse>;
+  void SaveTraceForBugreport(const SaveTraceForBugreportRequest&, DeferredSaveTraceForBugreportResponse, int fd = -1);
+
+  using DeferredCloneSessionResponse = ::perfetto::ipc::Deferred<CloneSessionResponse>;
+  void CloneSession(const CloneSessionRequest&, DeferredCloneSessionResponse, int fd = -1);
+
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
+// gen_amalgamated begin header: include/perfetto/ext/ipc/codegen_helpers.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// This file is only meant to be included in autogenerated .cc files.
+
+#ifndef INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
+#define INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+
+// A templated protobuf message decoder. Returns nullptr in case of failure.
+template <typename T>
+::std::unique_ptr<::perfetto::ipc::ProtoMessage> _IPC_Decoder(
+    const std::string& proto_data) {
+  ::std::unique_ptr<::perfetto::ipc::ProtoMessage> msg(new T());
+  if (msg->ParseFromString(proto_data))
+    return msg;
+  return nullptr;
+}
+
+// Templated method dispatcher. Used to obtain a function pointer to a given
+// IPC method (Method) of a given service (TSvc) that can be invoked by the
+// host-side machinery starting from a generic Service pointer and a generic
+// ProtoMessage request argument.
+template <typename TSvc,    // Type of the actual Service subclass.
+          typename TReq,    // Type of the request argument.
+          typename TReply,  // Type of the reply argument.
+          void (TSvc::*Method)(const TReq&, ::perfetto::ipc::Deferred<TReply>)>
+void _IPC_Invoker(::perfetto::ipc::Service* s,
+                  const ::perfetto::ipc::ProtoMessage& req,
+                  ::perfetto::ipc::DeferredBase reply) {
+  (*static_cast<TSvc*>(s).*Method)(
+      static_cast<const TReq&>(req),
+      ::perfetto::ipc::Deferred<TReply>(::std::move(reply)));
+}
+
+#endif  // INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
+// DO NOT EDIT. Autogenerated by Perfetto IPC
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
+
+#include <memory>
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+::perfetto::ipc::ServiceDescriptor* ConsumerPort::NewDescriptor() {
+  auto* desc = new ::perfetto::ipc::ServiceDescriptor();
+  desc->service_name = "ConsumerPort";
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "EnableTracing",
+     &_IPC_Decoder<EnableTracingRequest>,
+     &_IPC_Decoder<EnableTracingResponse>,
+     &_IPC_Invoker<ConsumerPort, EnableTracingRequest, EnableTracingResponse, &ConsumerPort::EnableTracing>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "DisableTracing",
+     &_IPC_Decoder<DisableTracingRequest>,
+     &_IPC_Decoder<DisableTracingResponse>,
+     &_IPC_Invoker<ConsumerPort, DisableTracingRequest, DisableTracingResponse, &ConsumerPort::DisableTracing>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "ReadBuffers",
+     &_IPC_Decoder<ReadBuffersRequest>,
+     &_IPC_Decoder<ReadBuffersResponse>,
+     &_IPC_Invoker<ConsumerPort, ReadBuffersRequest, ReadBuffersResponse, &ConsumerPort::ReadBuffers>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "FreeBuffers",
+     &_IPC_Decoder<FreeBuffersRequest>,
+     &_IPC_Decoder<FreeBuffersResponse>,
+     &_IPC_Invoker<ConsumerPort, FreeBuffersRequest, FreeBuffersResponse, &ConsumerPort::FreeBuffers>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "Flush",
+     &_IPC_Decoder<FlushRequest>,
+     &_IPC_Decoder<FlushResponse>,
+     &_IPC_Invoker<ConsumerPort, FlushRequest, FlushResponse, &ConsumerPort::Flush>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "StartTracing",
+     &_IPC_Decoder<StartTracingRequest>,
+     &_IPC_Decoder<StartTracingResponse>,
+     &_IPC_Invoker<ConsumerPort, StartTracingRequest, StartTracingResponse, &ConsumerPort::StartTracing>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "ChangeTraceConfig",
+     &_IPC_Decoder<ChangeTraceConfigRequest>,
+     &_IPC_Decoder<ChangeTraceConfigResponse>,
+     &_IPC_Invoker<ConsumerPort, ChangeTraceConfigRequest, ChangeTraceConfigResponse, &ConsumerPort::ChangeTraceConfig>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "Detach",
+     &_IPC_Decoder<DetachRequest>,
+     &_IPC_Decoder<DetachResponse>,
+     &_IPC_Invoker<ConsumerPort, DetachRequest, DetachResponse, &ConsumerPort::Detach>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "Attach",
+     &_IPC_Decoder<AttachRequest>,
+     &_IPC_Decoder<AttachResponse>,
+     &_IPC_Invoker<ConsumerPort, AttachRequest, AttachResponse, &ConsumerPort::Attach>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "GetTraceStats",
+     &_IPC_Decoder<GetTraceStatsRequest>,
+     &_IPC_Decoder<GetTraceStatsResponse>,
+     &_IPC_Invoker<ConsumerPort, GetTraceStatsRequest, GetTraceStatsResponse, &ConsumerPort::GetTraceStats>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "ObserveEvents",
+     &_IPC_Decoder<ObserveEventsRequest>,
+     &_IPC_Decoder<ObserveEventsResponse>,
+     &_IPC_Invoker<ConsumerPort, ObserveEventsRequest, ObserveEventsResponse, &ConsumerPort::ObserveEvents>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "QueryServiceState",
+     &_IPC_Decoder<QueryServiceStateRequest>,
+     &_IPC_Decoder<QueryServiceStateResponse>,
+     &_IPC_Invoker<ConsumerPort, QueryServiceStateRequest, QueryServiceStateResponse, &ConsumerPort::QueryServiceState>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "QueryCapabilities",
+     &_IPC_Decoder<QueryCapabilitiesRequest>,
+     &_IPC_Decoder<QueryCapabilitiesResponse>,
+     &_IPC_Invoker<ConsumerPort, QueryCapabilitiesRequest, QueryCapabilitiesResponse, &ConsumerPort::QueryCapabilities>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "SaveTraceForBugreport",
+     &_IPC_Decoder<SaveTraceForBugreportRequest>,
+     &_IPC_Decoder<SaveTraceForBugreportResponse>,
+     &_IPC_Invoker<ConsumerPort, SaveTraceForBugreportRequest, SaveTraceForBugreportResponse, &ConsumerPort::SaveTraceForBugreport>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "CloneSession",
+     &_IPC_Decoder<CloneSessionRequest>,
+     &_IPC_Decoder<CloneSessionResponse>,
+     &_IPC_Invoker<ConsumerPort, CloneSessionRequest, CloneSessionResponse, &ConsumerPort::CloneSession>});
+  desc->methods.shrink_to_fit();
+  return desc;
+}
+
+
+const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptorStatic() {
+  static auto* instance = NewDescriptor();
+  return *instance;
+}
+
+// Host-side definitions.
+ConsumerPort::~ConsumerPort() = default;
+
+const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptor() {
+  return GetDescriptorStatic();
+}
+
+// Client-side definitions.
+ConsumerPortProxy::ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
+    : ::perfetto::ipc::ServiceProxy(event_listener) {}
+
+ConsumerPortProxy::~ConsumerPortProxy() = default;
+
+const ::perfetto::ipc::ServiceDescriptor& ConsumerPortProxy::GetDescriptor() {
+  return ConsumerPort::GetDescriptorStatic();
+}
+
+void ConsumerPortProxy::EnableTracing(const EnableTracingRequest& request, DeferredEnableTracingResponse reply, int fd) {
+  BeginInvoke("EnableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::DisableTracing(const DisableTracingRequest& request, DeferredDisableTracingResponse reply, int fd) {
+  BeginInvoke("DisableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::ReadBuffers(const ReadBuffersRequest& request, DeferredReadBuffersResponse reply, int fd) {
+  BeginInvoke("ReadBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::FreeBuffers(const FreeBuffersRequest& request, DeferredFreeBuffersResponse reply, int fd) {
+  BeginInvoke("FreeBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::Flush(const FlushRequest& request, DeferredFlushResponse reply, int fd) {
+  BeginInvoke("Flush", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::StartTracing(const StartTracingRequest& request, DeferredStartTracingResponse reply, int fd) {
+  BeginInvoke("StartTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::ChangeTraceConfig(const ChangeTraceConfigRequest& request, DeferredChangeTraceConfigResponse reply, int fd) {
+  BeginInvoke("ChangeTraceConfig", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::Detach(const DetachRequest& request, DeferredDetachResponse reply, int fd) {
+  BeginInvoke("Detach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::Attach(const AttachRequest& request, DeferredAttachResponse reply, int fd) {
+  BeginInvoke("Attach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::GetTraceStats(const GetTraceStatsRequest& request, DeferredGetTraceStatsResponse reply, int fd) {
+  BeginInvoke("GetTraceStats", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::ObserveEvents(const ObserveEventsRequest& request, DeferredObserveEventsResponse reply, int fd) {
+  BeginInvoke("ObserveEvents", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::QueryServiceState(const QueryServiceStateRequest& request, DeferredQueryServiceStateResponse reply, int fd) {
+  BeginInvoke("QueryServiceState", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::QueryCapabilities(const QueryCapabilitiesRequest& request, DeferredQueryCapabilitiesResponse reply, int fd) {
+  BeginInvoke("QueryCapabilities", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::SaveTraceForBugreport(const SaveTraceForBugreportRequest& request, DeferredSaveTraceForBugreportResponse reply, int fd) {
+  BeginInvoke("SaveTraceForBugreport", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ConsumerPortProxy::CloneSession(const CloneSessionRequest& request, DeferredCloneSessionResponse reply, int fd) {
+  BeginInvoke("CloneSession", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+// gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.ipc.cc
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.ipc.h
+// DO NOT EDIT. Autogenerated by Perfetto IPC
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
+
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class ProducerPort : public ::perfetto::ipc::Service {
+ private:
+  static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
+
+ public:
+  ~ProducerPort() override;
+
+  static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
+
+  // Service implementation.
+  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
+
+  // Methods from the .proto file
+  using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
+  virtual void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse) = 0;
+
+  using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
+  virtual void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse) = 0;
+
+  using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
+  virtual void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse) = 0;
+
+  using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
+  virtual void CommitData(const CommitDataRequest&, DeferredCommitDataResponse) = 0;
+
+  using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
+  virtual void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse) = 0;
+
+  using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
+  virtual void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse) = 0;
+
+  using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
+  virtual void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse) = 0;
+
+  using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
+  virtual void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse) = 0;
+
+  using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
+  virtual void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse) = 0;
+
+  using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
+  virtual void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse) = 0;
+
+  using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
+  virtual void Sync(const SyncRequest&, DeferredSyncResponse) = 0;
+
+  using DeferredUpdateDataSourceResponse = ::perfetto::ipc::Deferred<UpdateDataSourceResponse>;
+  virtual void UpdateDataSource(const UpdateDataSourceRequest&, DeferredUpdateDataSourceResponse) = 0;
+
+};
+
+
+class ProducerPortProxy : public ::perfetto::ipc::ServiceProxy {
+ public:
+   explicit ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
+   ~ProducerPortProxy() override;
+
+  // ServiceProxy implementation.
+  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
+
+  // Methods from the .proto file
+  using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
+  void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse, int fd = -1);
+
+  using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
+  void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse, int fd = -1);
+
+  using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
+  void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse, int fd = -1);
+
+  using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
+  void CommitData(const CommitDataRequest&, DeferredCommitDataResponse, int fd = -1);
+
+  using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
+  void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse, int fd = -1);
+
+  using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
+  void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse, int fd = -1);
+
+  using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
+  void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse, int fd = -1);
+
+  using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
+  void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse, int fd = -1);
+
+  using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
+  void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse, int fd = -1);
+
+  using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
+  void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse, int fd = -1);
+
+  using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
+  void Sync(const SyncRequest&, DeferredSyncResponse, int fd = -1);
+
+  using DeferredUpdateDataSourceResponse = ::perfetto::ipc::Deferred<UpdateDataSourceResponse>;
+  void UpdateDataSource(const UpdateDataSourceRequest&, DeferredUpdateDataSourceResponse, int fd = -1);
+
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
+// DO NOT EDIT. Autogenerated by Perfetto IPC
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
+
+#include <memory>
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+::perfetto::ipc::ServiceDescriptor* ProducerPort::NewDescriptor() {
+  auto* desc = new ::perfetto::ipc::ServiceDescriptor();
+  desc->service_name = "ProducerPort";
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "InitializeConnection",
+     &_IPC_Decoder<InitializeConnectionRequest>,
+     &_IPC_Decoder<InitializeConnectionResponse>,
+     &_IPC_Invoker<ProducerPort, InitializeConnectionRequest, InitializeConnectionResponse, &ProducerPort::InitializeConnection>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "RegisterDataSource",
+     &_IPC_Decoder<RegisterDataSourceRequest>,
+     &_IPC_Decoder<RegisterDataSourceResponse>,
+     &_IPC_Invoker<ProducerPort, RegisterDataSourceRequest, RegisterDataSourceResponse, &ProducerPort::RegisterDataSource>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "UnregisterDataSource",
+     &_IPC_Decoder<UnregisterDataSourceRequest>,
+     &_IPC_Decoder<UnregisterDataSourceResponse>,
+     &_IPC_Invoker<ProducerPort, UnregisterDataSourceRequest, UnregisterDataSourceResponse, &ProducerPort::UnregisterDataSource>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "CommitData",
+     &_IPC_Decoder<CommitDataRequest>,
+     &_IPC_Decoder<CommitDataResponse>,
+     &_IPC_Invoker<ProducerPort, CommitDataRequest, CommitDataResponse, &ProducerPort::CommitData>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "GetAsyncCommand",
+     &_IPC_Decoder<GetAsyncCommandRequest>,
+     &_IPC_Decoder<GetAsyncCommandResponse>,
+     &_IPC_Invoker<ProducerPort, GetAsyncCommandRequest, GetAsyncCommandResponse, &ProducerPort::GetAsyncCommand>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "RegisterTraceWriter",
+     &_IPC_Decoder<RegisterTraceWriterRequest>,
+     &_IPC_Decoder<RegisterTraceWriterResponse>,
+     &_IPC_Invoker<ProducerPort, RegisterTraceWriterRequest, RegisterTraceWriterResponse, &ProducerPort::RegisterTraceWriter>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "UnregisterTraceWriter",
+     &_IPC_Decoder<UnregisterTraceWriterRequest>,
+     &_IPC_Decoder<UnregisterTraceWriterResponse>,
+     &_IPC_Invoker<ProducerPort, UnregisterTraceWriterRequest, UnregisterTraceWriterResponse, &ProducerPort::UnregisterTraceWriter>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "NotifyDataSourceStarted",
+     &_IPC_Decoder<NotifyDataSourceStartedRequest>,
+     &_IPC_Decoder<NotifyDataSourceStartedResponse>,
+     &_IPC_Invoker<ProducerPort, NotifyDataSourceStartedRequest, NotifyDataSourceStartedResponse, &ProducerPort::NotifyDataSourceStarted>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "NotifyDataSourceStopped",
+     &_IPC_Decoder<NotifyDataSourceStoppedRequest>,
+     &_IPC_Decoder<NotifyDataSourceStoppedResponse>,
+     &_IPC_Invoker<ProducerPort, NotifyDataSourceStoppedRequest, NotifyDataSourceStoppedResponse, &ProducerPort::NotifyDataSourceStopped>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "ActivateTriggers",
+     &_IPC_Decoder<ActivateTriggersRequest>,
+     &_IPC_Decoder<ActivateTriggersResponse>,
+     &_IPC_Invoker<ProducerPort, ActivateTriggersRequest, ActivateTriggersResponse, &ProducerPort::ActivateTriggers>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "Sync",
+     &_IPC_Decoder<SyncRequest>,
+     &_IPC_Decoder<SyncResponse>,
+     &_IPC_Invoker<ProducerPort, SyncRequest, SyncResponse, &ProducerPort::Sync>});
+
+  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
+     "UpdateDataSource",
+     &_IPC_Decoder<UpdateDataSourceRequest>,
+     &_IPC_Decoder<UpdateDataSourceResponse>,
+     &_IPC_Invoker<ProducerPort, UpdateDataSourceRequest, UpdateDataSourceResponse, &ProducerPort::UpdateDataSource>});
+  desc->methods.shrink_to_fit();
+  return desc;
+}
+
+
+const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptorStatic() {
+  static auto* instance = NewDescriptor();
+  return *instance;
+}
+
+// Host-side definitions.
+ProducerPort::~ProducerPort() = default;
+
+const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptor() {
+  return GetDescriptorStatic();
+}
+
+// Client-side definitions.
+ProducerPortProxy::ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
+    : ::perfetto::ipc::ServiceProxy(event_listener) {}
+
+ProducerPortProxy::~ProducerPortProxy() = default;
+
+const ::perfetto::ipc::ServiceDescriptor& ProducerPortProxy::GetDescriptor() {
+  return ProducerPort::GetDescriptorStatic();
+}
+
+void ProducerPortProxy::InitializeConnection(const InitializeConnectionRequest& request, DeferredInitializeConnectionResponse reply, int fd) {
+  BeginInvoke("InitializeConnection", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::RegisterDataSource(const RegisterDataSourceRequest& request, DeferredRegisterDataSourceResponse reply, int fd) {
+  BeginInvoke("RegisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::UnregisterDataSource(const UnregisterDataSourceRequest& request, DeferredUnregisterDataSourceResponse reply, int fd) {
+  BeginInvoke("UnregisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::CommitData(const CommitDataRequest& request, DeferredCommitDataResponse reply, int fd) {
+  BeginInvoke("CommitData", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::GetAsyncCommand(const GetAsyncCommandRequest& request, DeferredGetAsyncCommandResponse reply, int fd) {
+  BeginInvoke("GetAsyncCommand", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::RegisterTraceWriter(const RegisterTraceWriterRequest& request, DeferredRegisterTraceWriterResponse reply, int fd) {
+  BeginInvoke("RegisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::UnregisterTraceWriter(const UnregisterTraceWriterRequest& request, DeferredUnregisterTraceWriterResponse reply, int fd) {
+  BeginInvoke("UnregisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::NotifyDataSourceStarted(const NotifyDataSourceStartedRequest& request, DeferredNotifyDataSourceStartedResponse reply, int fd) {
+  BeginInvoke("NotifyDataSourceStarted", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest& request, DeferredNotifyDataSourceStoppedResponse reply, int fd) {
+  BeginInvoke("NotifyDataSourceStopped", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::ActivateTriggers(const ActivateTriggersRequest& request, DeferredActivateTriggersResponse reply, int fd) {
+  BeginInvoke("ActivateTriggers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::Sync(const SyncRequest& request, DeferredSyncResponse reply, int fd) {
+  BeginInvoke("Sync", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+
+void ProducerPortProxy::UpdateDataSource(const UpdateDataSourceRequest& request, DeferredUpdateDataSourceResponse reply, int fd) {
+  BeginInvoke("UpdateDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
+              fd);
+}
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+// gen_amalgamated begin source: src/tracing/ipc/default_socket.cc
+/*
+ * Copyright (C) 2018 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/default_socket.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+
+#include <stdlib.h>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace {
+
+const char* kRunPerfettoBaseDir = "/run/perfetto/";
+
+// On Linux and CrOS, check /run/perfetto/ before using /tmp/ as the socket
+// base directory.
+bool UseRunPerfettoBaseDir() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
+  // Note that the trailing / in |kRunPerfettoBaseDir| ensures we are checking
+  // against a directory, not a file.
+  int res = PERFETTO_EINTR(access(kRunPerfettoBaseDir, X_OK));
+  if (!res)
+    return true;
+
+  // If the path doesn't exist (ENOENT), fail silently to the caller. Otherwise,
+  // fail with an explicit error message.
+  if (errno != ENOENT
+#if PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
+      // access(2) won't return EPERM, but Chromium sandbox returns EPERM if the
+      // sandbox doesn't allow the call (e.g. in the child processes).
+      && errno != EPERM
+#endif
+  ) {
+    PERFETTO_PLOG("%s exists but cannot be accessed. Falling back on /tmp/ ",
+                  kRunPerfettoBaseDir);
+  }
+  return false;
+#else
+  base::ignore_result(kRunPerfettoBaseDir);
+  return false;
+#endif
+}
+
+}  // anonymous namespace
+
+const char* GetProducerSocket() {
+  const char* name = getenv("PERFETTO_PRODUCER_SOCK_NAME");
+  if (name == nullptr) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    name = "127.0.0.1:32278";
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+    name = "/dev/socket/traced_producer";
+#else
+    // Use /run/perfetto if it exists. Then fallback to /tmp.
+    static const char* producer_socket =
+        UseRunPerfettoBaseDir() ? "/run/perfetto/traced-producer.sock"
+                                : "/tmp/perfetto-producer";
+    name = producer_socket;
+#endif
+  }
+  base::ignore_result(UseRunPerfettoBaseDir);  // Silence unused func warnings.
+  return name;
+}
+
+const char* GetRelaySocket() {
+  // The relay socket is optional and is connected only when the env var is set.
+  return getenv("PERFETTO_RELAY_SOCK_NAME");
+}
+
+std::vector<std::string> TokenizeProducerSockets(
+    const char* producer_socket_names) {
+  return base::SplitString(producer_socket_names, ",");
+}
+
+const char* GetConsumerSocket() {
+  const char* name = getenv("PERFETTO_CONSUMER_SOCK_NAME");
+  if (name == nullptr) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    name = "127.0.0.1:32279";
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+    name = "/dev/socket/traced_consumer";
+#else
+    // Use /run/perfetto if it exists. Then fallback to /tmp.
+    static const char* consumer_socket =
+        UseRunPerfettoBaseDir() ? "/run/perfetto/traced-consumer.sock"
+                                : "/tmp/perfetto-consumer";
+    name = consumer_socket;
+#endif
+  }
+  return name;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/memfd.cc
+// gen_amalgamated begin header: src/tracing/ipc/memfd.h
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef SRC_TRACING_IPC_MEMFD_H_
+#define SRC_TRACING_IPC_MEMFD_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+
+// Some android build bots use a sysroot that doesn't support memfd when
+// compiling for the host, so we define the flags we need ourselves.
+
+// from memfd.h
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC 0x0001U
+#define MFD_ALLOW_SEALING 0x0002U
+#endif
+
+// from fcntl.h
+#ifndef F_ADD_SEALS
+#define F_ADD_SEALS 1033
+#define F_GET_SEALS 1034
+#define F_SEAL_SEAL 0x0001
+#define F_SEAL_SHRINK 0x0002
+#define F_SEAL_GROW 0x0004
+#define F_SEAL_WRITE 0x0008
+#endif
+
+namespace perfetto {
+
+// Whether the operating system supports memfd.
+bool HasMemfdSupport();
+
+// Call memfd(2) if available on platform and return the fd as result. This call
+// also makes a kernel version check for safety on older kernels (b/116769556).
+// Returns an invalid ScopedFile on failure.
+base::ScopedFile CreateMemfd(const char* name, unsigned int flags);
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_MEMFD_H_
+/*
+ * Copyright (C) 2020 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"
+
+#include <errno.h>
+
+#define PERFETTO_MEMFD_ENABLED()             \
+  PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+      PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
+
+#if PERFETTO_MEMFD_ENABLED()
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/syscall.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+
+// Some android build bots use a sysroot that doesn't support memfd when
+// compiling for the host, so we redefine it if necessary.
+#if !defined(__NR_memfd_create)
+#if defined(__x86_64__)
+#define __NR_memfd_create 319
+#elif defined(__i386__)
+#define __NR_memfd_create 356
+#elif defined(__aarch64__)
+#define __NR_memfd_create 279
+#elif defined(__arm__)
+#define __NR_memfd_create 385
+#else
+#error "unsupported sysroot without memfd support"
+#endif
+#endif  // !defined(__NR_memfd_create)
+
+namespace perfetto {
+bool HasMemfdSupport() {
+  static bool kSupportsMemfd = [] {
+    // Check kernel version supports memfd_create(). Some older kernels segfault
+    // executing memfd_create() rather than returning ENOSYS (b/116769556).
+    static constexpr int kRequiredMajor = 3;
+    static constexpr int kRequiredMinor = 17;
+    struct utsname uts;
+    int major, minor;
+    if (uname(&uts) == 0 && strcmp(uts.sysname, "Linux") == 0 &&
+        sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
+        ((major < kRequiredMajor ||
+          (major == kRequiredMajor && minor < kRequiredMinor)))) {
+      return false;
+    }
+
+    base::ScopedFile fd;
+    fd.reset(static_cast<int>(syscall(__NR_memfd_create, "perfetto_shmem",
+                                      MFD_CLOEXEC | MFD_ALLOW_SEALING)));
+    return !!fd;
+  }();
+  return kSupportsMemfd;
+}
+
+base::ScopedFile CreateMemfd(const char* name, unsigned int flags) {
+  if (!HasMemfdSupport()) {
+    errno = ENOSYS;
+    return base::ScopedFile();
+  }
+  return base::ScopedFile(
+      static_cast<int>(syscall(__NR_memfd_create, name, flags)));
+}
+}  // namespace perfetto
+
+#else  // PERFETTO_MEMFD_ENABLED()
+
+namespace perfetto {
+bool HasMemfdSupport() {
+  return false;
+}
+base::ScopedFile CreateMemfd(const char*, unsigned int) {
+  errno = ENOSYS;
+  return base::ScopedFile();
+}
+}  // namespace perfetto
+
+#endif  // PERFETTO_MEMFD_ENABLED()
+// gen_amalgamated begin source: src/tracing/ipc/posix_shared_memory.cc
+// gen_amalgamated begin header: src/tracing/ipc/posix_shared_memory.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
+#define SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+
+#include <stddef.h>
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+
+namespace perfetto {
+
+// Implements the SharedMemory and its factory for the posix-based transport.
+class PosixSharedMemory : public SharedMemory {
+ public:
+  class Factory : public SharedMemory::Factory {
+   public:
+    ~Factory() override;
+    std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
+  };
+
+  // Create a brand new SHM region.
+  static std::unique_ptr<PosixSharedMemory> Create(size_t size);
+
+  // Mmaps a file descriptor to an existing SHM region. If
+  // |require_seals_if_supported| is true and the system supports
+  // memfd_create(), the FD is required to be a sealed memfd with F_SEAL_SEAL,
+  // F_SEAL_GROW, and F_SEAL_SHRINK seals set (otherwise, nullptr is returned).
+  // May also return nullptr if mapping fails for another reason (e.g. OOM).
+  static std::unique_ptr<PosixSharedMemory> AttachToFd(
+      base::ScopedFile,
+      bool require_seals_if_supported = true);
+
+  ~PosixSharedMemory() override;
+
+  int fd() const { return fd_.get(); }
+
+  // SharedMemory implementation.
+  void* start() const override { return start_; }
+  size_t size() const override { return size_; }
+
+ private:
+  static std::unique_ptr<PosixSharedMemory> MapFD(base::ScopedFile, size_t);
+
+  PosixSharedMemory(void* start, size_t size, base::ScopedFile);
+  PosixSharedMemory(const PosixSharedMemory&) = delete;
+  PosixSharedMemory& operator=(const PosixSharedMemory&) = delete;
+
+  void* const start_;
+  const size_t size_;
+  base::ScopedFile fd_;
+};
+
+}  // namespace perfetto
+
+#endif  // OS_LINUX || OS_ANDROID || OS_APPLE
+#endif  // SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <memory>
+#include <utility>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
+// gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"
+
+namespace perfetto {
+
+namespace {
+int kFileSeals = F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL;
+}  // namespace
+
+// static
+std::unique_ptr<PosixSharedMemory> PosixSharedMemory::Create(size_t size) {
+  base::ScopedFile fd =
+      CreateMemfd("perfetto_shmem", MFD_CLOEXEC | MFD_ALLOW_SEALING);
+  bool is_memfd = !!fd;
+
+  // In-tree builds only allow mem_fd, so we can inspect the seals to verify the
+  // fd is appropriately sealed. We'll crash in the PERFETTO_CHECK(fd) below if
+  // memfd_create failed.
+#if !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+  if (!fd) {
+    // TODO: if this fails on Android we should fall back on ashmem.
+    PERFETTO_DPLOG("memfd_create() failed");
+    fd = base::TempFile::CreateUnlinked().ReleaseFD();
+  }
+#endif
+
+  PERFETTO_CHECK(fd);
+  int res = ftruncate(fd.get(), static_cast<off_t>(size));
+  PERFETTO_CHECK(res == 0);
+
+  if (is_memfd) {
+    // When memfd is supported, file seals should be, too.
+    res = fcntl(*fd, F_ADD_SEALS, kFileSeals);
+    PERFETTO_DCHECK(res == 0);
+  }
+
+  return MapFD(std::move(fd), size);
+}
+
+// static
+std::unique_ptr<PosixSharedMemory> PosixSharedMemory::AttachToFd(
+    base::ScopedFile fd,
+    bool require_seals_if_supported) {
+  bool requires_seals = require_seals_if_supported;
+
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+  // In-tree kernels all support memfd.
+  PERFETTO_CHECK(HasMemfdSupport());
+#else
+  // In out-of-tree builds, we only require seals if the kernel supports memfd.
+  if (requires_seals)
+    requires_seals = HasMemfdSupport();
+#endif
+
+  if (requires_seals) {
+    // If the system supports memfd, we require a sealed memfd.
+    int res = fcntl(*fd, F_GET_SEALS);
+    if (res == -1 || (res & kFileSeals) != kFileSeals) {
+      PERFETTO_PLOG("Couldn't verify file seals on shmem FD");
+      return nullptr;
+    }
+  }
+
+  struct stat stat_buf = {};
+  int res = fstat(fd.get(), &stat_buf);
+  PERFETTO_CHECK(res == 0 && stat_buf.st_size > 0);
+  return MapFD(std::move(fd), static_cast<size_t>(stat_buf.st_size));
+}
+
+// static
+std::unique_ptr<PosixSharedMemory> PosixSharedMemory::MapFD(base::ScopedFile fd,
+                                                            size_t size) {
+  PERFETTO_DCHECK(fd);
+  PERFETTO_DCHECK(size > 0);
+  void* start =
+      mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0);
+  PERFETTO_CHECK(start != MAP_FAILED);
+  return std::unique_ptr<PosixSharedMemory>(
+      new PosixSharedMemory(start, size, std::move(fd)));
+}
+
+PosixSharedMemory::PosixSharedMemory(void* start,
+                                     size_t size,
+                                     base::ScopedFile fd)
+    : start_(start), size_(size), fd_(std::move(fd)) {}
+
+PosixSharedMemory::~PosixSharedMemory() {
+  munmap(start(), size());
+}
+
+PosixSharedMemory::Factory::~Factory() {}
+
+std::unique_ptr<SharedMemory> PosixSharedMemory::Factory::CreateSharedMemory(
+    size_t size) {
+  return PosixSharedMemory::Create(size);
+}
+
+}  // namespace perfetto
+
+#endif  // OS_LINUX || OS_ANDROID || OS_APPLE
+// gen_amalgamated begin source: src/tracing/ipc/shared_memory_windows.cc
+// gen_amalgamated begin header: src/tracing/ipc/shared_memory_windows.h
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
+#define SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+
+namespace perfetto {
+
+// Implements the SharedMemory and its factory for the Windows IPC transport.
+// This used only for standalone builds and NOT in chromium, which instead uses
+// a custom Mojo wrapper (MojoSharedMemory in chromium's //services/tracing/).
+class SharedMemoryWindows : public SharedMemory {
+ public:
+  class Factory : public SharedMemory::Factory {
+   public:
+    ~Factory() override;
+    std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
+  };
+
+  // Create a brand new SHM region.
+  enum Flags { kNone = 0, kInheritableHandles };
+  static std::unique_ptr<SharedMemoryWindows> Create(
+      size_t size, Flags flags=Flags::kNone);
+  static std::unique_ptr<SharedMemoryWindows> Attach(const std::string& key);
+  static std::unique_ptr<SharedMemoryWindows> AttachToHandleWithKey(
+      base::ScopedPlatformHandle fd, const std::string& key);
+  ~SharedMemoryWindows() override;
+  const std::string& key() const { return key_; }
+  const base::ScopedPlatformHandle& handle() const { return handle_; }
+
+  // SharedMemory implementation.
+  void* start() const override { return start_; }
+  size_t size() const override { return size_; }
+
+ private:
+  SharedMemoryWindows(void* start,
+                      size_t size,
+                      std::string,
+                      base::ScopedPlatformHandle);
+  SharedMemoryWindows(const SharedMemoryWindows&) = delete;
+  SharedMemoryWindows& operator=(const SharedMemoryWindows&) = delete;
+
+  void* const start_;
+  const size_t size_;
+  std::string key_;
+  base::ScopedPlatformHandle handle_;
+};
+
+}  // namespace perfetto
+
+#endif  // OS_WIN
+
+#endif  // SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include <memory>
+#include <random>
+
+#include <Windows.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
+
+namespace perfetto {
+
+// static
+std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Create(
+    size_t size, Flags flags) {
+  base::ScopedPlatformHandle shmem_handle;
+  std::random_device rnd_dev;
+  uint64_t rnd_key = (static_cast<uint64_t>(rnd_dev()) << 32) | rnd_dev();
+  std::string key = "perfetto_shm_" + base::Uint64ToHexStringNoPrefix(rnd_key);
+
+  SECURITY_ATTRIBUTES security_attributes = {};
+  security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+  if (flags & Flags::kInheritableHandles)
+    security_attributes.bInheritHandle = TRUE;
+
+  shmem_handle.reset(CreateFileMappingA(
+      INVALID_HANDLE_VALUE,  // Use paging file.
+      &security_attributes,
+      PAGE_READWRITE,
+      static_cast<DWORD>(size >> 32),  // maximum object size (high-order DWORD)
+      static_cast<DWORD>(size),        // maximum object size (low-order DWORD)
+      key.c_str()));
+
+  if (!shmem_handle) {
+    PERFETTO_PLOG("CreateFileMapping() call failed");
+    return nullptr;
+  }
+  void* start =
+      MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
+                    /*offsetLow=*/0, size);
+  if (!start) {
+    PERFETTO_PLOG("MapViewOfFile() failed");
+    return nullptr;
+  }
+
+  return std::unique_ptr<SharedMemoryWindows>(new SharedMemoryWindows(
+      start, size, std::move(key), std::move(shmem_handle)));
+}
+
+// static
+std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Attach(
+    const std::string& key) {
+  base::ScopedPlatformHandle shmem_handle;
+  shmem_handle.reset(
+      OpenFileMappingA(FILE_MAP_ALL_ACCESS, /*inherit=*/false, key.c_str()));
+  if (!shmem_handle) {
+    PERFETTO_PLOG("Failed to OpenFileMapping()");
+    return nullptr;
+  }
+
+  void* start =
+      MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
+                    /*offsetLow=*/0, /*dwNumberOfBytesToMap=*/0);
+  if (!start) {
+    PERFETTO_PLOG("MapViewOfFile() failed");
+    return nullptr;
+  }
+
+  MEMORY_BASIC_INFORMATION info{};
+  if (!VirtualQuery(start, &info, sizeof(info))) {
+    PERFETTO_PLOG("VirtualQuery() failed");
+    return nullptr;
+  }
+  size_t size = info.RegionSize;
+  return std::unique_ptr<SharedMemoryWindows>(
+      new SharedMemoryWindows(start, size, key, std::move(shmem_handle)));
+}
+
+// static
+std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::AttachToHandleWithKey(
+    base::ScopedPlatformHandle shmem_handle, const std::string& key) {
+  void* start =
+      MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
+                    /*offsetLow=*/0, /*dwNumberOfBytesToMap=*/0);
+  if (!start) {
+    PERFETTO_PLOG("MapViewOfFile() failed");
+    return nullptr;
+  }
+
+  MEMORY_BASIC_INFORMATION info{};
+  if (!VirtualQuery(start, &info, sizeof(info))) {
+    PERFETTO_PLOG("VirtualQuery() failed");
+    return nullptr;
+  }
+  size_t size = info.RegionSize;
+
+  return std::unique_ptr<SharedMemoryWindows>(
+      new SharedMemoryWindows(start, size, key, std::move(shmem_handle)));
+}
+
+SharedMemoryWindows::SharedMemoryWindows(void* start,
+                                         size_t size,
+                                         std::string key,
+                                         base::ScopedPlatformHandle handle)
+    : start_(start),
+      size_(size),
+      key_(std::move(key)),
+      handle_(std::move(handle)) {}
+
+SharedMemoryWindows::~SharedMemoryWindows() {
+  if (start_)
+    UnmapViewOfFile(start_);
+}
+
+SharedMemoryWindows::Factory::~Factory() = default;
+
+std::unique_ptr<SharedMemory> SharedMemoryWindows::Factory::CreateSharedMemory(
+    size_t size) {
+  return SharedMemoryWindows::Create(size);
+}
+
+}  // namespace perfetto
+
+#endif  // !OS_WIN
+// gen_amalgamated begin source: src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
+// gen_amalgamated begin header: src/tracing/ipc/consumer/consumer_ipc_client_impl.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/consumer_ipc_client.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
+
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+namespace perfetto {
+
+class Consumer;
+
+// Allows to connect to a remote Service through a UNIX domain socket.
+// Exposed to:
+//   Consumer(s) of the tracing library.
+// Implemented in:
+//   src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
+class PERFETTO_EXPORT_COMPONENT ConsumerIPCClient {
+ public:
+  // Connects to the producer port of the Service listening on the given
+  // |service_sock_name|. If the connection is successful, the OnConnect()
+  // method will be invoked asynchronously on the passed Consumer interface.
+  // If the connection fails, OnDisconnect() will be invoked instead.
+  // The returned ConsumerEndpoint serves also to delimit the scope of the
+  // callbacks invoked on the Consumer interface: no more Consumer callbacks are
+  // invoked immediately after its destruction and any pending callback will be
+  // dropped.
+  static std::unique_ptr<TracingService::ConsumerEndpoint>
+  Connect(const char* service_sock_name, Consumer*, base::TaskRunner*);
+
+ protected:
+  ConsumerIPCClient() = delete;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
+#define SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
+
+#include <stdint.h>
+
+#include <list>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+namespace ipc {
+class Client;
+}  // namespace ipc
+
+class Consumer;
+
+// Exposes a Service endpoint to Consumer(s), proxying all requests through a
+// IPC channel to the remote Service. This class is the glue layer between the
+// generic Service interface exposed to the clients of the library and the
+// actual IPC transport.
+class ConsumerIPCClientImpl : public TracingService::ConsumerEndpoint,
+                              public ipc::ServiceProxy::EventListener {
+ public:
+  ConsumerIPCClientImpl(const char* service_sock_name,
+                        Consumer*,
+                        base::TaskRunner*);
+  ~ConsumerIPCClientImpl() override;
+
+  // TracingService::ConsumerEndpoint implementation.
+  // These methods are invoked by the actual Consumer(s) code by clients of the
+  // tracing library, which know nothing about the IPC transport.
+  void EnableTracing(const TraceConfig&, base::ScopedFile) override;
+  void StartTracing() override;
+  void ChangeTraceConfig(const TraceConfig&) override;
+  void DisableTracing() override;
+  void ReadBuffers() override;
+  void FreeBuffers() override;
+  void Flush(uint32_t timeout_ms, FlushCallback, FlushFlags) override;
+  void Detach(const std::string& key) override;
+  void Attach(const std::string& key) override;
+  void GetTraceStats() override;
+  void ObserveEvents(uint32_t enabled_event_types) override;
+  void QueryServiceState(QueryServiceStateCallback) override;
+  void QueryCapabilities(QueryCapabilitiesCallback) override;
+  void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
+  void CloneSession(TracingSessionID) override;
+
+  // ipc::ServiceProxy::EventListener implementation.
+  // These methods are invoked by the IPC layer, which knows nothing about
+  // tracing, consumers and consumers.
+  void OnConnect() override;
+  void OnDisconnect() override;
+
+ private:
+  struct PendingQueryServiceRequest {
+    QueryServiceStateCallback callback;
+
+    // All the replies will be appended here until |has_more| == false.
+    std::vector<uint8_t> merged_resp;
+  };
+
+  // List because we need stable iterators.
+  using PendingQueryServiceRequests = std::list<PendingQueryServiceRequest>;
+
+  void OnReadBuffersResponse(
+      ipc::AsyncResult<protos::gen::ReadBuffersResponse>);
+  void OnEnableTracingResponse(
+      ipc::AsyncResult<protos::gen::EnableTracingResponse>);
+  void OnQueryServiceStateResponse(
+      ipc::AsyncResult<protos::gen::QueryServiceStateResponse>,
+      PendingQueryServiceRequests::iterator);
+
+  // TODO(primiano): think to dtor order, do we rely on any specific sequence?
+  Consumer* const consumer_;
+
+  // The object that owns the client socket and takes care of IPC traffic.
+  std::unique_ptr<ipc::Client> ipc_channel_;
+
+  // The proxy interface for the consumer port of the service. It is bound
+  // to |ipc_channel_| and (de)serializes method invocations over the wire.
+  protos::gen::ConsumerPortProxy consumer_port_;
+
+  bool connected_ = false;
+
+  PendingQueryServiceRequests pending_query_svc_reqs_;
+
+  // When a packet is too big to fit into a ReadBuffersResponse IPC, the service
+  // will chunk it into several IPCs, each containing few slices of the packet
+  // (a packet's slice is always guaranteed to be << kIPCBufferSize). When
+  // chunking happens this field accumulates the slices received until the
+  // one with |last_slice_for_packet| == true is received.
+  TracePacket partial_packet_;
+
+  // Keep last.
+  base::WeakPtrFactory<ConsumerIPCClientImpl> weak_ptr_factory_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/consumer/consumer_ipc_client_impl.h"
+
+#include <string.h>
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
+
+// TODO(fmayer): Add a test to check to what happens when ConsumerIPCClientImpl
+// gets destroyed w.r.t. the Consumer pointer. Also think to lifetime of the
+// Consumer* during the callbacks.
+
+namespace perfetto {
+
+// static. (Declared in include/tracing/ipc/consumer_ipc_client.h).
+std::unique_ptr<TracingService::ConsumerEndpoint> ConsumerIPCClient::Connect(
+    const char* service_sock_name,
+    Consumer* consumer,
+    base::TaskRunner* task_runner) {
+  return std::unique_ptr<TracingService::ConsumerEndpoint>(
+      new ConsumerIPCClientImpl(service_sock_name, consumer, task_runner));
+}
+
+ConsumerIPCClientImpl::ConsumerIPCClientImpl(const char* service_sock_name,
+                                             Consumer* consumer,
+                                             base::TaskRunner* task_runner)
+    : consumer_(consumer),
+      ipc_channel_(
+          ipc::Client::CreateInstance({service_sock_name, /*sock_retry=*/false},
+                                      task_runner)),
+      consumer_port_(this /* event_listener */),
+      weak_ptr_factory_(this) {
+  ipc_channel_->BindService(consumer_port_.GetWeakPtr());
+}
+
+ConsumerIPCClientImpl::~ConsumerIPCClientImpl() = default;
+
+// Called by the IPC layer if the BindService() succeeds.
+void ConsumerIPCClientImpl::OnConnect() {
+  connected_ = true;
+  consumer_->OnConnect();
+}
+
+void ConsumerIPCClientImpl::OnDisconnect() {
+  PERFETTO_DLOG("Tracing service connection failure");
+  connected_ = false;
+  consumer_->OnDisconnect();  // Note: may delete |this|.
+}
+
+void ConsumerIPCClientImpl::EnableTracing(const TraceConfig& trace_config,
+                                          base::ScopedFile fd) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot EnableTracing(), not connected to tracing service");
+    return;
+  }
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  if (fd) {
+    consumer_->OnTracingDisabled(
+        "Passing FDs for write_into_file is not supported on Windows");
+    return;
+  }
+#endif
+
+  protos::gen::EnableTracingRequest req;
+  *req.mutable_trace_config() = trace_config;
+  ipc::Deferred<protos::gen::EnableTracingResponse> async_response;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  async_response.Bind(
+      [weak_this](
+          ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
+        if (weak_this)
+          weak_this->OnEnableTracingResponse(std::move(response));
+      });
+
+  // |fd| will be closed when this function returns, but it's fine because the
+  // IPC layer dup()'s it when sending the IPC.
+  consumer_port_.EnableTracing(req, std::move(async_response), *fd);
+}
+
+void ConsumerIPCClientImpl::ChangeTraceConfig(const TraceConfig& trace_config) {
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot ChangeTraceConfig(), not connected to tracing service");
+    return;
+  }
+
+  ipc::Deferred<protos::gen::ChangeTraceConfigResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("ChangeTraceConfig() failed");
+      });
+  protos::gen::ChangeTraceConfigRequest req;
+  *req.mutable_trace_config() = trace_config;
+  consumer_port_.ChangeTraceConfig(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::StartTracing() {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot StartTracing(), not connected to tracing service");
+    return;
+  }
+
+  ipc::Deferred<protos::gen::StartTracingResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::StartTracingResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("StartTracing() failed");
+      });
+  protos::gen::StartTracingRequest req;
+  consumer_port_.StartTracing(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::DisableTracing() {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot DisableTracing(), not connected to tracing service");
+    return;
+  }
+
+  ipc::Deferred<protos::gen::DisableTracingResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::DisableTracingResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("DisableTracing() failed");
+      });
+  consumer_port_.DisableTracing(protos::gen::DisableTracingRequest(),
+                                std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::ReadBuffers() {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot ReadBuffers(), not connected to tracing service");
+    return;
+  }
+
+  ipc::Deferred<protos::gen::ReadBuffersResponse> async_response;
+
+  // The IPC layer guarantees that callbacks are destroyed after this object
+  // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
+  // contract of this class expects the caller to not destroy the Consumer class
+  // before having destroyed this class. Hence binding |this| here is safe.
+  async_response.Bind(
+      [this](ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
+        OnReadBuffersResponse(std::move(response));
+      });
+  consumer_port_.ReadBuffers(protos::gen::ReadBuffersRequest(),
+                             std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::OnReadBuffersResponse(
+    ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
+  if (!response) {
+    PERFETTO_DLOG("ReadBuffers() failed");
+    return;
+  }
+  std::vector<TracePacket> trace_packets;
+  for (auto& resp_slice : response->slices()) {
+    const std::string& slice_data = resp_slice.data();
+    Slice slice = Slice::Allocate(slice_data.size());
+    memcpy(slice.own_data(), slice_data.data(), slice.size);
+    partial_packet_.AddSlice(std::move(slice));
+    if (resp_slice.last_slice_for_packet())
+      trace_packets.emplace_back(std::move(partial_packet_));
+  }
+  if (!trace_packets.empty() || !response.has_more())
+    consumer_->OnTraceData(std::move(trace_packets), response.has_more());
+}
+
+void ConsumerIPCClientImpl::OnEnableTracingResponse(
+    ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
+  std::string error;
+  // |response| might be empty when the request gets rejected (if the connection
+  // with the service is dropped all outstanding requests are auto-rejected).
+  if (!response) {
+    error =
+        "EnableTracing IPC request rejected. This is likely due to a loss of "
+        "the traced connection";
+  } else {
+    error = response->error();
+  }
+  if (!response || response->disabled())
+    consumer_->OnTracingDisabled(error);
+}
+
+void ConsumerIPCClientImpl::FreeBuffers() {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot FreeBuffers(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::FreeBuffersRequest req;
+  ipc::Deferred<protos::gen::FreeBuffersResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::FreeBuffersResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("FreeBuffers() failed");
+      });
+  consumer_port_.FreeBuffers(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::Flush(uint32_t timeout_ms,
+                                  FlushCallback callback,
+                                  FlushFlags flush_flags) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot Flush(), not connected to tracing service");
+    return callback(/*success=*/false);
+  }
+
+  protos::gen::FlushRequest req;
+  req.set_timeout_ms(static_cast<uint32_t>(timeout_ms));
+  req.set_flags(flush_flags.flags());
+  ipc::Deferred<protos::gen::FlushResponse> async_response;
+  async_response.Bind(
+      [callback](ipc::AsyncResult<protos::gen::FlushResponse> response) {
+        callback(!!response);
+      });
+  consumer_port_.Flush(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::Detach(const std::string& key) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot Detach(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::DetachRequest req;
+  req.set_key(key);
+  ipc::Deferred<protos::gen::DetachResponse> async_response;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+
+  async_response.Bind(
+      [weak_this](ipc::AsyncResult<protos::gen::DetachResponse> response) {
+        if (weak_this)
+          weak_this->consumer_->OnDetach(!!response);
+      });
+  consumer_port_.Detach(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::Attach(const std::string& key) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot Attach(), not connected to tracing service");
+    return;
+  }
+
+  {
+    protos::gen::AttachRequest req;
+    req.set_key(key);
+    ipc::Deferred<protos::gen::AttachResponse> async_response;
+    auto weak_this = weak_ptr_factory_.GetWeakPtr();
+
+    async_response.Bind(
+        [weak_this](ipc::AsyncResult<protos::gen::AttachResponse> response) {
+          if (!weak_this)
+            return;
+          if (!response) {
+            weak_this->consumer_->OnAttach(/*success=*/false, TraceConfig());
+            return;
+          }
+          const TraceConfig& trace_config = response->trace_config();
+
+          // If attached successfully, also attach to the end-of-trace
+          // notificaton callback, via EnableTracing(attach_notification_only).
+          protos::gen::EnableTracingRequest enable_req;
+          enable_req.set_attach_notification_only(true);
+          ipc::Deferred<protos::gen::EnableTracingResponse> enable_resp;
+          enable_resp.Bind(
+              [weak_this](
+                  ipc::AsyncResult<protos::gen::EnableTracingResponse> resp) {
+                if (weak_this)
+                  weak_this->OnEnableTracingResponse(std::move(resp));
+              });
+          weak_this->consumer_port_.EnableTracing(enable_req,
+                                                  std::move(enable_resp));
+
+          weak_this->consumer_->OnAttach(/*success=*/true, trace_config);
+        });
+    consumer_port_.Attach(req, std::move(async_response));
+  }
+}
+
+void ConsumerIPCClientImpl::GetTraceStats() {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot GetTraceStats(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::GetTraceStatsRequest req;
+  ipc::Deferred<protos::gen::GetTraceStatsResponse> async_response;
+
+  // The IPC layer guarantees that callbacks are destroyed after this object
+  // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
+  // contract of this class expects the caller to not destroy the Consumer class
+  // before having destroyed this class. Hence binding |this| here is safe.
+  async_response.Bind(
+      [this](ipc::AsyncResult<protos::gen::GetTraceStatsResponse> response) {
+        if (!response) {
+          consumer_->OnTraceStats(/*success=*/false, TraceStats());
+          return;
+        }
+        consumer_->OnTraceStats(/*success=*/true, response->trace_stats());
+      });
+  consumer_port_.GetTraceStats(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::ObserveEvents(uint32_t enabled_event_types) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot ObserveEvents(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::ObserveEventsRequest req;
+  for (uint32_t i = 0; i < 32; i++) {
+    const uint32_t event_id = 1u << i;
+    if (enabled_event_types & event_id)
+      req.add_events_to_observe(static_cast<ObservableEvents::Type>(event_id));
+  }
+
+  ipc::Deferred<protos::gen::ObserveEventsResponse> async_response;
+  // The IPC layer guarantees that callbacks are destroyed after this object
+  // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
+  // contract of this class expects the caller to not destroy the Consumer class
+  // before having destroyed this class. Hence binding |this| here is safe.
+  async_response.Bind(
+      [this](ipc::AsyncResult<protos::gen::ObserveEventsResponse> response) {
+        // Skip empty response, which the service sends to close the stream.
+        if (!response.has_more()) {
+          PERFETTO_DCHECK(!response.success());
+          return;
+        }
+        consumer_->OnObservableEvents(response->events());
+      });
+  consumer_port_.ObserveEvents(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::QueryServiceState(
+    QueryServiceStateCallback callback) {
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot QueryServiceState(), not connected to tracing service");
+    return;
+  }
+
+  auto it = pending_query_svc_reqs_.insert(pending_query_svc_reqs_.end(),
+                                           {std::move(callback), {}});
+  protos::gen::QueryServiceStateRequest req;
+  ipc::Deferred<protos::gen::QueryServiceStateResponse> async_response;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  async_response.Bind(
+      [weak_this,
+       it](ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response) {
+        if (weak_this)
+          weak_this->OnQueryServiceStateResponse(std::move(response), it);
+      });
+  consumer_port_.QueryServiceState(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::OnQueryServiceStateResponse(
+    ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response,
+    PendingQueryServiceRequests::iterator req_it) {
+  PERFETTO_DCHECK(req_it->callback);
+
+  if (!response) {
+    auto callback = std::move(req_it->callback);
+    pending_query_svc_reqs_.erase(req_it);
+    callback(false, TracingServiceState());
+    return;
+  }
+
+  // The QueryServiceState response can be split in several chunks if the
+  // service has several data sources. The client is supposed to merge all the
+  // replies. The easiest way to achieve this is to re-serialize the partial
+  // response and then re-decode the merged result in one shot.
+  std::vector<uint8_t>& merged_resp = req_it->merged_resp;
+  std::vector<uint8_t> part = response->service_state().SerializeAsArray();
+  merged_resp.insert(merged_resp.end(), part.begin(), part.end());
+
+  if (response.has_more())
+    return;
+
+  // All replies have been received. Decode the merged result and reply to the
+  // callback.
+  protos::gen::TracingServiceState svc_state;
+  bool ok = svc_state.ParseFromArray(merged_resp.data(), merged_resp.size());
+  if (!ok)
+    PERFETTO_ELOG("Failed to decode merged QueryServiceStateResponse");
+  auto callback = std::move(req_it->callback);
+  pending_query_svc_reqs_.erase(req_it);
+  callback(ok, std::move(svc_state));
+}
+
+void ConsumerIPCClientImpl::QueryCapabilities(
+    QueryCapabilitiesCallback callback) {
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot QueryCapabilities(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::QueryCapabilitiesRequest req;
+  ipc::Deferred<protos::gen::QueryCapabilitiesResponse> async_response;
+  async_response.Bind(
+      [callback](
+          ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse> response) {
+        if (!response) {
+          // If the IPC fails, we are talking to an older version of the service
+          // that didn't support QueryCapabilities at all. In this case return
+          // an empty capabilities message.
+          callback(TracingServiceCapabilities());
+        } else {
+          callback(response->capabilities());
+        }
+      });
+  consumer_port_.QueryCapabilities(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::SaveTraceForBugreport(
+    SaveTraceForBugreportCallback callback) {
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot SaveTraceForBugreport(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::SaveTraceForBugreportRequest req;
+  ipc::Deferred<protos::gen::SaveTraceForBugreportResponse> async_response;
+  async_response.Bind(
+      [callback](ipc::AsyncResult<protos::gen::SaveTraceForBugreportResponse>
+                     response) {
+        if (!response) {
+          // If the IPC fails, we are talking to an older version of the service
+          // that didn't support SaveTraceForBugreport at all.
+          callback(
+              false,
+              "The tracing service doesn't support SaveTraceForBugreport()");
+        } else {
+          callback(response->success(), response->msg());
+        }
+      });
+  consumer_port_.SaveTraceForBugreport(req, std::move(async_response));
+}
+
+void ConsumerIPCClientImpl::CloneSession(TracingSessionID tsid) {
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot CloneSession(), not connected to tracing service");
+    return;
+  }
+
+  protos::gen::CloneSessionRequest req;
+  req.set_session_id(tsid);
+  ipc::Deferred<protos::gen::CloneSessionResponse> async_response;
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+
+  async_response.Bind(
+      [weak_this](
+          ipc::AsyncResult<protos::gen::CloneSessionResponse> response) {
+        if (!weak_this)
+          return;
+        if (!response) {
+          // If the IPC fails, we are talking to an older version of the service
+          // that didn't support CloneSession at all.
+          weak_this->consumer_->OnSessionCloned(
+              {false, "CloneSession IPC not supported", {}});
+        } else {
+          base::Uuid uuid(response->uuid_lsb(), response->uuid_msb());
+          weak_this->consumer_->OnSessionCloned(
+              {response->success(), response->error(), uuid});
+        }
+      });
+  consumer_port_.CloneSession(req, std::move(async_response));
+}
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/producer/producer_ipc_client_impl.cc
+// gen_amalgamated begin header: src/tracing/ipc/producer/producer_ipc_client_impl.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/producer_ipc_client.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
+
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+
+namespace perfetto {
+
+class Producer;
+
+// Allows to connect to a remote Service through a UNIX domain socket.
+// Exposed to:
+//   Producer(s) of the tracing library.
+// Implemented in:
+//   src/tracing/ipc/producer/producer_ipc_client_impl.cc
+class PERFETTO_EXPORT_COMPONENT ProducerIPCClient {
+ public:
+  enum class ConnectionFlags {
+    // Fails immediately with OnConnect(false) if the service connection cannot
+    // be established.
+    kDefault = 0,
+
+    // Keeps retrying with exponential backoff indefinitely. The caller will
+    // never see an OnConnect(false).
+    kRetryIfUnreachable = 1,
+  };
+
+  // Connects to the producer port of the Service listening on the given
+  // |service_sock_name|. If the connection is successful, the OnConnect()
+  // method will be invoked asynchronously on the passed Producer interface. If
+  // the connection fails, OnDisconnect() will be invoked instead. The returned
+  // ProducerEndpoint serves also to delimit the scope of the callbacks invoked
+  // on the Producer interface: no more Producer callbacks are invoked
+  // immediately after its destruction and any pending callback will be dropped.
+  // To provide a producer-allocated shared memory buffer, both |shm| and
+  // |shm_arbiter| should be set. |shm_arbiter| should be an unbound
+  // SharedMemoryArbiter instance. When |shm| and |shm_arbiter| are provided,
+  // the service will attempt to adopt the provided SMB. If this fails, the
+  // ProducerEndpoint will disconnect, but the SMB and arbiter will remain valid
+  // until the client is destroyed.
+  //
+  // TODO(eseckler): Support adoption failure more gracefully.
+  // TODO(primiano): move all the existing use cases to the Connect(ConnArgs)
+  // below. Also move the functionality of ConnectionFlags into ConnArgs.
+  static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
+      const char* service_sock_name,
+      Producer*,
+      const std::string& producer_name,
+      base::TaskRunner*,
+      TracingService::ProducerSMBScrapingMode smb_scraping_mode =
+          TracingService::ProducerSMBScrapingMode::kDefault,
+      size_t shared_memory_size_hint_bytes = 0,
+      size_t shared_memory_page_size_hint_bytes = 0,
+      std::unique_ptr<SharedMemory> shm = nullptr,
+      std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr,
+      ConnectionFlags = ConnectionFlags::kDefault);
+
+  // Overload of Connect() to support adopting a connected socket using
+  // ipc::Client::ConnArgs.
+  static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
+      ipc::Client::ConnArgs,
+      Producer*,
+      const std::string& producer_name,
+      base::TaskRunner*,
+      TracingService::ProducerSMBScrapingMode smb_scraping_mode =
+          TracingService::ProducerSMBScrapingMode::kDefault,
+      size_t shared_memory_size_hint_bytes = 0,
+      size_t shared_memory_page_size_hint_bytes = 0,
+      std::unique_ptr<SharedMemory> shm = nullptr,
+      std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr,
+      CreateSocketAsync create_socket_async = nullptr);
+
+ protected:
+  ProducerIPCClient() = delete;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
+#define SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
+
+#include <stdint.h>
+
+#include <set>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+class Producer;
+class SharedMemoryArbiter;
+
+// Exposes a Service endpoint to Producer(s), proxying all requests through a
+// IPC channel to the remote Service. This class is the glue layer between the
+// generic Service interface exposed to the clients of the library and the
+// actual IPC transport.
+// If create_socket_async is set, it will be called to create and connect to a
+// socket to the service. If unset, the producer will create and connect itself.
+class ProducerIPCClientImpl : public TracingService::ProducerEndpoint,
+                              public ipc::ServiceProxy::EventListener {
+ public:
+  ProducerIPCClientImpl(ipc::Client::ConnArgs,
+                        Producer*,
+                        const std::string& producer_name,
+                        base::TaskRunner*,
+                        TracingService::ProducerSMBScrapingMode,
+                        size_t shared_memory_size_hint_bytes,
+                        size_t shared_memory_page_size_hint_bytes,
+                        std::unique_ptr<SharedMemory> shm,
+                        std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
+                        CreateSocketAsync create_socket_async);
+  ~ProducerIPCClientImpl() override;
+
+  // TracingService::ProducerEndpoint implementation.
+  // These methods are invoked by the actual Producer(s) code by clients of the
+  // tracing library, which know nothing about the IPC transport.
+  void Disconnect() override;
+  void RegisterDataSource(const DataSourceDescriptor&) override;
+  void UpdateDataSource(const DataSourceDescriptor&) override;
+  void UnregisterDataSource(const std::string& name) override;
+  void RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer) override;
+  void UnregisterTraceWriter(uint32_t writer_id) override;
+  void CommitData(const CommitDataRequest&, CommitDataCallback) override;
+  void NotifyDataSourceStarted(DataSourceInstanceID) override;
+  void NotifyDataSourceStopped(DataSourceInstanceID) override;
+  void ActivateTriggers(const std::vector<std::string>&) override;
+  void Sync(std::function<void()> callback) override;
+
+  std::unique_ptr<TraceWriter> CreateTraceWriter(
+      BufferID target_buffer,
+      BufferExhaustedPolicy) override;
+  SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
+  bool IsShmemProvidedByProducer() const override;
+  void NotifyFlushComplete(FlushRequestID) override;
+  SharedMemory* shared_memory() const override;
+  size_t shared_buffer_page_size_kb() const override;
+
+  // ipc::ServiceProxy::EventListener implementation.
+  // These methods are invoked by the IPC layer, which knows nothing about
+  // tracing, producers and consumers.
+  void OnConnect() override;
+  void OnDisconnect() override;
+
+  ipc::Client* GetClientForTesting() { return ipc_channel_.get(); }
+
+ private:
+  // Drops the provider connection if a protocol error was detected while
+  // processing an IPC command.
+  void ScheduleDisconnect();
+
+  // Invoked soon after having established the connection with the service.
+  void OnConnectionInitialized(bool connection_succeeded,
+                               bool using_shmem_provided_by_producer,
+                               bool direct_smb_patching_supported,
+                               bool use_shmem_emulation);
+
+  // Invoked when the remote Service sends an IPC to tell us to do something
+  // (e.g. start/stop a data source).
+  void OnServiceRequest(const protos::gen::GetAsyncCommandResponse&);
+
+  // TODO think to destruction order, do we rely on any specific dtor sequence?
+  Producer* const producer_;
+  base::TaskRunner* const task_runner_;
+
+  // A callback used to receive the shmem region out of band of the socket.
+  std::function<int(void)> receive_shmem_fd_cb_fuchsia_;
+
+  // The object that owns the client socket and takes care of IPC traffic.
+  std::unique_ptr<ipc::Client> ipc_channel_;
+
+  // The proxy interface for the producer port of the service. It is bound
+  // to |ipc_channel_| and (de)serializes method invocations over the wire.
+  std::unique_ptr<protos::gen::ProducerPortProxy> producer_port_;
+
+  std::unique_ptr<SharedMemory> shared_memory_;
+  std::unique_ptr<SharedMemoryArbiter> shared_memory_arbiter_;
+  size_t shared_buffer_page_size_kb_ = 0;
+  std::set<DataSourceInstanceID> data_sources_setup_;
+  bool connected_ = false;
+  std::string const name_;
+  size_t shared_memory_page_size_hint_bytes_ = 0;
+  size_t shared_memory_size_hint_bytes_ = 0;
+  TracingService::ProducerSMBScrapingMode const smb_scraping_mode_;
+  bool is_shmem_provided_by_producer_ = false;
+  bool direct_smb_patching_supported_ = false;
+  bool use_shmem_emulation_ = false;
+  std::vector<std::function<void()>> pending_sync_reqs_;
+  base::WeakPtrFactory<ProducerIPCClientImpl> weak_factory_{this};
+  PERFETTO_THREAD_CHECKER(thread_checker_)
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/producer/producer_ipc_client_impl.h"
+
+#include <cinttypes>
+
+#include <string.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "src/tracing/core/in_process_shared_memory.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
+#else
+// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
+#endif
+
+// TODO(fmayer): think to what happens when ProducerIPCClientImpl gets destroyed
+// w.r.t. the Producer pointer. Also think to lifetime of the Producer* during
+// the callbacks.
+
+namespace perfetto {
+
+// static. (Declared in include/tracing/ipc/producer_ipc_client.h).
+std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::Connect(
+    const char* service_sock_name,
+    Producer* producer,
+    const std::string& producer_name,
+    base::TaskRunner* task_runner,
+    TracingService::ProducerSMBScrapingMode smb_scraping_mode,
+    size_t shared_memory_size_hint_bytes,
+    size_t shared_memory_page_size_hint_bytes,
+    std::unique_ptr<SharedMemory> shm,
+    std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
+    ConnectionFlags conn_flags) {
+  return std::unique_ptr<TracingService::ProducerEndpoint>(
+      new ProducerIPCClientImpl(
+          {service_sock_name,
+           conn_flags ==
+               ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable},
+          producer, producer_name, task_runner, smb_scraping_mode,
+          shared_memory_size_hint_bytes, shared_memory_page_size_hint_bytes,
+          std::move(shm), std::move(shm_arbiter), nullptr));
+}
+
+// static. (Declared in include/tracing/ipc/producer_ipc_client.h).
+std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::Connect(
+    ipc::Client::ConnArgs conn_args,
+    Producer* producer,
+    const std::string& producer_name,
+    base::TaskRunner* task_runner,
+    TracingService::ProducerSMBScrapingMode smb_scraping_mode,
+    size_t shared_memory_size_hint_bytes,
+    size_t shared_memory_page_size_hint_bytes,
+    std::unique_ptr<SharedMemory> shm,
+    std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
+    CreateSocketAsync create_socket_async) {
+  return std::unique_ptr<TracingService::ProducerEndpoint>(
+      new ProducerIPCClientImpl(
+          std::move(conn_args), producer, producer_name, task_runner,
+          smb_scraping_mode, shared_memory_size_hint_bytes,
+          shared_memory_page_size_hint_bytes, std::move(shm),
+          std::move(shm_arbiter), create_socket_async));
+}
+
+ProducerIPCClientImpl::ProducerIPCClientImpl(
+    ipc::Client::ConnArgs conn_args,
+    Producer* producer,
+    const std::string& producer_name,
+    base::TaskRunner* task_runner,
+    TracingService::ProducerSMBScrapingMode smb_scraping_mode,
+    size_t shared_memory_size_hint_bytes,
+    size_t shared_memory_page_size_hint_bytes,
+    std::unique_ptr<SharedMemory> shm,
+    std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
+    CreateSocketAsync create_socket_async)
+    : producer_(producer),
+      task_runner_(task_runner),
+      receive_shmem_fd_cb_fuchsia_(
+          std::move(conn_args.receive_shmem_fd_cb_fuchsia)),
+      producer_port_(
+          new protos::gen::ProducerPortProxy(this /* event_listener */)),
+      shared_memory_(std::move(shm)),
+      shared_memory_arbiter_(std::move(shm_arbiter)),
+      name_(producer_name),
+      shared_memory_page_size_hint_bytes_(shared_memory_page_size_hint_bytes),
+      shared_memory_size_hint_bytes_(shared_memory_size_hint_bytes),
+      smb_scraping_mode_(smb_scraping_mode) {
+  // Check for producer-provided SMB (used by Chrome for startup tracing).
+  if (shared_memory_) {
+    // We also expect a valid (unbound) arbiter. Bind it to this endpoint now.
+    PERFETTO_CHECK(shared_memory_arbiter_);
+    shared_memory_arbiter_->BindToProducerEndpoint(this, task_runner_);
+
+    // If the service accepts our SMB, then it must match our requested page
+    // layout. The protocol doesn't allow the service to change the size and
+    // layout when the SMB is provided by the producer.
+    shared_buffer_page_size_kb_ = shared_memory_page_size_hint_bytes_ / 1024;
+  }
+
+  if (create_socket_async) {
+    PERFETTO_DCHECK(conn_args.socket_name);
+    auto weak_this = weak_factory_.GetWeakPtr();
+    create_socket_async(
+        [weak_this, task_runner = task_runner_](base::SocketHandle fd) {
+          task_runner->PostTask([weak_this, fd] {
+            base::ScopedSocketHandle handle(fd);
+            if (!weak_this) {
+              return;
+            }
+            ipc::Client::ConnArgs args(std::move(handle));
+            weak_this->ipc_channel_ = ipc::Client::CreateInstance(
+                std::move(args), weak_this->task_runner_);
+            weak_this->ipc_channel_->BindService(
+                weak_this->producer_port_->GetWeakPtr());
+          });
+        });
+  } else {
+    ipc_channel_ =
+        ipc::Client::CreateInstance(std::move(conn_args), task_runner);
+    ipc_channel_->BindService(producer_port_->GetWeakPtr());
+  }
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+}
+
+ProducerIPCClientImpl::~ProducerIPCClientImpl() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+}
+
+void ProducerIPCClientImpl::Disconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!producer_port_)
+    return;
+  // Reset the producer port so that no further IPCs are received and IPC
+  // callbacks are no longer executed. Also reset the IPC channel so that the
+  // service is notified of the disconnection.
+  producer_port_.reset();
+  ipc_channel_.reset();
+  // Perform disconnect synchronously.
+  OnDisconnect();
+}
+
+// Called by the IPC layer if the BindService() succeeds.
+void ProducerIPCClientImpl::OnConnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  connected_ = true;
+
+  // The IPC layer guarantees that any outstanding callback will be dropped on
+  // the floor if producer_port_ is destroyed between the request and the reply.
+  // Binding |this| is hence safe.
+  ipc::Deferred<protos::gen::InitializeConnectionResponse> on_init;
+  on_init.Bind(
+      [this](ipc::AsyncResult<protos::gen::InitializeConnectionResponse> resp) {
+        OnConnectionInitialized(
+            resp.success(),
+            resp.success() ? resp->using_shmem_provided_by_producer() : false,
+            resp.success() ? resp->direct_smb_patching_supported() : false,
+            resp.success() ? resp->use_shmem_emulation() : false);
+      });
+  protos::gen::InitializeConnectionRequest req;
+  req.set_producer_name(name_);
+  req.set_shared_memory_size_hint_bytes(
+      static_cast<uint32_t>(shared_memory_size_hint_bytes_));
+  req.set_shared_memory_page_size_hint_bytes(
+      static_cast<uint32_t>(shared_memory_page_size_hint_bytes_));
+  switch (smb_scraping_mode_) {
+    case TracingService::ProducerSMBScrapingMode::kDefault:
+      // No need to set the mode, it defaults to use the service default if
+      // unspecified.
+      break;
+    case TracingService::ProducerSMBScrapingMode::kEnabled:
+      req.set_smb_scraping_mode(
+          protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED);
+      break;
+    case TracingService::ProducerSMBScrapingMode::kDisabled:
+      req.set_smb_scraping_mode(
+          protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED);
+      break;
+  }
+
+  int shm_fd = -1;
+  if (shared_memory_) {
+    req.set_producer_provided_shmem(true);
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    auto key = static_cast<SharedMemoryWindows*>(shared_memory_.get())->key();
+    req.set_shm_key_windows(key);
+#else
+    shm_fd = static_cast<PosixSharedMemory*>(shared_memory_.get())->fd();
+#endif
+  }
+
+  req.set_sdk_version(base::GetVersionString());
+  producer_port_->InitializeConnection(req, std::move(on_init), shm_fd);
+
+  // Create the back channel to receive commands from the Service.
+  ipc::Deferred<protos::gen::GetAsyncCommandResponse> on_cmd;
+  on_cmd.Bind(
+      [this](ipc::AsyncResult<protos::gen::GetAsyncCommandResponse> resp) {
+        if (!resp)
+          return;  // The IPC channel was closed and |resp| was auto-rejected.
+        OnServiceRequest(*resp);
+      });
+  producer_port_->GetAsyncCommand(protos::gen::GetAsyncCommandRequest(),
+                                  std::move(on_cmd));
+
+  // If there are pending Sync() requests, send them now.
+  for (const auto& pending_sync : pending_sync_reqs_)
+    Sync(std::move(pending_sync));
+  pending_sync_reqs_.clear();
+}
+
+void ProducerIPCClientImpl::OnDisconnect() {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  PERFETTO_DLOG("Tracing service connection failure");
+  connected_ = false;
+  data_sources_setup_.clear();
+  producer_->OnDisconnect();  // Note: may delete |this|.
+}
+
+void ProducerIPCClientImpl::ScheduleDisconnect() {
+  // |ipc_channel| doesn't allow disconnection in the middle of handling
+  // an IPC call, so the connection drop must take place over two phases.
+
+  // First, synchronously drop the |producer_port_| so that no more IPC
+  // messages are handled.
+  producer_port_.reset();
+
+  // Then schedule an async task for performing the remainder of the
+  // disconnection operations outside the context of the IPC method handler.
+  auto weak_this = weak_factory_.GetWeakPtr();
+  task_runner_->PostTask([weak_this]() {
+    if (weak_this) {
+      weak_this->Disconnect();
+    }
+  });
+}
+
+void ProducerIPCClientImpl::OnConnectionInitialized(
+    bool connection_succeeded,
+    bool using_shmem_provided_by_producer,
+    bool direct_smb_patching_supported,
+    bool use_shmem_emulation) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  // If connection_succeeded == false, the OnDisconnect() call will follow next
+  // and there we'll notify the |producer_|. TODO: add a test for this.
+  if (!connection_succeeded)
+    return;
+  is_shmem_provided_by_producer_ = using_shmem_provided_by_producer;
+  direct_smb_patching_supported_ = direct_smb_patching_supported;
+  // The tracing service may reject using shared memory and tell the client to
+  // commit data over the socket. This can happen when the client connects to
+  // the service via a relay service:
+  // client <-Unix socket-> relay service <- vsock -> tracing service.
+  use_shmem_emulation_ = use_shmem_emulation;
+  producer_->OnConnect();
+
+  // Bail out if the service failed to adopt our producer-allocated SMB.
+  // TODO(eseckler): Handle adoption failure more gracefully.
+  if (shared_memory_ && !is_shmem_provided_by_producer_) {
+    PERFETTO_DLOG("Service failed adopt producer-provided SMB, disconnecting.");
+    Disconnect();
+    return;
+  }
+}
+
+void ProducerIPCClientImpl::OnServiceRequest(
+    const protos::gen::GetAsyncCommandResponse& cmd) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  // This message is sent only when connecting to a service running Android Q+.
+  // See comment below in kStartDataSource.
+  if (cmd.has_setup_data_source()) {
+    const auto& req = cmd.setup_data_source();
+    const DataSourceInstanceID dsid = req.new_instance_id();
+    data_sources_setup_.insert(dsid);
+    producer_->SetupDataSource(dsid, req.config());
+    return;
+  }
+
+  if (cmd.has_start_data_source()) {
+    const auto& req = cmd.start_data_source();
+    const DataSourceInstanceID dsid = req.new_instance_id();
+    const DataSourceConfig& cfg = req.config();
+    if (!data_sources_setup_.count(dsid)) {
+      // When connecting with an older (Android P) service, the service will not
+      // send a SetupDataSource message. We synthesize it here in that case.
+      producer_->SetupDataSource(dsid, cfg);
+    }
+    producer_->StartDataSource(dsid, cfg);
+    return;
+  }
+
+  if (cmd.has_stop_data_source()) {
+    const DataSourceInstanceID dsid = cmd.stop_data_source().instance_id();
+    producer_->StopDataSource(dsid);
+    data_sources_setup_.erase(dsid);
+    return;
+  }
+
+  if (cmd.has_setup_tracing()) {
+    std::unique_ptr<SharedMemory> ipc_shared_memory;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    const std::string& shm_key = cmd.setup_tracing().shm_key_windows();
+    if (!shm_key.empty())
+      ipc_shared_memory = SharedMemoryWindows::Attach(shm_key);
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+    // On Fuchsia, the embedder is responsible for routing the shared memory
+    // FD, which is provided to this code via a blocking callback.
+    PERFETTO_CHECK(receive_shmem_fd_cb_fuchsia_);
+
+    base::ScopedFile shmem_fd(receive_shmem_fd_cb_fuchsia_());
+    if (!shmem_fd) {
+      // Failure to get a shared memory buffer is a protocol violation and
+      // therefore we should drop the Protocol connection.
+      PERFETTO_ELOG("Could not get shared memory FD from embedder.");
+      ScheduleDisconnect();
+      return;
+    }
+
+    ipc_shared_memory =
+        PosixSharedMemory::AttachToFd(std::move(shmem_fd),
+                                      /*require_seals_if_supported=*/false);
+#else
+    base::ScopedFile shmem_fd = ipc_channel_->TakeReceivedFD();
+    if (shmem_fd) {
+      // TODO(primiano): handle mmap failure in case of OOM.
+      ipc_shared_memory =
+          PosixSharedMemory::AttachToFd(std::move(shmem_fd),
+                                        /*require_seals_if_supported=*/false);
+    }
+#endif
+    if (use_shmem_emulation_) {
+      PERFETTO_CHECK(!ipc_shared_memory);
+      // Need to create an emulated shmem buffer when the transport deosn't
+      // support it.
+      // TODO(chinglinyu): Let the tracing service decide on the shmem size and
+      // propagate the size in InitializeConnectionResponse.
+      ipc_shared_memory = InProcessSharedMemory::Create(
+          /*size=*/InProcessSharedMemory::kDefaultSize);
+    }
+    if (ipc_shared_memory) {
+      auto shmem_mode = use_shmem_emulation_
+                            ? SharedMemoryABI::ShmemMode::kShmemEmulation
+                            : SharedMemoryABI::ShmemMode::kDefault;
+      // This is the nominal case used in most configurations, where the service
+      // provides the SMB.
+      PERFETTO_CHECK(!is_shmem_provided_by_producer_ && !shared_memory_);
+      shared_memory_ = std::move(ipc_shared_memory);
+      shared_buffer_page_size_kb_ =
+          cmd.setup_tracing().shared_buffer_page_size_kb();
+      shared_memory_arbiter_ = SharedMemoryArbiter::CreateInstance(
+          shared_memory_.get(), shared_buffer_page_size_kb_ * 1024, shmem_mode,
+          this, task_runner_);
+      if (direct_smb_patching_supported_)
+        shared_memory_arbiter_->SetDirectSMBPatchingSupportedByService();
+    } else {
+      // Producer-provided SMB (used by Chrome for startup tracing).
+      PERFETTO_CHECK(is_shmem_provided_by_producer_ && shared_memory_ &&
+                     shared_memory_arbiter_);
+    }
+    producer_->OnTracingSetup();
+    return;
+  }
+
+  if (cmd.has_flush()) {
+    // This cast boilerplate is required only because protobuf uses its own
+    // uint64 and not stdint's uint64_t. On some 64 bit archs they differ on the
+    // type (long vs long long) even though they have the same size.
+    const auto* data_source_ids = cmd.flush().data_source_ids().data();
+    static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
+                  "data_source_ids should be 64-bit");
+
+    FlushFlags flags(cmd.flush().flags());
+    producer_->Flush(
+        cmd.flush().request_id(),
+        reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
+        static_cast<size_t>(cmd.flush().data_source_ids().size()), flags);
+    return;
+  }
+
+  if (cmd.has_clear_incremental_state()) {
+    const auto* data_source_ids =
+        cmd.clear_incremental_state().data_source_ids().data();
+    static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
+                  "data_source_ids should be 64-bit");
+    producer_->ClearIncrementalState(
+        reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
+        static_cast<size_t>(
+            cmd.clear_incremental_state().data_source_ids().size()));
+    return;
+  }
+
+  PERFETTO_DFATAL("Unknown async request received from tracing service");
+}
+
+void ProducerIPCClientImpl::RegisterDataSource(
+    const DataSourceDescriptor& descriptor) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot RegisterDataSource(), not connected to tracing service");
+  }
+  protos::gen::RegisterDataSourceRequest req;
+  *req.mutable_data_source_descriptor() = descriptor;
+  ipc::Deferred<protos::gen::RegisterDataSourceResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::RegisterDataSourceResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("RegisterDataSource() failed: connection reset");
+      });
+  producer_port_->RegisterDataSource(req, std::move(async_response));
+}
+
+void ProducerIPCClientImpl::UpdateDataSource(
+    const DataSourceDescriptor& descriptor) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot UpdateDataSource(), not connected to tracing service");
+  }
+  protos::gen::UpdateDataSourceRequest req;
+  *req.mutable_data_source_descriptor() = descriptor;
+  ipc::Deferred<protos::gen::UpdateDataSourceResponse> async_response;
+  async_response.Bind(
+      [](ipc::AsyncResult<protos::gen::UpdateDataSourceResponse> response) {
+        if (!response)
+          PERFETTO_DLOG("UpdateDataSource() failed: connection reset");
+      });
+  producer_port_->UpdateDataSource(req, std::move(async_response));
+}
+
+void ProducerIPCClientImpl::UnregisterDataSource(const std::string& name) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot UnregisterDataSource(), not connected to tracing service");
+    return;
+  }
+  protos::gen::UnregisterDataSourceRequest req;
+  req.set_data_source_name(name);
+  producer_port_->UnregisterDataSource(
+      req, ipc::Deferred<protos::gen::UnregisterDataSourceResponse>());
+}
+
+void ProducerIPCClientImpl::RegisterTraceWriter(uint32_t writer_id,
+                                                uint32_t target_buffer) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot RegisterTraceWriter(), not connected to tracing service");
+    return;
+  }
+  protos::gen::RegisterTraceWriterRequest req;
+  req.set_trace_writer_id(writer_id);
+  req.set_target_buffer(target_buffer);
+  producer_port_->RegisterTraceWriter(
+      req, ipc::Deferred<protos::gen::RegisterTraceWriterResponse>());
+}
+
+void ProducerIPCClientImpl::UnregisterTraceWriter(uint32_t writer_id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot UnregisterTraceWriter(), not connected to tracing service");
+    return;
+  }
+  protos::gen::UnregisterTraceWriterRequest req;
+  req.set_trace_writer_id(writer_id);
+  producer_port_->UnregisterTraceWriter(
+      req, ipc::Deferred<protos::gen::UnregisterTraceWriterResponse>());
+}
+
+void ProducerIPCClientImpl::CommitData(const CommitDataRequest& req,
+                                       CommitDataCallback callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG("Cannot CommitData(), not connected to tracing service");
+    return;
+  }
+  ipc::Deferred<protos::gen::CommitDataResponse> async_response;
+  // TODO(primiano): add a test that destroys ProducerIPCClientImpl soon after
+  // this call and checks that the callback is dropped.
+  if (callback) {
+    async_response.Bind(
+        [callback](ipc::AsyncResult<protos::gen::CommitDataResponse> response) {
+          if (!response) {
+            PERFETTO_DLOG("CommitData() failed: connection reset");
+            return;
+          }
+          callback();
+        });
+  }
+  producer_port_->CommitData(req, std::move(async_response));
+}
+
+void ProducerIPCClientImpl::NotifyDataSourceStarted(DataSourceInstanceID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot NotifyDataSourceStarted(), not connected to tracing service");
+    return;
+  }
+  protos::gen::NotifyDataSourceStartedRequest req;
+  req.set_data_source_id(id);
+  producer_port_->NotifyDataSourceStarted(
+      req, ipc::Deferred<protos::gen::NotifyDataSourceStartedResponse>());
+}
+
+void ProducerIPCClientImpl::NotifyDataSourceStopped(DataSourceInstanceID id) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot NotifyDataSourceStopped(), not connected to tracing service");
+    return;
+  }
+  protos::gen::NotifyDataSourceStoppedRequest req;
+  req.set_data_source_id(id);
+  producer_port_->NotifyDataSourceStopped(
+      req, ipc::Deferred<protos::gen::NotifyDataSourceStoppedResponse>());
+}
+
+void ProducerIPCClientImpl::ActivateTriggers(
+    const std::vector<std::string>& triggers) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    PERFETTO_DLOG(
+        "Cannot ActivateTriggers(), not connected to tracing service");
+    return;
+  }
+  protos::gen::ActivateTriggersRequest proto_req;
+  for (const auto& name : triggers) {
+    *proto_req.add_trigger_names() = name;
+  }
+  producer_port_->ActivateTriggers(
+      proto_req, ipc::Deferred<protos::gen::ActivateTriggersResponse>());
+}
+
+void ProducerIPCClientImpl::Sync(std::function<void()> callback) {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!connected_) {
+    pending_sync_reqs_.emplace_back(std::move(callback));
+    return;
+  }
+  ipc::Deferred<protos::gen::SyncResponse> resp;
+  resp.Bind([callback](ipc::AsyncResult<protos::gen::SyncResponse>) {
+    // Here we ACK the callback even if the service replies with a failure
+    // (i.e. the service is too old and doesn't understand Sync()). In that
+    // case the service has still seen the request, the IPC roundtrip is
+    // still a (weaker) linearization fence.
+    callback();
+  });
+  producer_port_->Sync(protos::gen::SyncRequest(), std::move(resp));
+}
+
+std::unique_ptr<TraceWriter> ProducerIPCClientImpl::CreateTraceWriter(
+    BufferID target_buffer,
+    BufferExhaustedPolicy buffer_exhausted_policy) {
+  // This method can be called by different threads. |shared_memory_arbiter_| is
+  // thread-safe but be aware of accessing any other state in this function.
+  return shared_memory_arbiter_->CreateTraceWriter(target_buffer,
+                                                   buffer_exhausted_policy);
+}
+
+SharedMemoryArbiter* ProducerIPCClientImpl::MaybeSharedMemoryArbiter() {
+  return shared_memory_arbiter_.get();
+}
+
+bool ProducerIPCClientImpl::IsShmemProvidedByProducer() const {
+  return is_shmem_provided_by_producer_;
+}
+
+void ProducerIPCClientImpl::NotifyFlushComplete(FlushRequestID req_id) {
+  return shared_memory_arbiter_->NotifyFlushComplete(req_id);
+}
+
+SharedMemory* ProducerIPCClientImpl::shared_memory() const {
+  return shared_memory_.get();
+}
+
+size_t ProducerIPCClientImpl::shared_buffer_page_size_kb() const {
+  return shared_buffer_page_size_kb_;
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/service/consumer_ipc_service.cc
+// gen_amalgamated begin header: src/tracing/ipc/service/consumer_ipc_service.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
+#define SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
+
+#include <list>
+#include <map>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
+
+namespace perfetto {
+
+namespace ipc {
+class Host;
+}  // namespace ipc
+
+// Implements the Consumer port of the IPC service. This class proxies requests
+// and responses between the core service logic (|svc_|) and remote Consumer(s)
+// on the IPC socket, through the methods overriddden from ConsumerPort.
+class ConsumerIPCService : public protos::gen::ConsumerPort {
+ public:
+  explicit ConsumerIPCService(TracingService* core_service);
+  ~ConsumerIPCService() override;
+
+  // ConsumerPort implementation (from .proto IPC definition).
+  void EnableTracing(const protos::gen::EnableTracingRequest&,
+                     DeferredEnableTracingResponse) override;
+  void StartTracing(const protos::gen::StartTracingRequest&,
+                    DeferredStartTracingResponse) override;
+  void ChangeTraceConfig(const protos::gen::ChangeTraceConfigRequest&,
+                         DeferredChangeTraceConfigResponse) override;
+  void DisableTracing(const protos::gen::DisableTracingRequest&,
+                      DeferredDisableTracingResponse) override;
+  void ReadBuffers(const protos::gen::ReadBuffersRequest&,
+                   DeferredReadBuffersResponse) override;
+  void FreeBuffers(const protos::gen::FreeBuffersRequest&,
+                   DeferredFreeBuffersResponse) override;
+  void Flush(const protos::gen::FlushRequest&, DeferredFlushResponse) override;
+  void Detach(const protos::gen::DetachRequest&,
+              DeferredDetachResponse) override;
+  void Attach(const protos::gen::AttachRequest&,
+              DeferredAttachResponse) override;
+  void GetTraceStats(const protos::gen::GetTraceStatsRequest&,
+                     DeferredGetTraceStatsResponse) override;
+  void ObserveEvents(const protos::gen::ObserveEventsRequest&,
+                     DeferredObserveEventsResponse) override;
+  void QueryServiceState(const protos::gen::QueryServiceStateRequest&,
+                         DeferredQueryServiceStateResponse) override;
+  void QueryCapabilities(const protos::gen::QueryCapabilitiesRequest&,
+                         DeferredQueryCapabilitiesResponse) override;
+  void SaveTraceForBugreport(const protos::gen::SaveTraceForBugreportRequest&,
+                             DeferredSaveTraceForBugreportResponse) override;
+  void CloneSession(const protos::gen::CloneSessionRequest&,
+                    DeferredCloneSessionResponse) override;
+  void OnClientDisconnected() override;
+
+ private:
+  // Acts like a Consumer with the core Service business logic (which doesn't
+  // know anything about the remote transport), but all it does is proxying
+  // methods to the remote Consumer on the other side of the IPC channel.
+  class RemoteConsumer : public Consumer {
+   public:
+    RemoteConsumer();
+    ~RemoteConsumer() override;
+
+    // These methods are called by the |core_service_| business logic. There is
+    // no connection here, these methods are posted straight away.
+    void OnConnect() override;
+    void OnDisconnect() override;
+    void OnTracingDisabled(const std::string& error) override;
+    void OnTraceData(std::vector<TracePacket>, bool has_more) override;
+    void OnDetach(bool) override;
+    void OnAttach(bool, const TraceConfig&) override;
+    void OnTraceStats(bool, const TraceStats&) override;
+    void OnObservableEvents(const ObservableEvents&) override;
+    void OnSessionCloned(const OnSessionClonedArgs&) override;
+
+    void CloseObserveEventsResponseStream();
+
+    // The interface obtained from the core service business logic through
+    // TracingService::ConnectConsumer(this). This allows to invoke methods for
+    // a specific Consumer on the Service business logic.
+    std::unique_ptr<TracingService::ConsumerEndpoint> service_endpoint;
+
+    // After ReadBuffers() is invoked, this binds the async callback that
+    // allows to stream trace packets back to the client.
+    DeferredReadBuffersResponse read_buffers_response;
+
+    // After EnableTracing() is invoked, this binds the async callback that
+    // allows to send the OnTracingDisabled notification.
+    DeferredEnableTracingResponse enable_tracing_response;
+
+    // After Detach() is invoked, this binds the async callback that allows to
+    // send the session id to the consumer.
+    DeferredDetachResponse detach_response;
+
+    // As above, but for the Attach() case.
+    DeferredAttachResponse attach_response;
+
+    // As above, but for GetTraceStats().
+    DeferredGetTraceStatsResponse get_trace_stats_response;
+
+    // As above, but for CloneSession().
+    DeferredCloneSessionResponse clone_session_response;
+
+    // After ObserveEvents() is invoked, this binds the async callback that
+    // allows to stream ObservableEvents back to the client.
+    DeferredObserveEventsResponse observe_events_response;
+  };
+
+  // This has to be a container that doesn't invalidate iterators.
+  using PendingFlushResponses = std::list<DeferredFlushResponse>;
+  using PendingQuerySvcResponses = std::list<DeferredQueryServiceStateResponse>;
+  using PendingQueryCapabilitiesResponses =
+      std::list<DeferredQueryCapabilitiesResponse>;
+  using PendingSaveTraceForBugreportResponses =
+      std::list<DeferredSaveTraceForBugreportResponse>;
+
+  ConsumerIPCService(const ConsumerIPCService&) = delete;
+  ConsumerIPCService& operator=(const ConsumerIPCService&) = delete;
+
+  // Returns the ConsumerEndpoint in the core business logic that corresponds to
+  // the current IPC request.
+  RemoteConsumer* GetConsumerForCurrentRequest();
+
+  void OnFlushCallback(bool success, PendingFlushResponses::iterator);
+  void OnQueryServiceCallback(bool success,
+                              const TracingServiceState&,
+                              PendingQuerySvcResponses::iterator);
+  void OnQueryCapabilitiesCallback(const TracingServiceCapabilities&,
+                                   PendingQueryCapabilitiesResponses::iterator);
+  void OnSaveTraceForBugreportCallback(
+      bool success,
+      const std::string& msg,
+      PendingSaveTraceForBugreportResponses::iterator);
+
+  TracingService* const core_service_;
+
+  // Maps IPC clients to ConsumerEndpoint instances registered on the
+  // |core_service_| business logic.
+  std::map<ipc::ClientID, std::unique_ptr<RemoteConsumer>> consumers_;
+
+  PendingFlushResponses pending_flush_responses_;
+  PendingQuerySvcResponses pending_query_service_responses_;
+  PendingQueryCapabilitiesResponses pending_query_capabilities_responses_;
+  PendingSaveTraceForBugreportResponses pending_bugreport_responses_;
+
+  base::WeakPtrFactory<ConsumerIPCService> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
+
+namespace perfetto {
+
+ConsumerIPCService::ConsumerIPCService(TracingService* core_service)
+    : core_service_(core_service), weak_ptr_factory_(this) {}
+
+ConsumerIPCService::~ConsumerIPCService() = default;
+
+ConsumerIPCService::RemoteConsumer*
+ConsumerIPCService::GetConsumerForCurrentRequest() {
+  const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
+  const uid_t uid = ipc::Service::client_info().uid();
+  PERFETTO_CHECK(ipc_client_id);
+  auto it = consumers_.find(ipc_client_id);
+  if (it == consumers_.end()) {
+    auto* remote_consumer = new RemoteConsumer();
+    consumers_[ipc_client_id].reset(remote_consumer);
+    remote_consumer->service_endpoint =
+        core_service_->ConnectConsumer(remote_consumer, uid);
+    return remote_consumer;
+  }
+  return it->second.get();
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::OnClientDisconnected() {
+  ipc::ClientID client_id = ipc::Service::client_info().client_id();
+  consumers_.erase(client_id);
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::EnableTracing(
+    const protos::gen::EnableTracingRequest& req,
+    DeferredEnableTracingResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  if (req.attach_notification_only()) {
+    remote_consumer->enable_tracing_response = std::move(resp);
+    return;
+  }
+  const TraceConfig& trace_config = req.trace_config();
+  base::ScopedFile fd;
+  if (trace_config.write_into_file() && trace_config.output_path().empty())
+    fd = ipc::Service::TakeReceivedFD();
+  remote_consumer->service_endpoint->EnableTracing(trace_config, std::move(fd));
+  remote_consumer->enable_tracing_response = std::move(resp);
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::StartTracing(const protos::gen::StartTracingRequest&,
+                                      DeferredStartTracingResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->service_endpoint->StartTracing();
+  resp.Resolve(ipc::AsyncResult<protos::gen::StartTracingResponse>::Create());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::ChangeTraceConfig(
+    const protos::gen::ChangeTraceConfigRequest& req,
+    DeferredChangeTraceConfigResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->service_endpoint->ChangeTraceConfig(req.trace_config());
+  resp.Resolve(
+      ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse>::Create());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::DisableTracing(
+    const protos::gen::DisableTracingRequest&,
+    DeferredDisableTracingResponse resp) {
+  GetConsumerForCurrentRequest()->service_endpoint->DisableTracing();
+  resp.Resolve(ipc::AsyncResult<protos::gen::DisableTracingResponse>::Create());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::ReadBuffers(const protos::gen::ReadBuffersRequest&,
+                                     DeferredReadBuffersResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->read_buffers_response = std::move(resp);
+  remote_consumer->service_endpoint->ReadBuffers();
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::FreeBuffers(const protos::gen::FreeBuffersRequest&,
+                                     DeferredFreeBuffersResponse resp) {
+  GetConsumerForCurrentRequest()->service_endpoint->FreeBuffers();
+  resp.Resolve(ipc::AsyncResult<protos::gen::FreeBuffersResponse>::Create());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::Flush(const protos::gen::FlushRequest& req,
+                               DeferredFlushResponse resp) {
+  auto it = pending_flush_responses_.insert(pending_flush_responses_.end(),
+                                            std::move(resp));
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto callback = [weak_this, it](bool success) {
+    if (weak_this)
+      weak_this->OnFlushCallback(success, std::move(it));
+  };
+  FlushFlags flags(req.flags());
+  GetConsumerForCurrentRequest()->service_endpoint->Flush(
+      req.timeout_ms(), std::move(callback), flags);
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::Detach(const protos::gen::DetachRequest& req,
+                                DeferredDetachResponse resp) {
+  // OnDetach() will resolve the |detach_response|.
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->detach_response = std::move(resp);
+  remote_consumer->service_endpoint->Detach(req.key());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::Attach(const protos::gen::AttachRequest& req,
+                                DeferredAttachResponse resp) {
+  // OnAttach() will resolve the |attach_response|.
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->attach_response = std::move(resp);
+  remote_consumer->service_endpoint->Attach(req.key());
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::GetTraceStats(const protos::gen::GetTraceStatsRequest&,
+                                       DeferredGetTraceStatsResponse resp) {
+  // OnTraceStats() will resolve the |get_trace_stats_response|.
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->get_trace_stats_response = std::move(resp);
+  remote_consumer->service_endpoint->GetTraceStats();
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::ObserveEvents(
+    const protos::gen::ObserveEventsRequest& req,
+    DeferredObserveEventsResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+
+  // If there's a prior stream, close it so that client can clean it up.
+  remote_consumer->CloseObserveEventsResponseStream();
+
+  remote_consumer->observe_events_response = std::move(resp);
+
+  uint32_t events_mask = 0;
+  for (const auto& type : req.events_to_observe()) {
+    events_mask |= static_cast<uint32_t>(type);
+  }
+  remote_consumer->service_endpoint->ObserveEvents(events_mask);
+
+  // If no events are to be observed, close the stream immediately so that the
+  // client can clean up.
+  if (events_mask == 0)
+    remote_consumer->CloseObserveEventsResponseStream();
+}
+
+// Called by the IPC layer.
+void ConsumerIPCService::QueryServiceState(
+    const protos::gen::QueryServiceStateRequest&,
+    DeferredQueryServiceStateResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  auto it = pending_query_service_responses_.insert(
+      pending_query_service_responses_.end(), std::move(resp));
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto callback = [weak_this, it](bool success,
+                                  const TracingServiceState& svc_state) {
+    if (weak_this)
+      weak_this->OnQueryServiceCallback(success, svc_state, std::move(it));
+  };
+  remote_consumer->service_endpoint->QueryServiceState(callback);
+}
+
+// Called by the service in response to service_endpoint->QueryServiceState().
+void ConsumerIPCService::OnQueryServiceCallback(
+    bool success,
+    const TracingServiceState& svc_state,
+    PendingQuerySvcResponses::iterator pending_response_it) {
+  DeferredQueryServiceStateResponse response(std::move(*pending_response_it));
+  pending_query_service_responses_.erase(pending_response_it);
+  if (!success) {
+    response.Reject();
+    return;
+  }
+
+  // The TracingServiceState object might be too big to fit into a single IPC
+  // message because it contains the DataSourceDescriptor of each data source.
+  // Here we split it in chunks to fit in the IPC limit, observing the
+  // following rule: each chunk must be invididually a valid TracingServiceState
+  // message; all the chunks concatenated together must form the original
+  // message. This is to deal with the legacy API that was just sending one
+  // whole message (failing in presence of too many data sources, b/153142114).
+  // The message is split as follows: we take the whole TracingServiceState,
+  // take out the data sources section (which is a top-level repeated field)
+  // and re-add them one-by-one. If, in the process of appending, the IPC msg
+  // size is reached, a new chunk is created. This assumes that the rest of
+  // TracingServiceState fits in one IPC message and each DataSourceDescriptor
+  // fits in the worst case in a dedicated message (which is true, because
+  // otherwise the RegisterDataSource() which passes the descriptor in the first
+  // place would fail).
+
+  std::vector<uint8_t> chunked_reply;
+
+  // Transmits the current chunk and starts a new one.
+  bool sent_eof = false;
+  auto send_chunked_reply = [&chunked_reply, &response,
+                             &sent_eof](bool has_more) {
+    PERFETTO_CHECK(!sent_eof);
+    sent_eof = !has_more;
+    auto resp =
+        ipc::AsyncResult<protos::gen::QueryServiceStateResponse>::Create();
+    resp.set_has_more(has_more);
+    PERFETTO_CHECK(resp->mutable_service_state()->ParseFromArray(
+        chunked_reply.data(), chunked_reply.size()));
+    chunked_reply.clear();
+    response.Resolve(std::move(resp));
+  };
+
+  // Create a copy of the whole response and cut away the data_sources section.
+  protos::gen::TracingServiceState svc_state_copy = svc_state;
+  auto data_sources = std::move(*svc_state_copy.mutable_data_sources());
+  chunked_reply = svc_state_copy.SerializeAsArray();
+
+  // Now re-add them fitting within the IPC message limits (- some margin for
+  // the outer IPC frame).
+  constexpr size_t kMaxMsgSize = ipc::kIPCBufferSize - 128;
+  for (const auto& data_source : data_sources) {
+    protos::gen::TracingServiceState tmp;
+    tmp.mutable_data_sources()->emplace_back(std::move(data_source));
+    std::vector<uint8_t> chunk = tmp.SerializeAsArray();
+    if (chunked_reply.size() + chunk.size() < kMaxMsgSize) {
+      chunked_reply.insert(chunked_reply.end(), chunk.begin(), chunk.end());
+    } else {
+      send_chunked_reply(/*has_more=*/true);
+      chunked_reply = std::move(chunk);
+    }
+  }
+
+  PERFETTO_DCHECK(!chunked_reply.empty());
+  send_chunked_reply(/*has_more=*/false);
+  PERFETTO_CHECK(sent_eof);
+}
+
+// Called by the service in response to a service_endpoint->Flush() request.
+void ConsumerIPCService::OnFlushCallback(
+    bool success,
+    PendingFlushResponses::iterator pending_response_it) {
+  DeferredFlushResponse response(std::move(*pending_response_it));
+  pending_flush_responses_.erase(pending_response_it);
+  if (success) {
+    response.Resolve(ipc::AsyncResult<protos::gen::FlushResponse>::Create());
+  } else {
+    response.Reject();
+  }
+}
+
+void ConsumerIPCService::QueryCapabilities(
+    const protos::gen::QueryCapabilitiesRequest&,
+    DeferredQueryCapabilitiesResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  auto it = pending_query_capabilities_responses_.insert(
+      pending_query_capabilities_responses_.end(), std::move(resp));
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto callback = [weak_this, it](const TracingServiceCapabilities& caps) {
+    if (weak_this)
+      weak_this->OnQueryCapabilitiesCallback(caps, std::move(it));
+  };
+  remote_consumer->service_endpoint->QueryCapabilities(callback);
+}
+
+// Called by the service in response to service_endpoint->QueryCapabilities().
+void ConsumerIPCService::OnQueryCapabilitiesCallback(
+    const TracingServiceCapabilities& caps,
+    PendingQueryCapabilitiesResponses::iterator pending_response_it) {
+  DeferredQueryCapabilitiesResponse response(std::move(*pending_response_it));
+  pending_query_capabilities_responses_.erase(pending_response_it);
+  auto resp =
+      ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse>::Create();
+  *resp->mutable_capabilities() = caps;
+  response.Resolve(std::move(resp));
+}
+
+void ConsumerIPCService::SaveTraceForBugreport(
+    const protos::gen::SaveTraceForBugreportRequest&,
+    DeferredSaveTraceForBugreportResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  auto it = pending_bugreport_responses_.insert(
+      pending_bugreport_responses_.end(), std::move(resp));
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto callback = [weak_this, it](bool success, const std::string& msg) {
+    if (weak_this)
+      weak_this->OnSaveTraceForBugreportCallback(success, msg, std::move(it));
+  };
+  remote_consumer->service_endpoint->SaveTraceForBugreport(callback);
+}
+
+void ConsumerIPCService::CloneSession(
+    const protos::gen::CloneSessionRequest& req,
+    DeferredCloneSessionResponse resp) {
+  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
+  remote_consumer->clone_session_response = std::move(resp);
+  remote_consumer->service_endpoint->CloneSession(req.session_id());
+}
+
+// Called by the service in response to
+// service_endpoint->SaveTraceForBugreport().
+void ConsumerIPCService::OnSaveTraceForBugreportCallback(
+    bool success,
+    const std::string& msg,
+    PendingSaveTraceForBugreportResponses::iterator pending_response_it) {
+  DeferredSaveTraceForBugreportResponse response(
+      std::move(*pending_response_it));
+  pending_bugreport_responses_.erase(pending_response_it);
+  auto resp =
+      ipc::AsyncResult<protos::gen::SaveTraceForBugreportResponse>::Create();
+  resp->set_success(success);
+  resp->set_msg(msg);
+  response.Resolve(std::move(resp));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RemoteConsumer methods
+////////////////////////////////////////////////////////////////////////////////
+
+ConsumerIPCService::RemoteConsumer::RemoteConsumer() = default;
+ConsumerIPCService::RemoteConsumer::~RemoteConsumer() = default;
+
+// Invoked by the |core_service_| business logic after the ConnectConsumer()
+// call. There is nothing to do here, we really expected the ConnectConsumer()
+// to just work in the local case.
+void ConsumerIPCService::RemoteConsumer::OnConnect() {}
+
+// Invoked by the |core_service_| business logic after we destroy the
+// |service_endpoint| (in the RemoteConsumer dtor).
+void ConsumerIPCService::RemoteConsumer::OnDisconnect() {}
+
+void ConsumerIPCService::RemoteConsumer::OnTracingDisabled(
+    const std::string& error) {
+  if (enable_tracing_response.IsBound()) {
+    auto result =
+        ipc::AsyncResult<protos::gen::EnableTracingResponse>::Create();
+    result->set_disabled(true);
+    if (!error.empty())
+      result->set_error(error);
+    enable_tracing_response.Resolve(std::move(result));
+  }
+}
+
+void ConsumerIPCService::RemoteConsumer::OnTraceData(
+    std::vector<TracePacket> trace_packets,
+    bool has_more) {
+  if (!read_buffers_response.IsBound())
+    return;
+
+  auto result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
+
+  // A TracePacket might be too big to fit into a single IPC message (max
+  // kIPCBufferSize). However a TracePacket is made of slices and each slice
+  // is way smaller than kIPCBufferSize (a slice size is effectively bounded by
+  // the max chunk size of the SharedMemoryABI). When sending a TracePacket,
+  // if its slices don't fit within one IPC, chunk them over several contiguous
+  // IPCs using the |last_slice_for_packet| for glueing on the other side.
+  static_assert(ipc::kIPCBufferSize >= SharedMemoryABI::kMaxPageSize * 2,
+                "kIPCBufferSize too small given the max possible slice size");
+
+  auto send_ipc_reply = [this, &result](bool more) {
+    result.set_has_more(more);
+    read_buffers_response.Resolve(std::move(result));
+    result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
+  };
+
+  size_t approx_reply_size = 0;
+  for (const TracePacket& trace_packet : trace_packets) {
+    size_t num_slices_left_for_packet = trace_packet.slices().size();
+    for (const Slice& slice : trace_packet.slices()) {
+      // Check if this slice would cause the IPC to overflow its max size and,
+      // if that is the case, split the IPCs. The "16" and "64" below are
+      // over-estimations of, respectively:
+      // 16: the preamble that prefixes each slice (there are 2 x size fields
+      //     in the proto + the |last_slice_for_packet| bool).
+      // 64: the overhead of the IPC InvokeMethodReply + wire_protocol's frame.
+      // If these estimations are wrong, BufferedFrameDeserializer::Serialize()
+      // will hit a DCHECK anyways.
+      const size_t approx_slice_size = slice.size + 16;
+      if (approx_reply_size + approx_slice_size > ipc::kIPCBufferSize - 64) {
+        // If we hit this CHECK we got a single slice that is > kIPCBufferSize.
+        PERFETTO_CHECK(result->slices_size() > 0);
+        send_ipc_reply(/*has_more=*/true);
+        approx_reply_size = 0;
+      }
+      approx_reply_size += approx_slice_size;
+
+      auto* res_slice = result->add_slices();
+      res_slice->set_last_slice_for_packet(--num_slices_left_for_packet == 0);
+      res_slice->set_data(slice.start, slice.size);
+    }
+  }
+  send_ipc_reply(has_more);
+}
+
+void ConsumerIPCService::RemoteConsumer::OnDetach(bool success) {
+  if (!success) {
+    std::move(detach_response).Reject();
+    return;
+  }
+  auto resp = ipc::AsyncResult<protos::gen::DetachResponse>::Create();
+  std::move(detach_response).Resolve(std::move(resp));
+}
+
+void ConsumerIPCService::RemoteConsumer::OnAttach(
+    bool success,
+    const TraceConfig& trace_config) {
+  if (!success) {
+    std::move(attach_response).Reject();
+    return;
+  }
+  auto response = ipc::AsyncResult<protos::gen::AttachResponse>::Create();
+  *response->mutable_trace_config() = trace_config;
+  std::move(attach_response).Resolve(std::move(response));
+}
+
+void ConsumerIPCService::RemoteConsumer::OnTraceStats(bool success,
+                                                      const TraceStats& stats) {
+  if (!success) {
+    std::move(get_trace_stats_response).Reject();
+    return;
+  }
+  auto response =
+      ipc::AsyncResult<protos::gen::GetTraceStatsResponse>::Create();
+  *response->mutable_trace_stats() = stats;
+  std::move(get_trace_stats_response).Resolve(std::move(response));
+}
+
+void ConsumerIPCService::RemoteConsumer::OnObservableEvents(
+    const ObservableEvents& events) {
+  if (!observe_events_response.IsBound())
+    return;
+
+  auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
+  result.set_has_more(true);
+  *result->mutable_events() = events;
+  observe_events_response.Resolve(std::move(result));
+}
+
+void ConsumerIPCService::RemoteConsumer::CloseObserveEventsResponseStream() {
+  if (!observe_events_response.IsBound())
+    return;
+
+  auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
+  result.set_has_more(false);
+  observe_events_response.Resolve(std::move(result));
+}
+
+void ConsumerIPCService::RemoteConsumer::OnSessionCloned(
+    const OnSessionClonedArgs& args) {
+  if (!clone_session_response.IsBound())
+    return;
+
+  auto resp = ipc::AsyncResult<protos::gen::CloneSessionResponse>::Create();
+  resp->set_success(args.success);
+  resp->set_error(args.error);
+  resp->set_uuid_msb(args.uuid.msb());
+  resp->set_uuid_lsb(args.uuid.lsb());
+  std::move(clone_session_response).Resolve(std::move(resp));
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/service/producer_ipc_service.cc
+// gen_amalgamated begin header: src/tracing/ipc/service/producer_ipc_service.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
+#define SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
+
+#include <list>
+#include <map>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
+
+namespace perfetto {
+
+namespace ipc {
+class Host;
+}  // namespace ipc
+
+// Implements the Producer port of the IPC service. This class proxies requests
+// and responses between the core service logic (|svc_|) and remote Producer(s)
+// on the IPC socket, through the methods overriddden from ProducerPort.
+class ProducerIPCService : public protos::gen::ProducerPort {
+ public:
+  explicit ProducerIPCService(TracingService* core_service);
+  ~ProducerIPCService() override;
+
+  // ProducerPort implementation (from .proto IPC definition).
+  void InitializeConnection(const protos::gen::InitializeConnectionRequest&,
+                            DeferredInitializeConnectionResponse) override;
+  void RegisterDataSource(const protos::gen::RegisterDataSourceRequest&,
+                          DeferredRegisterDataSourceResponse) override;
+  void UpdateDataSource(const protos::gen::UpdateDataSourceRequest&,
+                        DeferredUpdateDataSourceResponse) override;
+  void UnregisterDataSource(const protos::gen::UnregisterDataSourceRequest&,
+                            DeferredUnregisterDataSourceResponse) override;
+  void RegisterTraceWriter(const protos::gen::RegisterTraceWriterRequest&,
+                           DeferredRegisterTraceWriterResponse) override;
+  void UnregisterTraceWriter(const protos::gen::UnregisterTraceWriterRequest&,
+                             DeferredUnregisterTraceWriterResponse) override;
+  void CommitData(const protos::gen::CommitDataRequest&,
+                  DeferredCommitDataResponse) override;
+  void NotifyDataSourceStarted(
+      const protos::gen::NotifyDataSourceStartedRequest&,
+      DeferredNotifyDataSourceStartedResponse) override;
+  void NotifyDataSourceStopped(
+      const protos::gen::NotifyDataSourceStoppedRequest&,
+      DeferredNotifyDataSourceStoppedResponse) override;
+  void ActivateTriggers(const protos::gen::ActivateTriggersRequest&,
+                        DeferredActivateTriggersResponse) override;
+
+  void GetAsyncCommand(const protos::gen::GetAsyncCommandRequest&,
+                       DeferredGetAsyncCommandResponse) override;
+  void Sync(const protos::gen::SyncRequest&, DeferredSyncResponse) override;
+  void OnClientDisconnected() override;
+
+ private:
+  // Acts like a Producer with the core Service business logic (which doesn't
+  // know anything about the remote transport), but all it does is proxying
+  // methods to the remote Producer on the other side of the IPC channel.
+  class RemoteProducer : public Producer {
+   public:
+    RemoteProducer();
+    ~RemoteProducer() override;
+
+    // These methods are called by the |core_service_| business logic. There is
+    // no connection here, these methods are posted straight away.
+    void OnConnect() override;
+    void OnDisconnect() override;
+    void SetupDataSource(DataSourceInstanceID,
+                         const DataSourceConfig&) override;
+    void StartDataSource(DataSourceInstanceID,
+                         const DataSourceConfig&) override;
+    void StopDataSource(DataSourceInstanceID) override;
+    void OnTracingSetup() override;
+    void Flush(FlushRequestID,
+               const DataSourceInstanceID* data_source_ids,
+               size_t num_data_sources,
+               FlushFlags) override;
+
+    void ClearIncrementalState(const DataSourceInstanceID* data_source_ids,
+                               size_t num_data_sources) override;
+
+    void SendSetupTracing();
+
+    // The interface obtained from the core service business logic through
+    // Service::ConnectProducer(this). This allows to invoke methods for a
+    // specific Producer on the Service business logic.
+    std::unique_ptr<TracingService::ProducerEndpoint> service_endpoint;
+
+    // The back-channel (based on a never ending stream request) that allows us
+    // to send asynchronous commands to the remote Producer (e.g. start/stop a
+    // data source).
+    DeferredGetAsyncCommandResponse async_producer_commands;
+
+    // Set if the service calls OnTracingSetup() before the
+    // |async_producer_commands| was bound by the service. In this case, we
+    // forward the SetupTracing command when it is bound later.
+    bool send_setup_tracing_on_async_commands_bound = false;
+  };
+
+  ProducerIPCService(const ProducerIPCService&) = delete;
+  ProducerIPCService& operator=(const ProducerIPCService&) = delete;
+
+  // Returns the ProducerEndpoint in the core business logic that corresponds to
+  // the current IPC request.
+  RemoteProducer* GetProducerForCurrentRequest();
+
+  TracingService* const core_service_;
+
+  // Maps IPC clients to ProducerEndpoint instances registered on the
+  // |core_service_| business logic.
+  std::map<ipc::ClientID, std::unique_ptr<RemoteProducer>> producers_;
+
+  // List because pointers need to be stable.
+  std::list<DeferredSyncResponse> pending_syncs_;
+
+  base::WeakPtrFactory<ProducerIPCService> weak_ptr_factory_;  // Keep last.
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
+
+#include <cinttypes>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
+#else
+// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
+#endif
+
+// The remote Producer(s) are not trusted. All the methods from the ProducerPort
+// IPC layer (e.g. RegisterDataSource()) must assume that the remote Producer is
+// compromised.
+
+namespace perfetto {
+
+ProducerIPCService::ProducerIPCService(TracingService* core_service)
+    : core_service_(core_service), weak_ptr_factory_(this) {}
+
+ProducerIPCService::~ProducerIPCService() = default;
+
+ProducerIPCService::RemoteProducer*
+ProducerIPCService::GetProducerForCurrentRequest() {
+  const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
+  PERFETTO_CHECK(ipc_client_id);
+  auto it = producers_.find(ipc_client_id);
+  if (it == producers_.end())
+    return nullptr;
+  return it->second.get();
+}
+
+// Called by the remote Producer through the IPC channel soon after connecting.
+void ProducerIPCService::InitializeConnection(
+    const protos::gen::InitializeConnectionRequest& req,
+    DeferredInitializeConnectionResponse response) {
+  const auto& client_info = ipc::Service::client_info();
+  const ipc::ClientID ipc_client_id = client_info.client_id();
+  PERFETTO_CHECK(ipc_client_id);
+
+  if (producers_.count(ipc_client_id) > 0) {
+    PERFETTO_DLOG(
+        "The remote Producer is trying to re-initialize the connection");
+    return response.Reject();
+  }
+
+  // Create a new entry.
+  std::unique_ptr<RemoteProducer> producer(new RemoteProducer());
+
+  TracingService::ProducerSMBScrapingMode smb_scraping_mode =
+      TracingService::ProducerSMBScrapingMode::kDefault;
+  switch (req.smb_scraping_mode()) {
+    case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_UNSPECIFIED:
+      break;
+    case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED:
+      smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kDisabled;
+      break;
+    case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED:
+      smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kEnabled;
+      break;
+  }
+
+  // If the producer provided an SMB, tell the service to attempt to adopt it.
+  std::unique_ptr<SharedMemory> shmem;
+  if (req.producer_provided_shmem()) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    if (!req.has_shm_key_windows() || req.shm_key_windows().empty()) {
+      PERFETTO_ELOG(
+          "shm_key_windows must be non-empty when "
+          "producer_provided_shmem = true");
+    } else {
+      shmem = SharedMemoryWindows::Attach(req.shm_key_windows());
+      // Attach() does error logging if something fails, no need to extra ELOGs.
+    }
+#else
+    base::ScopedFile shmem_fd = ipc::Service::TakeReceivedFD();
+
+    if (shmem_fd) {
+      shmem = PosixSharedMemory::AttachToFd(
+          std::move(shmem_fd), /*require_seals_if_supported=*/true);
+      if (!shmem) {
+        PERFETTO_ELOG(
+            "Couldn't map producer-provided SMB, falling back to "
+            "service-provided SMB");
+      }
+    } else {
+      PERFETTO_DLOG(
+          "InitializeConnectionRequest's producer_provided_shmem flag is set "
+          "but the producer didn't provide an FD");
+    }
+#endif
+  }
+
+  // Copy the data fields to be emitted to trace packets into ClientIdentity.
+  ClientIdentity client_identity(client_info.uid(), client_info.pid(),
+                                 client_info.machine_id());
+  // ConnectProducer will call OnConnect() on the next task.
+  producer->service_endpoint = core_service_->ConnectProducer(
+      producer.get(), client_identity, req.producer_name(),
+      req.shared_memory_size_hint_bytes(),
+      /*in_process=*/false, smb_scraping_mode,
+      req.shared_memory_page_size_hint_bytes(), std::move(shmem),
+      req.sdk_version());
+
+  // Could happen if the service has too many producers connected.
+  if (!producer->service_endpoint) {
+    response.Reject();
+    return;
+  }
+
+  bool use_shmem_emulation = ipc::Service::use_shmem_emulation();
+  bool using_producer_shmem =
+      !use_shmem_emulation &&
+      producer->service_endpoint->IsShmemProvidedByProducer();
+
+  producers_.emplace(ipc_client_id, std::move(producer));
+  // Because of the std::move() |producer| is invalid after this point.
+
+  auto async_res =
+      ipc::AsyncResult<protos::gen::InitializeConnectionResponse>::Create();
+  async_res->set_using_shmem_provided_by_producer(using_producer_shmem);
+  async_res->set_direct_smb_patching_supported(true);
+  async_res->set_use_shmem_emulation(use_shmem_emulation);
+  response.Resolve(std::move(async_res));
+}
+
+// Called by the remote Producer through the IPC channel.
+void ProducerIPCService::RegisterDataSource(
+    const protos::gen::RegisterDataSourceRequest& req,
+    DeferredRegisterDataSourceResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked RegisterDataSource() before InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+
+  const DataSourceDescriptor& dsd = req.data_source_descriptor();
+  GetProducerForCurrentRequest()->service_endpoint->RegisterDataSource(dsd);
+
+  // RegisterDataSource doesn't expect any meaningful response.
+  if (response.IsBound()) {
+    response.Resolve(
+        ipc::AsyncResult<protos::gen::RegisterDataSourceResponse>::Create());
+  }
+}
+
+// Called by the remote Producer through the IPC channel.
+void ProducerIPCService::UpdateDataSource(
+    const protos::gen::UpdateDataSourceRequest& req,
+    DeferredUpdateDataSourceResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked UpdateDataSource() before InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+
+  const DataSourceDescriptor& dsd = req.data_source_descriptor();
+  GetProducerForCurrentRequest()->service_endpoint->UpdateDataSource(dsd);
+
+  // UpdateDataSource doesn't expect any meaningful response.
+  if (response.IsBound()) {
+    response.Resolve(
+        ipc::AsyncResult<protos::gen::UpdateDataSourceResponse>::Create());
+  }
+}
+
+// Called by the IPC layer.
+void ProducerIPCService::OnClientDisconnected() {
+  ipc::ClientID client_id = ipc::Service::client_info().client_id();
+  PERFETTO_DLOG("Client %" PRIu64 " disconnected", client_id);
+  producers_.erase(client_id);
+}
+
+// TODO(fmayer): test what happens if we receive the following tasks, in order:
+// RegisterDataSource, UnregisterDataSource, OnDataSourceRegistered.
+// which essentially means that the client posted back to back a
+// ReqisterDataSource and UnregisterDataSource speculating on the next id.
+// Called by the remote Service through the IPC channel.
+void ProducerIPCService::UnregisterDataSource(
+    const protos::gen::UnregisterDataSourceRequest& req,
+    DeferredUnregisterDataSourceResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked UnregisterDataSource() before "
+        "InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+  producer->service_endpoint->UnregisterDataSource(req.data_source_name());
+
+  // UnregisterDataSource doesn't expect any meaningful response.
+  if (response.IsBound()) {
+    response.Resolve(
+        ipc::AsyncResult<protos::gen::UnregisterDataSourceResponse>::Create());
+  }
+}
+
+void ProducerIPCService::RegisterTraceWriter(
+    const protos::gen::RegisterTraceWriterRequest& req,
+    DeferredRegisterTraceWriterResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked RegisterTraceWriter() before "
+        "InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+  producer->service_endpoint->RegisterTraceWriter(req.trace_writer_id(),
+                                                  req.target_buffer());
+
+  // RegisterTraceWriter doesn't expect any meaningful response.
+  if (response.IsBound()) {
+    response.Resolve(
+        ipc::AsyncResult<protos::gen::RegisterTraceWriterResponse>::Create());
+  }
+}
+
+void ProducerIPCService::UnregisterTraceWriter(
+    const protos::gen::UnregisterTraceWriterRequest& req,
+    DeferredUnregisterTraceWriterResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked UnregisterTraceWriter() before "
+        "InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+  producer->service_endpoint->UnregisterTraceWriter(req.trace_writer_id());
+
+  // UnregisterTraceWriter doesn't expect any meaningful response.
+  if (response.IsBound()) {
+    response.Resolve(
+        ipc::AsyncResult<protos::gen::UnregisterTraceWriterResponse>::Create());
+  }
+}
+
+void ProducerIPCService::CommitData(const protos::gen::CommitDataRequest& req,
+                                    DeferredCommitDataResponse resp) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked CommitData() before InitializeConnection()");
+    if (resp.IsBound())
+      resp.Reject();
+    return;
+  }
+
+  // We don't want to send a response if the client didn't attach a callback to
+  // the original request. Doing so would generate unnecessary wakeups and
+  // context switches.
+  std::function<void()> callback;
+  if (resp.IsBound()) {
+    // Capturing |resp| by reference here speculates on the fact that
+    // CommitData() in tracing_service_impl.cc invokes the passed callback
+    // inline, without posting it. If that assumption changes this code needs to
+    // wrap the response in a shared_ptr (C+11 lambdas don't support move) and
+    // use a weak ptr in the caller.
+    callback = [&resp] {
+      resp.Resolve(ipc::AsyncResult<protos::gen::CommitDataResponse>::Create());
+    };
+  }
+  producer->service_endpoint->CommitData(req, callback);
+}
+
+void ProducerIPCService::NotifyDataSourceStarted(
+    const protos::gen::NotifyDataSourceStartedRequest& request,
+    DeferredNotifyDataSourceStartedResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked NotifyDataSourceStarted() before "
+        "InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+  producer->service_endpoint->NotifyDataSourceStarted(request.data_source_id());
+
+  // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
+  // a useless IPC in that case.
+  if (response.IsBound()) {
+    response.Resolve(ipc::AsyncResult<
+                     protos::gen::NotifyDataSourceStartedResponse>::Create());
+  }
+}
+
+void ProducerIPCService::NotifyDataSourceStopped(
+    const protos::gen::NotifyDataSourceStoppedRequest& request,
+    DeferredNotifyDataSourceStoppedResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked NotifyDataSourceStopped() before "
+        "InitializeConnection()");
+    if (response.IsBound())
+      response.Reject();
+    return;
+  }
+  producer->service_endpoint->NotifyDataSourceStopped(request.data_source_id());
+
+  // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
+  // a useless IPC in that case.
+  if (response.IsBound()) {
+    response.Resolve(ipc::AsyncResult<
+                     protos::gen::NotifyDataSourceStoppedResponse>::Create());
+  }
+}
+
+void ProducerIPCService::ActivateTriggers(
+    const protos::gen::ActivateTriggersRequest& proto_req,
+    DeferredActivateTriggersResponse resp) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked ActivateTriggers() before InitializeConnection()");
+    if (resp.IsBound())
+      resp.Reject();
+    return;
+  }
+  std::vector<std::string> triggers;
+  for (const auto& name : proto_req.trigger_names()) {
+    triggers.push_back(name);
+  }
+  producer->service_endpoint->ActivateTriggers(triggers);
+  // ActivateTriggers shouldn't expect any meaningful response, avoid
+  // a useless IPC in that case.
+  if (resp.IsBound()) {
+    resp.Resolve(
+        ipc::AsyncResult<protos::gen::ActivateTriggersResponse>::Create());
+  }
+}
+
+void ProducerIPCService::GetAsyncCommand(
+    const protos::gen::GetAsyncCommandRequest&,
+    DeferredGetAsyncCommandResponse response) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG(
+        "Producer invoked GetAsyncCommand() before "
+        "InitializeConnection()");
+    return response.Reject();
+  }
+  // Keep the back channel open, without ever resolving the ipc::Deferred fully,
+  // to send async commands to the RemoteProducer (e.g., starting/stopping a
+  // data source).
+  producer->async_producer_commands = std::move(response);
+
+  // Service may already have issued the OnTracingSetup() event, in which case
+  // we should forward it to the producer now.
+  if (producer->send_setup_tracing_on_async_commands_bound)
+    producer->SendSetupTracing();
+}
+
+void ProducerIPCService::Sync(const protos::gen::SyncRequest&,
+                              DeferredSyncResponse resp) {
+  RemoteProducer* producer = GetProducerForCurrentRequest();
+  if (!producer) {
+    PERFETTO_DLOG("Producer invoked Sync() before InitializeConnection()");
+    return resp.Reject();
+  }
+  auto weak_this = weak_ptr_factory_.GetWeakPtr();
+  auto resp_it = pending_syncs_.insert(pending_syncs_.end(), std::move(resp));
+  auto callback = [weak_this, resp_it]() {
+    if (!weak_this)
+      return;
+    auto pending_resp = std::move(*resp_it);
+    weak_this->pending_syncs_.erase(resp_it);
+    pending_resp.Resolve(ipc::AsyncResult<protos::gen::SyncResponse>::Create());
+  };
+  producer->service_endpoint->Sync(callback);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// RemoteProducer methods
+////////////////////////////////////////////////////////////////////////////////
+
+ProducerIPCService::RemoteProducer::RemoteProducer() = default;
+ProducerIPCService::RemoteProducer::~RemoteProducer() = default;
+
+// Invoked by the |core_service_| business logic after the ConnectProducer()
+// call. There is nothing to do here, we really expected the ConnectProducer()
+// to just work in the local case.
+void ProducerIPCService::RemoteProducer::OnConnect() {}
+
+// Invoked by the |core_service_| business logic after we destroy the
+// |service_endpoint| (in the RemoteProducer dtor).
+void ProducerIPCService::RemoteProducer::OnDisconnect() {}
+
+// Invoked by the |core_service_| business logic when it wants to create a new
+// data source.
+void ProducerIPCService::RemoteProducer::SetupDataSource(
+    DataSourceInstanceID dsid,
+    const DataSourceConfig& cfg) {
+  if (!async_producer_commands.IsBound()) {
+    PERFETTO_DLOG(
+        "The Service tried to create a new data source but the remote Producer "
+        "has not yet initialized the connection");
+    return;
+  }
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  cmd->mutable_setup_data_source()->set_new_instance_id(dsid);
+  *cmd->mutable_setup_data_source()->mutable_config() = cfg;
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+// Invoked by the |core_service_| business logic when it wants to start a new
+// data source.
+void ProducerIPCService::RemoteProducer::StartDataSource(
+    DataSourceInstanceID dsid,
+    const DataSourceConfig& cfg) {
+  if (!async_producer_commands.IsBound()) {
+    PERFETTO_DLOG(
+        "The Service tried to start a new data source but the remote Producer "
+        "has not yet initialized the connection");
+    return;
+  }
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  cmd->mutable_start_data_source()->set_new_instance_id(dsid);
+  *cmd->mutable_start_data_source()->mutable_config() = cfg;
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+void ProducerIPCService::RemoteProducer::StopDataSource(
+    DataSourceInstanceID dsid) {
+  if (!async_producer_commands.IsBound()) {
+    PERFETTO_DLOG(
+        "The Service tried to stop a data source but the remote Producer "
+        "has not yet initialized the connection");
+    return;
+  }
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  cmd->mutable_stop_data_source()->set_instance_id(dsid);
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+void ProducerIPCService::RemoteProducer::OnTracingSetup() {
+  if (!async_producer_commands.IsBound()) {
+    // Service may call this before the producer issued GetAsyncCommand.
+    send_setup_tracing_on_async_commands_bound = true;
+    return;
+  }
+  SendSetupTracing();
+}
+
+void ProducerIPCService::RemoteProducer::SendSetupTracing() {
+  PERFETTO_CHECK(async_producer_commands.IsBound());
+  PERFETTO_CHECK(service_endpoint->shared_memory());
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  auto setup_tracing = cmd->mutable_setup_tracing();
+  if (!service_endpoint->IsShmemProvidedByProducer()) {
+    // Nominal case (% Chrome): service provides SMB.
+    setup_tracing->set_shared_buffer_page_size_kb(
+        static_cast<uint32_t>(service_endpoint->shared_buffer_page_size_kb()));
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    const std::string& shm_key =
+        static_cast<SharedMemoryWindows*>(service_endpoint->shared_memory())
+            ->key();
+    setup_tracing->set_shm_key_windows(shm_key);
+#else
+    const int shm_fd =
+        static_cast<PosixSharedMemory*>(service_endpoint->shared_memory())
+            ->fd();
+    cmd.set_fd(shm_fd);
+#endif
+  }
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+void ProducerIPCService::RemoteProducer::Flush(
+    FlushRequestID flush_request_id,
+    const DataSourceInstanceID* data_source_ids,
+    size_t num_data_sources,
+    FlushFlags flush_flags) {
+  if (!async_producer_commands.IsBound()) {
+    PERFETTO_DLOG(
+        "The Service tried to request a flush but the remote Producer has not "
+        "yet initialized the connection");
+    return;
+  }
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  for (size_t i = 0; i < num_data_sources; i++)
+    cmd->mutable_flush()->add_data_source_ids(data_source_ids[i]);
+  cmd->mutable_flush()->set_request_id(flush_request_id);
+  cmd->mutable_flush()->set_flags(flush_flags.flags());
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+void ProducerIPCService::RemoteProducer::ClearIncrementalState(
+    const DataSourceInstanceID* data_source_ids,
+    size_t num_data_sources) {
+  if (!async_producer_commands.IsBound()) {
+    PERFETTO_DLOG(
+        "The Service tried to request an incremental state invalidation, but "
+        "the remote Producer has not yet initialized the connection");
+    return;
+  }
+  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
+  cmd.set_has_more(true);
+  for (size_t i = 0; i < num_data_sources; i++)
+    cmd->mutable_clear_incremental_state()->add_data_source_ids(
+        data_source_ids[i]);
+  async_producer_commands.Resolve(std::move(cmd));
+}
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/ipc/service/service_ipc_host_impl.cc
+// gen_amalgamated begin header: src/tracing/ipc/service/service_ipc_host_impl.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/service_ipc_host.h
+// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/default_socket.h
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
+
+// TODO(khokhlov): Migrate usages of "perfetto/ext/tracing/ipc/default_socket.h"
+// in Chromium to include "perfetto/tracing/internal/default_socket.h" instead,
+// then delete this file.
+// gen_amalgamated expanded: #include "perfetto/tracing/default_socket.h"
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
+#define INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/default_socket.h"
+
+namespace perfetto {
+namespace base {
+class TaskRunner;
+}  // namespace base.
+
+namespace ipc {
+class Host;
+}  // namespace ipc
+
+// Creates an instance of the service (business logic + UNIX socket transport).
+// Exposed to:
+//   The code in the tracing client that will host the service e.g., traced.
+// Implemented in:
+//   src/tracing/ipc/service/service_ipc_host_impl.cc
+class PERFETTO_EXPORT_COMPONENT ServiceIPCHost {
+ public:
+  static std::unique_ptr<ServiceIPCHost> CreateInstance(
+      base::TaskRunner*,
+      TracingService::InitOpts = {});
+  virtual ~ServiceIPCHost();
+
+  // The overload to wrap the multi-value producer socket name in the
+  // single-value variant for compatibility in tests.
+  bool Start(const char* producer_socket_name,
+             const char* consumer_socket_name) {
+    return Start(TokenizeProducerSockets(producer_socket_name),
+                 consumer_socket_name);
+  }
+  // Start listening on the Producer & Consumer ports. Returns false in case of
+  // failure (e.g., something else is listening on |socket_name|).
+  virtual bool Start(const std::vector<std::string>& producer_socket_names,
+                     const char* consumer_socket_name) = 0;
+
+  // Like the above, but takes two file descriptors to already bound sockets.
+  // This is used when building as part of the Android tree, where init opens
+  // and binds the socket beore exec()-ing us.
+  virtual bool Start(base::ScopedSocketHandle producer_socket_fd,
+                     base::ScopedSocketHandle consumer_socket_fd) = 0;
+
+  // Allows callers to supply preconstructed Hosts.
+  virtual bool Start(std::unique_ptr<ipc::Host> producer_host,
+                     std::unique_ptr<ipc::Host> consumer_host) = 0;
+
+  virtual TracingService* service() const = 0;
+
+ protected:
+  ServiceIPCHost();
+
+ private:
+  ServiceIPCHost(const ServiceIPCHost&) = delete;
+  ServiceIPCHost& operator=(const ServiceIPCHost&) = delete;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
+#define SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
+
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/service_ipc_host.h"
+
+namespace perfetto {
+
+namespace ipc {
+class Host;
+}
+
+// The implementation of the IPC host for the tracing service. This class does
+// very few things: it mostly initializes the IPC transport. The actual
+// implementation of the IPC <> Service business logic glue lives in
+// producer_ipc_service.cc and consumer_ipc_service.cc.
+class ServiceIPCHostImpl : public ServiceIPCHost {
+ public:
+  explicit ServiceIPCHostImpl(base::TaskRunner*,
+                              TracingService::InitOpts init_opts = {});
+  ~ServiceIPCHostImpl() override;
+
+  // ServiceIPCHost implementation.
+  bool Start(const std::vector<std::string>& producer_socket_names,
+             const char* consumer_socket_name) override;
+  bool Start(base::ScopedSocketHandle producer_socket_fd,
+             base::ScopedSocketHandle consumer_socket_fd) override;
+  bool Start(std::unique_ptr<ipc::Host> producer_host,
+             std::unique_ptr<ipc::Host> consumer_host) override;
+
+  TracingService* service() const override;
+
+ private:
+  bool DoStart();
+  void Shutdown();
+
+  base::TaskRunner* const task_runner_;
+  const TracingService::InitOpts init_opts_;
+  std::unique_ptr<TracingService> svc_;  // The service business logic.
+
+  // The IPC hosts that listen on the Producer sockets. They own the
+  // PosixServiceProducerPort instances which deal with all producers' IPC(s).
+  // Note that there can be multiple producer sockets if it's specified in the
+  // producer socket name (e.g. for listening both on vsock for VMs and AF_UNIX
+  // for processes on the same machine).
+  std::vector<std::unique_ptr<ipc::Host>> producer_ipc_ports_;
+
+  // As above, but for the Consumer port.
+  std::unique_ptr<ipc::Host> consumer_ipc_port_;
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/service_ipc_host_impl.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
+// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
+// gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
+#else
+// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
+#endif
+
+namespace perfetto {
+
+namespace {
+constexpr uint32_t kProducerSocketTxTimeoutMs = 10;
+}
+
+// TODO(fmayer): implement per-uid connection limit (b/69093705).
+
+// Implements the publicly exposed factory method declared in
+// include/tracing/posix_ipc/posix_service_host.h.
+std::unique_ptr<ServiceIPCHost> ServiceIPCHost::CreateInstance(
+    base::TaskRunner* task_runner,
+    TracingService::InitOpts init_opts) {
+  return std::unique_ptr<ServiceIPCHost>(
+      new ServiceIPCHostImpl(task_runner, init_opts));
+}
+
+ServiceIPCHostImpl::ServiceIPCHostImpl(base::TaskRunner* task_runner,
+                                       TracingService::InitOpts init_opts)
+    : task_runner_(task_runner), init_opts_(init_opts) {}
+
+ServiceIPCHostImpl::~ServiceIPCHostImpl() {}
+
+bool ServiceIPCHostImpl::Start(
+    const std::vector<std::string>& producer_socket_names,
+    const char* consumer_socket_name) {
+  PERFETTO_CHECK(!svc_);  // Check if already started.
+
+  // Initialize the IPC transport.
+  for (const auto& producer_socket_name : producer_socket_names)
+    producer_ipc_ports_.emplace_back(
+        ipc::Host::CreateInstance(producer_socket_name.c_str(), task_runner_));
+  consumer_ipc_port_ =
+      ipc::Host::CreateInstance(consumer_socket_name, task_runner_);
+  return DoStart();
+}
+
+bool ServiceIPCHostImpl::Start(base::ScopedSocketHandle producer_socket_fd,
+                               base::ScopedSocketHandle consumer_socket_fd) {
+  PERFETTO_CHECK(!svc_);  // Check if already started.
+
+  // Initialize the IPC transport.
+  producer_ipc_ports_.emplace_back(
+      ipc::Host::CreateInstance(std::move(producer_socket_fd), task_runner_));
+  consumer_ipc_port_ =
+      ipc::Host::CreateInstance(std::move(consumer_socket_fd), task_runner_);
+  return DoStart();
+}
+
+bool ServiceIPCHostImpl::Start(std::unique_ptr<ipc::Host> producer_host,
+                               std::unique_ptr<ipc::Host> consumer_host) {
+  PERFETTO_CHECK(!svc_);  // Check if already started.
+  PERFETTO_DCHECK(producer_host);
+  PERFETTO_DCHECK(consumer_host);
+
+  // Initialize the IPC transport.
+  producer_ipc_ports_.emplace_back(std::move(producer_host));
+  consumer_ipc_port_ = std::move(consumer_host);
+
+  return DoStart();
+}
+
+bool ServiceIPCHostImpl::DoStart() {
+  // Create and initialize the platform-independent tracing business logic.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  std::unique_ptr<SharedMemory::Factory> shm_factory(
+      new SharedMemoryWindows::Factory());
+#else
+  std::unique_ptr<SharedMemory::Factory> shm_factory(
+      new PosixSharedMemory::Factory());
+#endif
+  svc_ = TracingService::CreateInstance(std::move(shm_factory), task_runner_,
+                                        init_opts_);
+
+  if (producer_ipc_ports_.empty() || !consumer_ipc_port_) {
+    Shutdown();
+    return false;
+  }
+
+  // Lower the timeout for blocking socket sends to producers as we shouldn't
+  // normally exhaust the kernel send buffer unless the producer is
+  // unresponsive. We'll drop the connection if the timeout is hit (see
+  // UnixSocket::Send). Context in b/236813972, b/193234818.
+  // Consumer port continues using the default timeout (10s) as there are
+  // generally fewer consumer processes, and they're better behaved. Also the
+  // consumer port ipcs might exhaust the send buffer under normal operation
+  // due to large messages such as ReadBuffersResponse.
+  for (auto& producer_ipc_port : producer_ipc_ports_)
+    producer_ipc_port->SetSocketSendTimeoutMs(kProducerSocketTxTimeoutMs);
+
+  // TODO(fmayer): add a test that destroyes the ServiceIPCHostImpl soon after
+  // Start() and checks that no spurious callbacks are issued.
+  for (auto& producer_ipc_port : producer_ipc_ports_) {
+    bool producer_service_exposed = producer_ipc_port->ExposeService(
+        std::unique_ptr<ipc::Service>(new ProducerIPCService(svc_.get())));
+    PERFETTO_CHECK(producer_service_exposed);
+  }
+
+  bool consumer_service_exposed = consumer_ipc_port_->ExposeService(
+      std::unique_ptr<ipc::Service>(new ConsumerIPCService(svc_.get())));
+  PERFETTO_CHECK(consumer_service_exposed);
+
+  return true;
+}
+
+TracingService* ServiceIPCHostImpl::service() const {
+  return svc_.get();
+}
+
+void ServiceIPCHostImpl::Shutdown() {
+  // TODO(primiano): add a test that causes the Shutdown() and checks that no
+  // spurious callbacks are issued.
+  producer_ipc_ports_.clear();
+  consumer_ipc_port_.reset();
+  svc_.reset();
+}
+
+// Definitions for the base class ctor/dtor.
+ServiceIPCHost::ServiceIPCHost() = default;
+ServiceIPCHost::~ServiceIPCHost() = default;
+
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/internal/system_tracing_backend.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/system_tracing_backend.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/default_socket.h"
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_SYSTEM_CONSUMER)
+// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
+#else
+// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
+#endif
+
+namespace perfetto {
+namespace internal {
+
+// static
+TracingProducerBackend* SystemProducerTracingBackend::GetInstance() {
+  static auto* instance = new SystemProducerTracingBackend();
+  return instance;
+}
+
+SystemProducerTracingBackend::SystemProducerTracingBackend() {}
+
+std::unique_ptr<ProducerEndpoint> SystemProducerTracingBackend::ConnectProducer(
+    const ConnectProducerArgs& args) {
+  PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
+
+  std::unique_ptr<SharedMemory> shm;
+  std::unique_ptr<SharedMemoryArbiter> arbiter;
+  uint32_t shmem_size_hint = args.shmem_size_hint_bytes;
+  uint32_t shmem_page_size_hint = args.shmem_page_size_hint_bytes;
+  if (args.use_producer_provided_smb) {
+    if (shmem_size_hint == 0)
+      shmem_size_hint = TracingService::kDefaultShmSize;
+    if (shmem_page_size_hint == 0)
+      shmem_page_size_hint = TracingService::kDefaultShmPageSize;
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+    shm = SharedMemoryWindows::Create(shmem_size_hint);
+#else
+    shm = PosixSharedMemory::Create(shmem_size_hint);
+#endif
+    arbiter = SharedMemoryArbiter::CreateUnboundInstance(
+        shm.get(), shmem_page_size_hint, SharedMemoryABI::ShmemMode::kDefault);
+  }
+
+  ipc::Client::ConnArgs conn_args(GetProducerSocket(), true);
+  auto endpoint = ProducerIPCClient::Connect(
+      std::move(conn_args), args.producer, args.producer_name, args.task_runner,
+      TracingService::ProducerSMBScrapingMode::kEnabled, shmem_size_hint,
+      shmem_page_size_hint, std::move(shm), std::move(arbiter),
+      args.create_socket_async);
+  PERFETTO_CHECK(endpoint);
+  return endpoint;
+}
+
+// static
+TracingConsumerBackend* SystemConsumerTracingBackend::GetInstance() {
+  static auto* instance = new SystemConsumerTracingBackend();
+  return instance;
+}
+
+SystemConsumerTracingBackend::SystemConsumerTracingBackend() {}
+
+std::unique_ptr<ConsumerEndpoint> SystemConsumerTracingBackend::ConnectConsumer(
+    const ConnectConsumerArgs& args) {
+#if PERFETTO_BUILDFLAG(PERFETTO_SYSTEM_CONSUMER)
+  auto endpoint = ConsumerIPCClient::Connect(GetConsumerSocket(), args.consumer,
+                                             args.task_runner);
+  PERFETTO_CHECK(endpoint);
+  return endpoint;
+#else
+  base::ignore_result(args);
+  PERFETTO_FATAL("System backend consumer support disabled");
+  return nullptr;
+#endif
+}
+
+}  // namespace internal
+}  // namespace perfetto
+// gen_amalgamated begin source: src/tracing/platform_posix.cc
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace perfetto {
+
+namespace {
+
+class PlatformPosix : public Platform {
+ public:
+  PlatformPosix();
+  ~PlatformPosix() override;
+
+  ThreadLocalObject* GetOrCreateThreadLocalObject() override;
+
+  std::unique_ptr<base::TaskRunner> CreateTaskRunner(
+      const CreateTaskRunnerArgs&) override;
+  std::string GetCurrentProcessName() override;
+  void Shutdown() override;
+
+ private:
+  pthread_key_t tls_key_{};
+};
+
+PlatformPosix* g_instance = nullptr;
+
+using ThreadLocalObject = Platform::ThreadLocalObject;
+
+PlatformPosix::PlatformPosix() {
+  PERFETTO_CHECK(!g_instance);
+  g_instance = this;
+  auto tls_dtor = [](void* obj) {
+    // The Posix TLS implementation resets the key before calling this dtor.
+    // Here we re-reset it to the object we are about to delete. This is to
+    // handle re-entrant usages of tracing in the PostTask done during the dtor
+    // (see comments in TracingTLS::~TracingTLS()). Chromium's platform
+    // implementation (which does NOT use this platform impl) has a similar
+    // workaround (https://crrev.com/c/2748300).
+    pthread_setspecific(g_instance->tls_key_, obj);
+    delete static_cast<ThreadLocalObject*>(obj);
+    pthread_setspecific(g_instance->tls_key_, nullptr);
+  };
+  PERFETTO_CHECK(pthread_key_create(&tls_key_, tls_dtor) == 0);
+}
+
+PlatformPosix::~PlatformPosix() {
+  // pthread_key_delete doesn't call destructors, so do it manually for the
+  // calling thread.
+  void* tls_ptr = pthread_getspecific(tls_key_);
+  delete static_cast<ThreadLocalObject*>(tls_ptr);
+
+  pthread_key_delete(tls_key_);
+  g_instance = nullptr;
+}
+
+void PlatformPosix::Shutdown() {
+  PERFETTO_CHECK(g_instance == this);
+  delete this;
+  PERFETTO_CHECK(!g_instance);
+  // We're not clearing out the instance in GetDefaultPlatform() since it's not
+  // possible to re-initialize Perfetto after calling this function anyway.
+}
+
+ThreadLocalObject* PlatformPosix::GetOrCreateThreadLocalObject() {
+  // In chromium this should be implemented using base::ThreadLocalStorage.
+  void* tls_ptr = pthread_getspecific(tls_key_);
+
+  // This is needed to handle re-entrant calls during TLS dtor.
+  // See comments in platform.cc and aosp/1712371 .
+  ThreadLocalObject* tls = static_cast<ThreadLocalObject*>(tls_ptr);
+  if (!tls) {
+    tls = ThreadLocalObject::CreateInstance().release();
+    pthread_setspecific(tls_key_, tls);
+  }
+  return tls;
+}
+
+std::unique_ptr<base::TaskRunner> PlatformPosix::CreateTaskRunner(
+    const CreateTaskRunnerArgs& args) {
+  return std::unique_ptr<base::TaskRunner>(new base::ThreadTaskRunner(
+      base::ThreadTaskRunner::CreateAndStart(args.name_for_debugging)));
+}
+
+std::string PlatformPosix::GetCurrentProcessName() {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  std::string cmdline;
+  base::ReadFile("/proc/self/cmdline", &cmdline);
+  return cmdline.substr(0, cmdline.find('\0'));
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  return std::string(getprogname());
+#else
+  return "unknown_producer";
+#endif
+}
+
+}  // namespace
+
+// static
+Platform* Platform::GetDefaultPlatform() {
+  static PlatformPosix* instance = new PlatformPosix();
+  return instance;
+}
+
+}  // namespace perfetto
+#endif  // OS_LINUX || OS_ANDROID || OS_APPLE || OS_FUCHSIA
+// gen_amalgamated begin source: src/tracing/platform_windows.cc
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#include <Windows.h>
+
+// gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+
+// Thread Termination Callbacks.
+// Windows doesn't support a per-thread destructor with its
+// TLS primitives. So, we build it manually by inserting a
+// function to be called on each thread's exit.
+// This magic is from chromium's base/threading/thread_local_storage_win.cc
+// which in turn is from http://www.codeproject.com/threads/tls.asp.
+
+#ifdef _WIN64
+#pragma comment(linker, "/INCLUDE:_tls_used")
+#pragma comment(linker, "/INCLUDE:perfetto_thread_callback_base")
+#else
+#pragma comment(linker, "/INCLUDE:__tls_used")
+#pragma comment(linker, "/INCLUDE:_perfetto_thread_callback_base")
+#endif
+
+namespace perfetto {
+
+namespace {
+
+class PlatformWindows : public Platform {
+ public:
+  static PlatformWindows* instance;
+  PlatformWindows();
+  ~PlatformWindows() override;
+
+  ThreadLocalObject* GetOrCreateThreadLocalObject() override;
+  std::unique_ptr<base::TaskRunner> CreateTaskRunner(
+      const CreateTaskRunnerArgs&) override;
+  std::string GetCurrentProcessName() override;
+  void OnThreadExit();
+
+ private:
+  DWORD tls_key_{};
+};
+
+using ThreadLocalObject = Platform::ThreadLocalObject;
+
+// static
+PlatformWindows* PlatformWindows::instance = nullptr;
+
+PlatformWindows::PlatformWindows() {
+  instance = this;
+  tls_key_ = ::TlsAlloc();
+  PERFETTO_CHECK(tls_key_ != TLS_OUT_OF_INDEXES);
+}
+
+PlatformWindows::~PlatformWindows() {
+  ::TlsFree(tls_key_);
+  instance = nullptr;
+}
+
+void PlatformWindows::OnThreadExit() {
+  auto tls = static_cast<ThreadLocalObject*>(::TlsGetValue(tls_key_));
+  if (tls) {
+    // At this point we rely on the TLS object to be still set to the TracingTLS
+    // we are deleting. See comments in TracingTLS::~TracingTLS().
+    delete tls;
+  }
+}
+
+ThreadLocalObject* PlatformWindows::GetOrCreateThreadLocalObject() {
+  void* tls_ptr = ::TlsGetValue(tls_key_);
+
+  auto* tls = static_cast<ThreadLocalObject*>(tls_ptr);
+  if (!tls) {
+    tls = ThreadLocalObject::CreateInstance().release();
+    ::TlsSetValue(tls_key_, tls);
+  }
+  return tls;
+}
+
+std::unique_ptr<base::TaskRunner> PlatformWindows::CreateTaskRunner(
+    const CreateTaskRunnerArgs& args) {
+  return std::unique_ptr<base::TaskRunner>(new base::ThreadTaskRunner(
+      base::ThreadTaskRunner::CreateAndStart(args.name_for_debugging)));
+}
+
+std::string PlatformWindows::GetCurrentProcessName() {
+  char buf[MAX_PATH];
+  auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
+  std::string name(buf, static_cast<size_t>(len));
+  size_t sep = name.find_last_of('\\');
+  if (sep != std::string::npos)
+    name = name.substr(sep + 1);
+  return name;
+}
+
+}  // namespace
+
+// static
+Platform* Platform::GetDefaultPlatform() {
+  static PlatformWindows* thread_safe_init_instance = new PlatformWindows();
+  return thread_safe_init_instance;
+}
+
+}  // namespace perfetto
+
+// -----------------------
+// Thread-local destructor
+// -----------------------
+
+// .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are
+// called automatically by the OS loader code (not the CRT) when the module is
+// loaded and on thread creation. They are NOT called if the module has been
+// loaded by a LoadLibrary() call. It must have implicitly been loaded at
+// process startup.
+// See VC\crt\src\tlssup.c for reference.
+
+// extern "C" suppresses C++ name mangling so we know the symbol name for the
+// linker /INCLUDE:symbol pragma above.
+extern "C" {
+// The linker must not discard perfetto_thread_callback_base. (We force a
+// reference to this variable with a linker /INCLUDE:symbol pragma to ensure
+// that.) If this variable is discarded, the OnThreadExit function will never be
+// called.
+
+void NTAPI PerfettoOnThreadExit(PVOID, DWORD, PVOID);
+void NTAPI PerfettoOnThreadExit(PVOID, DWORD reason, PVOID) {
+  if (reason == DLL_THREAD_DETACH || reason == DLL_PROCESS_DETACH) {
+    if (perfetto::PlatformWindows::instance)
+      perfetto::PlatformWindows::instance->OnThreadExit();
+  }
+}
+
+#ifdef _WIN64
+
+// .CRT section is merged with .rdata on x64 so it must be constant data.
+#pragma const_seg(".CRT$XLP")
+
+// When defining a const variable, it must have external linkage to be sure the
+// linker doesn't discard it.
+extern const PIMAGE_TLS_CALLBACK perfetto_thread_callback_base;
+const PIMAGE_TLS_CALLBACK perfetto_thread_callback_base = PerfettoOnThreadExit;
+
+// Reset the default section.
+#pragma const_seg()
+
+#else  // _WIN64
+
+#pragma data_seg(".CRT$XLP")
+PIMAGE_TLS_CALLBACK perfetto_thread_callback_base = PerfettoOnThreadExit;
+// Reset the default section.
+#pragma data_seg()
+
+#endif  // _WIN64
+
+}  // extern "C"
+
+#endif  // OS_WIN
+
diff --git a/sdk/perfetto.h b/sdk/perfetto.h
new file mode 100644
index 0000000..4ebb057
--- /dev/null
+++ b/sdk/perfetto.h
@@ -0,0 +1,155884 @@
+// Copyright (C) 2019 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.
+//
+// This file is automatically generated by gen_amalgamated. Do not edit.
+
+// gen_amalgamated begin header: include/perfetto/tracing.h
+// gen_amalgamated begin header: include/perfetto/base/time.h
+// gen_amalgamated begin header: include/perfetto/base/build_config.h
+// gen_amalgamated begin header: gen/build_config/perfetto_build_flags.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+// Generated by write_buildflag_header.py
+
+// fix_include_guards: off
+#ifndef GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
+#define GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
+
+// clang-format off
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_BUILD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_CHROMIUM_BUILD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STANDALONE_BUILD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_START_DAEMONS() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_IPC() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_WATCHDOG() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPONENT_BUILD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_ON() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DLOG_OFF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DCHECK_ON() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_FORCE_DCHECK_OFF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERBOSE_LOGS() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_VERSION_GEN() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_PERCENTILE() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_LINENOISE() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_HTTPD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TP_JSON() (1)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LOCAL_SYMBOLIZER() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ZLIB() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_TRACED_PERF() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_HEAPPROFD() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_STDERR_CRASH_DUMP() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_X64_CPU_OPT() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_LLVM_DEMANGLE() (0)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_SYSTEM_CONSUMER() (1)
+
+// clang-format on
+#endif  // GEN_BUILD_CONFIG_PERFETTO_BUILD_FLAGS_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
+#define INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
+
+// Allows to define build flags that give a compiler error if the header that
+// defined the flag is not included, instead of silently ignoring the #if block.
+#define PERFETTO_BUILDFLAG_CAT_INDIRECT(a, b) a##b
+#define PERFETTO_BUILDFLAG_CAT(a, b) PERFETTO_BUILDFLAG_CAT_INDIRECT(a, b)
+#define PERFETTO_BUILDFLAG(flag) \
+  (PERFETTO_BUILDFLAG_CAT(PERFETTO_BUILDFLAG_DEFINE_, flag)())
+
+#if defined(__ANDROID__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+#elif defined(__APPLE__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+// Include TARGET_OS_IPHONE when on __APPLE__ systems.
+#include <TargetConditionals.h>
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 1
+#else
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#endif
+#elif defined(__linux__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+#elif defined(_WIN32)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+#elif defined(__EMSCRIPTEN__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+#elif defined(__Fuchsia__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 0
+#elif defined(__native_client__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_ANDROID() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_LINUX() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WIN() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_APPLE() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_MAC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_IOS() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_WASM() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_FUCHSIA() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_OS_NACL() 1
+#else
+#error OS not supported (see build_config.h)
+#endif
+
+#if defined(__clang__)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 0
+#elif defined(__GNUC__) // Careful: Clang also defines this!
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 1
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 0
+#elif defined(_MSC_VER)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 1
+#else
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_CLANG() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_GCC() 0
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_COMPILER_MSVC() 0
+#endif
+
+#if defined(PERFETTO_BUILD_WITH_ANDROID_USERDEBUG)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_USERDEBUG_BUILD() 1
+#else
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ANDROID_USERDEBUG_BUILD() 0
+#endif
+
+// Processor architecture detection.  For more info on what's defined, see:
+//   http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+//   http://www.agner.org/optimize/calling_conventions.pdf
+//   or with gcc, run: "echo | gcc -E -dM -"
+#if defined(__aarch64__) || defined(_M_ARM64)
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_ARM64() 1
+#else
+#define PERFETTO_BUILDFLAG_DEFINE_PERFETTO_ARCH_CPU_ARM64() 0
+#endif
+
+// perfetto_build_flags.h contains the tweakable build flags defined via GN.
+// - In GN builds (e.g., standalone, chromium, v8) this file is generated at
+//   build time via the gen_rule //gn/gen_buildflags.
+// - In Android in-tree builds, this file is generated by tools/gen_android_bp
+//   and checked in into include/perfetto/base/build_configs/android_tree/. The
+//   default cflags add this path to the default include path.
+// - Similarly, in bazel builds, this file is generated by tools/gen_bazel and
+//   checked in into include/perfetto/base/build_configs/bazel/.
+// - In amalgamated builds, this file is generated by tools/gen_amalgamated and
+//   added to the amalgamated headers.
+// gen_amalgamated expanded: #include "perfetto_build_flags.h"  // no-include-violation-check
+
+#endif  // INCLUDE_PERFETTO_BASE_BUILD_CONFIG_H_
+// gen_amalgamated begin header: include/perfetto/base/logging.h
+// gen_amalgamated begin header: include/perfetto/base/compiler.h
+// gen_amalgamated begin header: include/perfetto/public/compiler.h
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PUBLIC_COMPILER_H_
+#define INCLUDE_PERFETTO_PUBLIC_COMPILER_H_
+
+#include <stddef.h>
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_LIKELY(_x) __builtin_expect(!!(_x), 1)
+#define PERFETTO_UNLIKELY(_x) __builtin_expect(!!(_x), 0)
+#else
+#define PERFETTO_LIKELY(_x) (_x)
+#define PERFETTO_UNLIKELY(_x) (_x)
+#endif
+
+// PERFETTO_STATIC_CAST(TYPE, VAL): avoids the -Wold-style-cast warning when
+// writing code that needs to be compiled as C and C++.
+#ifdef __cplusplus
+#define PERFETTO_STATIC_CAST(TYPE, VAL) static_cast<TYPE>(VAL)
+#else
+#define PERFETTO_STATIC_CAST(TYPE, VAL) ((TYPE)(VAL))
+#endif
+
+// PERFETTO_REINTERPRET_CAST(TYPE, VAL): avoids the -Wold-style-cast warning
+// when writing code that needs to be compiled as C and C++.
+#ifdef __cplusplus
+#define PERFETTO_REINTERPRET_CAST(TYPE, VAL) reinterpret_cast<TYPE>(VAL)
+#else
+#define PERFETTO_REINTERPRET_CAST(TYPE, VAL) ((TYPE)(VAL))
+#endif
+
+// PERFETTO_NULL: avoids the -Wzero-as-null-pointer-constant warning when
+// writing code that needs to be compiled as C and C++.
+#ifdef __cplusplus
+#define PERFETTO_NULL nullptr
+#else
+#define PERFETTO_NULL NULL
+#endif
+
+#endif  // INCLUDE_PERFETTO_PUBLIC_COMPILER_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_COMPILER_H_
+#define INCLUDE_PERFETTO_BASE_COMPILER_H_
+
+#include <stddef.h>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/public/compiler.h"
+
+// __has_attribute is supported only by clang and recent versions of GCC.
+// Add a layer to wrap the __has_attribute macro.
+#if defined(__has_attribute)
+#define PERFETTO_HAS_ATTRIBUTE(x) __has_attribute(x)
+#else
+#define PERFETTO_HAS_ATTRIBUTE(x) 0
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define PERFETTO_WARN_UNUSED_RESULT
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_UNUSED __attribute__((unused))
+#else
+#define PERFETTO_UNUSED
+#endif
+
+#if defined(__clang__)
+#define PERFETTO_ALWAYS_INLINE __attribute__((__always_inline__))
+#define PERFETTO_NO_INLINE __attribute__((__noinline__))
+#else
+// GCC is too pedantic and often fails with the error:
+// "always_inline function might not be inlinable"
+#define PERFETTO_ALWAYS_INLINE
+#define PERFETTO_NO_INLINE
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_NORETURN __attribute__((__noreturn__))
+#else
+#define PERFETTO_NORETURN __declspec(noreturn)
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() __PRETTY_FUNCTION__
+#elif defined(_MSC_VER)
+#define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() __FUNCSIG__
+#else
+#define PERFETTO_DEBUG_FUNCTION_IDENTIFIER() \
+  static_assert(false, "Not implemented for this compiler")
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_PRINTF_FORMAT(x, y) \
+  __attribute__((__format__(__printf__, x, y)))
+#else
+#define PERFETTO_PRINTF_FORMAT(x, y)
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_POPCOUNT(x) __builtin_popcountll(x)
+#else
+#include <intrin.h>
+#define PERFETTO_POPCOUNT(x) __popcnt64(x)
+#endif
+
+#if defined(__clang__)
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+extern "C" void __asan_poison_memory_region(void const volatile*, size_t);
+extern "C" void __asan_unpoison_memory_region(void const volatile*, size_t);
+#define PERFETTO_ASAN_POISON(a, s) __asan_poison_memory_region((a), (s))
+#define PERFETTO_ASAN_UNPOISON(a, s) __asan_unpoison_memory_region((a), (s))
+#else
+#define PERFETTO_ASAN_POISON(addr, size)
+#define PERFETTO_ASAN_UNPOISON(addr, size)
+#endif  // __has_feature(address_sanitizer)
+#else
+#define PERFETTO_ASAN_POISON(addr, size)
+#define PERFETTO_ASAN_UNPOISON(addr, size)
+#endif  // __clang__
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_IS_LITTLE_ENDIAN() __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#else
+// Assume all MSVC targets are little endian.
+#define PERFETTO_IS_LITTLE_ENDIAN() 1
+#endif
+
+// This is used for exporting xxxMain() symbols (e.g., PerfettoCmdMain,
+// ProbesMain) from libperfetto.so when the GN arg monolithic_binaries = false.
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_EXPORT_ENTRYPOINT __attribute__((visibility("default")))
+#else
+// TODO(primiano): on Windows this should be a pair of dllexport/dllimport. But
+// that requires a -DXXX_IMPLEMENTATION depending on whether we are on the
+// impl-site or call-site. Right now it's not worth the trouble as we
+// force-export the xxxMain() symbols only on Android, where we pack all the
+// code for N binaries into one .so to save binary size. On Windows we support
+// only monolithic binaries, as they are easier to deal with.
+#define PERFETTO_EXPORT_ENTRYPOINT
+#endif
+
+// Disables thread safety analysis for functions where the compiler can't
+// accurate figure out which locks are being held.
+#if defined(__clang__)
+#define PERFETTO_NO_THREAD_SAFETY_ANALYSIS \
+  __attribute__((no_thread_safety_analysis))
+#else
+#define PERFETTO_NO_THREAD_SAFETY_ANALYSIS
+#endif
+
+// Disables undefined behavior analysis for a function.
+#if defined(__clang__)
+#define PERFETTO_NO_SANITIZE_UNDEFINED __attribute__((no_sanitize("undefined")))
+#else
+#define PERFETTO_NO_SANITIZE_UNDEFINED
+#endif
+
+// Avoid calling the exit-time destructor on an object with static lifetime.
+#if PERFETTO_HAS_ATTRIBUTE(no_destroy)
+#define PERFETTO_HAS_NO_DESTROY() 1
+#define PERFETTO_NO_DESTROY __attribute__((no_destroy))
+#else
+#define PERFETTO_HAS_NO_DESTROY() 0
+#define PERFETTO_NO_DESTROY
+#endif
+
+// Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional.
+#define PERFETTO_FALLTHROUGH [[fallthrough]]
+
+namespace perfetto {
+namespace base {
+
+template <typename... T>
+inline void ignore_result(const T&...) {}
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_COMPILER_H_
+// gen_amalgamated begin header: include/perfetto/base/export.h
+// gen_amalgamated begin header: include/perfetto/public/abi/export.h
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PUBLIC_ABI_EXPORT_H_
+#define INCLUDE_PERFETTO_PUBLIC_ABI_EXPORT_H_
+
+#ifdef _WIN32
+#define PERFETTO_INTERNAL_DLL_EXPORT __declspec(dllexport)
+#define PERFETTO_INTERNAL_DLL_IMPORT __declspec(dllimport)
+#else
+#define PERFETTO_INTERNAL_DLL_EXPORT __attribute__((visibility("default")))
+#define PERFETTO_INTERNAL_DLL_IMPORT
+#endif
+
+// PERFETTO_SDK_EXPORT: Exports a symbol from the perfetto SDK shared library.
+//
+// This is controlled by two defines (that likely come from the compiler command
+// line):
+// * PERFETTO_SDK_DISABLE_SHLIB_EXPORT: If this is defined, no export
+//   annotations are added. This might be useful when static linking.
+// * PERFETTO_SDK_SHLIB_IMPLEMENTATION: This must be defined when compiling the
+//   shared library itself (in order to export the symbols), but must be
+//   undefined when compiling objects that use the shared library (in order to
+//   import the symbols).
+#if !defined(PERFETTO_SDK_DISABLE_SHLIB_EXPORT)
+#if defined(PERFETTO_SHLIB_SDK_IMPLEMENTATION)
+#define PERFETTO_SDK_EXPORT PERFETTO_INTERNAL_DLL_EXPORT
+#else
+#define PERFETTO_SDK_EXPORT PERFETTO_INTERNAL_DLL_IMPORT
+#endif
+#else  // defined(PERFETTO_SDK_DISABLE_SHLIB_EXPORT)
+#define PERFETTO_SDK_EXPORT
+#endif  // defined(PERFETTO_SDK_DISABLE_SHLIB_EXPORT)
+
+#endif  // INCLUDE_PERFETTO_PUBLIC_ABI_EXPORT_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_EXPORT_H_
+#define INCLUDE_PERFETTO_BASE_EXPORT_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/public/abi/export.h"
+
+// PERFETTO_EXPORT_COMPONENT: Exports a symbol among C++ components when
+// building with is_component = true (mostly used by chromium build).
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
+
+#if defined(PERFETTO_IMPLEMENTATION)
+#define PERFETTO_EXPORT_COMPONENT PERFETTO_INTERNAL_DLL_EXPORT
+#else
+#define PERFETTO_EXPORT_COMPONENT PERFETTO_INTERNAL_DLL_IMPORT
+#endif
+
+#else  // !PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
+
+#if !defined(PERFETTO_EXPORT_COMPONENT)
+#define PERFETTO_EXPORT_COMPONENT
+#endif  // !defined(PERFETTO_EXPORT_COMPONENT)
+
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_COMPONENT_BUILD)
+
+#endif  // INCLUDE_PERFETTO_BASE_EXPORT_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_LOGGING_H_
+#define INCLUDE_PERFETTO_BASE_LOGGING_H_
+
+#include <errno.h>
+#include <string.h>  // For strerror.
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+#if defined(__GNUC__) || defined(__clang__)
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#pragma GCC system_header
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DCHECK_ON)
+#define PERFETTO_DCHECK_IS_ON() 1
+#elif PERFETTO_BUILDFLAG(PERFETTO_FORCE_DCHECK_OFF)
+#define PERFETTO_DCHECK_IS_ON() 0
+#elif defined(DCHECK_ALWAYS_ON) ||                                         \
+    (!defined(NDEBUG) && (PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
+                          PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD) ||   \
+                          PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)))
+#define PERFETTO_DCHECK_IS_ON() 1
+#else
+#define PERFETTO_DCHECK_IS_ON() 0
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_ON)
+#define PERFETTO_DLOG_IS_ON() 1
+#elif PERFETTO_BUILDFLAG(PERFETTO_FORCE_DLOG_OFF)
+#define PERFETTO_DLOG_IS_ON() 0
+#else
+#define PERFETTO_DLOG_IS_ON() PERFETTO_DCHECK_IS_ON()
+#endif
+
+#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
+    !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+#error "Async-safe logging is limited to Android tree builds"
+#endif
+// For binaries which need a very lightweight logging implementation.
+// Note that this header is incompatible with android/log.h.
+#include <async_safe/log.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+// Normal android logging.
+#include <android/log.h>
+#endif
+
+// Enable the "Print the most recent PERFETTO_LOG(s) before crashing" feature
+// on Android in-tree builds and on standalone builds (mainly for testing).
+// This is deliberately no PERFETTO_OS_ANDROID because we don't want this
+// feature when perfetto is embedded in other Android projects (e.g. SDK).
+// TODO(b/203795298): TFLite is using the client library in blaze builds and is
+// targeting API 19. For now disable the feature based on API level.
+#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 0
+#elif PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 1
+#elif PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) && \
+    (!PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) ||       \
+     (defined(__ANDROID_API__) && __ANDROID_API__ >= 21))
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 1
+#else
+#define PERFETTO_ENABLE_LOG_RING_BUFFER() 0
+#endif
+
+namespace perfetto {
+namespace base {
+
+// Constexpr functions to extract basename(__FILE__), e.g.: ../foo/f.c -> f.c .
+constexpr const char* StrEnd(const char* s) {
+  return *s ? StrEnd(s + 1) : s;
+}
+
+constexpr const char* BasenameRecursive(const char* s,
+                                        const char* begin,
+                                        const char* end) {
+  return (*s == '/' && s < end)
+             ? (s + 1)
+             : ((s > begin) ? BasenameRecursive(s - 1, begin, end) : s);
+}
+
+constexpr const char* Basename(const char* str) {
+  return BasenameRecursive(StrEnd(str), str, StrEnd(str));
+}
+
+enum LogLev { kLogDebug = 0, kLogInfo, kLogImportant, kLogError };
+
+struct LogMessageCallbackArgs {
+  LogLev level;
+  int line;
+  const char* filename;
+  const char* message;
+};
+
+using LogMessageCallback = void (*)(LogMessageCallbackArgs);
+
+// This is not thread safe and must be called before using tracing from other
+// threads.
+PERFETTO_EXPORT_COMPONENT void SetLogMessageCallback(
+    LogMessageCallback callback);
+
+PERFETTO_EXPORT_COMPONENT void LogMessage(LogLev,
+                                          const char* fname,
+                                          int line,
+                                          const char* fmt,
+                                          ...) PERFETTO_PRINTF_FORMAT(4, 5);
+
+// This is defined in debug_crash_stack_trace.cc, but that is only linked in
+// standalone && debug builds, see enable_perfetto_stderr_crash_dump in
+// perfetto.gni.
+PERFETTO_EXPORT_COMPONENT void EnableStacktraceOnCrashForDebug();
+
+#if PERFETTO_ENABLE_LOG_RING_BUFFER()
+// Gets a snapshot of the logs from the internal log ring buffer and:
+// - On Android in-tree builds: Passes that to android_set_abort_message().
+//   That will attach the logs to the crash report.
+// - On standalone builds (all otther OSes) prints that on stderr.
+// This function must called only once, right before inducing a crash (This is
+// because android_set_abort_message() can only be called once).
+PERFETTO_EXPORT_COMPONENT void MaybeSerializeLastLogsForCrashReporting();
+#else
+inline void MaybeSerializeLastLogsForCrashReporting() {}
+#endif
+
+#if defined(PERFETTO_ANDROID_ASYNC_SAFE_LOG)
+#define PERFETTO_XLOG(level, fmt, ...)                                        \
+  do {                                                                        \
+    async_safe_format_log((ANDROID_LOG_DEBUG + level), "perfetto",            \
+                          "%s:%d " fmt, ::perfetto::base::Basename(__FILE__), \
+                          __LINE__, ##__VA_ARGS__);                           \
+  } while (0)
+#elif defined(PERFETTO_DISABLE_LOG)
+#define PERFETTO_XLOG(level, fmt, ...) ::perfetto::base::ignore_result(level, \
+                                fmt, ##__VA_ARGS__)
+#else
+#define PERFETTO_XLOG(level, fmt, ...)                                      \
+  ::perfetto::base::LogMessage(level, ::perfetto::base::Basename(__FILE__), \
+                               __LINE__, fmt, ##__VA_ARGS__)
+#endif
+
+#if defined(_MSC_VER)
+#define PERFETTO_IMMEDIATE_CRASH()                               \
+  do {                                                           \
+    ::perfetto::base::MaybeSerializeLastLogsForCrashReporting(); \
+    __debugbreak();                                              \
+    __assume(0);                                                 \
+  } while (0)
+#else
+#define PERFETTO_IMMEDIATE_CRASH()                               \
+  do {                                                           \
+    ::perfetto::base::MaybeSerializeLastLogsForCrashReporting(); \
+    __builtin_trap();                                            \
+    __builtin_unreachable();                                     \
+  } while (0)
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
+#define PERFETTO_LOG(fmt, ...) \
+  PERFETTO_XLOG(::perfetto::base::kLogInfo, fmt, ##__VA_ARGS__)
+#else  // PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
+#define PERFETTO_LOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_VERBOSE_LOGS)
+
+#define PERFETTO_ILOG(fmt, ...) \
+  PERFETTO_XLOG(::perfetto::base::kLogImportant, fmt, ##__VA_ARGS__)
+#define PERFETTO_ELOG(fmt, ...) \
+  PERFETTO_XLOG(::perfetto::base::kLogError, fmt, ##__VA_ARGS__)
+#define PERFETTO_FATAL(fmt, ...)       \
+  do {                                 \
+    PERFETTO_PLOG(fmt, ##__VA_ARGS__); \
+    PERFETTO_IMMEDIATE_CRASH();        \
+  } while (0)
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_PLOG(x, ...) \
+  PERFETTO_ELOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno))
+#else
+// MSVC expands __VA_ARGS__ in a different order. Give up, not worth it.
+#define PERFETTO_PLOG PERFETTO_ELOG
+#endif
+
+#define PERFETTO_CHECK(x)                            \
+  do {                                               \
+    if (PERFETTO_UNLIKELY(!(x))) {                   \
+      PERFETTO_PLOG("%s", "PERFETTO_CHECK(" #x ")"); \
+      PERFETTO_IMMEDIATE_CRASH();                    \
+    }                                                \
+  } while (0)
+
+#if PERFETTO_DLOG_IS_ON()
+
+#define PERFETTO_DLOG(fmt, ...) \
+  PERFETTO_XLOG(::perfetto::base::kLogDebug, fmt, ##__VA_ARGS__)
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_DPLOG(x, ...) \
+  PERFETTO_DLOG(x " (errno: %d, %s)", ##__VA_ARGS__, errno, strerror(errno))
+#else
+// MSVC expands __VA_ARGS__ in a different order. Give up, not worth it.
+#define PERFETTO_DPLOG PERFETTO_DLOG
+#endif
+
+#else  // PERFETTO_DLOG_IS_ON()
+
+#define PERFETTO_DLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
+#define PERFETTO_DPLOG(...) ::perfetto::base::ignore_result(__VA_ARGS__)
+
+#endif  // PERFETTO_DLOG_IS_ON()
+
+#if PERFETTO_DCHECK_IS_ON()
+
+#define PERFETTO_DCHECK(x) PERFETTO_CHECK(x)
+#define PERFETTO_DFATAL(...) PERFETTO_FATAL(__VA_ARGS__)
+#define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_DFATAL(__VA_ARGS__)
+
+#else  // PERFETTO_DCHECK_IS_ON()
+
+#define PERFETTO_DCHECK(x) \
+  do {                     \
+  } while (false && (x))
+
+#define PERFETTO_DFATAL(...) ::perfetto::base::ignore_result(__VA_ARGS__)
+#define PERFETTO_DFATAL_OR_ELOG(...) PERFETTO_ELOG(__VA_ARGS__)
+
+#endif  // PERFETTO_DCHECK_IS_ON()
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_LOGGING_H_
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_TIME_H_
+#define INCLUDE_PERFETTO_BASE_TIME_H_
+
+#include <time.h>
+
+#include <chrono>
+#include <optional>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+#include <mach/mach_init.h>
+#include <mach/mach_port.h>
+#include <mach/mach_time.h>
+#include <mach/thread_act.h>
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+#include <emscripten/emscripten.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+using TimeSeconds = std::chrono::seconds;
+using TimeMillis = std::chrono::milliseconds;
+using TimeNanos = std::chrono::nanoseconds;
+
+inline TimeNanos FromPosixTimespec(const struct timespec& ts) {
+  return TimeNanos(ts.tv_sec * 1000000000LL + ts.tv_nsec);
+}
+
+void SleepMicroseconds(unsigned interval_us);
+void InitializeTime();
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+TimeNanos GetWallTimeNs();
+TimeNanos GetThreadCPUTimeNs();
+inline TimeNanos GetWallTimeRawNs() {
+  return GetWallTimeNs();
+}
+
+// TODO: Clock that counts time during suspend is not implemented on Windows.
+inline TimeNanos GetBootTimeNs() {
+  return GetWallTimeNs();
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+
+inline TimeNanos GetWallTimeNs() {
+  auto init_timebase_info = []() -> mach_timebase_info_data_t {
+    mach_timebase_info_data_t timebase_info;
+    mach_timebase_info(&timebase_info);
+    return timebase_info;
+  };
+
+  static mach_timebase_info_data_t timebase_info = init_timebase_info();
+  uint64_t mach_time = mach_absolute_time();
+
+  // Take the fast path when the conversion is 1:1. The result will for sure fit
+  // into an int_64 because we're going from nanoseconds to microseconds.
+  if (timebase_info.numer == timebase_info.denom) {
+    return TimeNanos(mach_time);
+  }
+
+  // Nanoseconds is mach_time * timebase.numer // timebase.denom. Divide first
+  // to reduce the chance of overflow. Also stash the remainder right now,
+  // a likely byproduct of the division.
+  uint64_t nanoseconds = mach_time / timebase_info.denom;
+  const uint64_t mach_time_remainder = mach_time % timebase_info.denom;
+
+  // Now multiply, keeping an eye out for overflow.
+  PERFETTO_CHECK(!__builtin_umulll_overflow(nanoseconds, timebase_info.numer,
+                                            &nanoseconds));
+
+  // By dividing first we lose precision. Regain it by adding back the
+  // nanoseconds from the remainder, with an eye out for overflow.
+  uint64_t least_significant_nanoseconds =
+      (mach_time_remainder * timebase_info.numer) / timebase_info.denom;
+  PERFETTO_CHECK(!__builtin_uaddll_overflow(
+      nanoseconds, least_significant_nanoseconds, &nanoseconds));
+
+  return TimeNanos(nanoseconds);
+}
+
+inline TimeNanos GetWallTimeRawNs() {
+  return GetWallTimeNs();
+}
+
+// TODO: Clock that counts time during suspend is not implemented on Mac.
+inline TimeNanos GetBootTimeNs() {
+  return GetWallTimeNs();
+}
+
+// Before MacOS 10.12 clock_gettime() was not implemented.
+#if __MAC_OS_X_VERSION_MIN_REQUIRED < 101200
+inline TimeNanos GetThreadCPUTimeNs() {
+  mach_port_t this_thread = mach_thread_self();
+  mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
+  thread_basic_info_data_t info{};
+  kern_return_t kr =
+      thread_info(this_thread, THREAD_BASIC_INFO,
+                  reinterpret_cast<thread_info_t>(&info), &count);
+  mach_port_deallocate(mach_task_self(), this_thread);
+
+  if (kr != KERN_SUCCESS) {
+    PERFETTO_DFATAL("Failed to get CPU time.");
+    return TimeNanos(0);
+  }
+  return TimeNanos(info.user_time.seconds * 1000000000LL +
+                   info.user_time.microseconds * 1000LL +
+                   info.system_time.seconds * 1000000000LL +
+                   info.system_time.microseconds * 1000LL);
+}
+#else
+inline TimeNanos GetThreadCPUTimeNs() {
+  struct timespec ts = {};
+  PERFETTO_CHECK(clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0);
+  return FromPosixTimespec(ts);
+}
+#endif
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
+
+inline TimeNanos GetWallTimeNs() {
+  return TimeNanos(static_cast<uint64_t>(emscripten_get_now()) * 1000000);
+}
+
+inline TimeNanos GetWallTimeRawNs() {
+  return GetWallTimeNs();
+}
+
+inline TimeNanos GetThreadCPUTimeNs() {
+  return TimeNanos(0);
+}
+
+// TODO: Clock that counts time during suspend is not implemented on WASM.
+inline TimeNanos GetBootTimeNs() {
+  return GetWallTimeNs();
+}
+
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+
+// Tracing time doesn't need to work on NaCl since its going away shortly. We
+// just need to compile on it. The only function NaCl could support is
+// GetWallTimeNs(), but to prevent false hope we leave it unimplemented.
+
+inline TimeNanos GetWallTimeNs() {
+  return TimeNanos(0);
+}
+
+inline TimeNanos GetWallTimeRawNs() {
+  return TimeNanos(0);
+}
+
+inline TimeNanos GetThreadCPUTimeNs() {
+  return TimeNanos(0);
+}
+
+inline TimeNanos GetBootTimeNs() {
+  return TimeNanos(0);
+}
+
+#else  // posix
+
+constexpr clockid_t kWallTimeClockSource = CLOCK_MONOTONIC;
+
+inline TimeNanos GetTimeInternalNs(clockid_t clk_id) {
+  struct timespec ts = {};
+  PERFETTO_CHECK(clock_gettime(clk_id, &ts) == 0);
+  return FromPosixTimespec(ts);
+}
+
+// Return ns from boot. Conversely to GetWallTimeNs, this clock counts also time
+// during suspend (when supported).
+inline TimeNanos GetBootTimeNs() {
+  // Determine if CLOCK_BOOTTIME is available on the first call.
+  static const clockid_t kBootTimeClockSource = [] {
+    struct timespec ts = {};
+    int res = clock_gettime(CLOCK_BOOTTIME, &ts);
+    return res == 0 ? CLOCK_BOOTTIME : kWallTimeClockSource;
+  }();
+  return GetTimeInternalNs(kBootTimeClockSource);
+}
+
+inline TimeNanos GetWallTimeNs() {
+  return GetTimeInternalNs(kWallTimeClockSource);
+}
+
+inline TimeNanos GetWallTimeRawNs() {
+  return GetTimeInternalNs(CLOCK_MONOTONIC_RAW);
+}
+
+inline TimeNanos GetThreadCPUTimeNs() {
+  return GetTimeInternalNs(CLOCK_THREAD_CPUTIME_ID);
+}
+#endif
+
+inline TimeSeconds GetBootTimeS() {
+  return std::chrono::duration_cast<TimeSeconds>(GetBootTimeNs());
+}
+
+inline TimeMillis GetBootTimeMs() {
+  return std::chrono::duration_cast<TimeMillis>(GetBootTimeNs());
+}
+
+inline TimeMillis GetWallTimeMs() {
+  return std::chrono::duration_cast<TimeMillis>(GetWallTimeNs());
+}
+
+inline TimeSeconds GetWallTimeS() {
+  return std::chrono::duration_cast<TimeSeconds>(GetWallTimeNs());
+}
+
+inline struct timespec ToPosixTimespec(TimeMillis time) {
+  struct timespec ts {};
+  const long time_s = static_cast<long>(time.count() / 1000);
+  ts.tv_sec = time_s;
+  ts.tv_nsec = (static_cast<long>(time.count()) - time_s * 1000L) * 1000000L;
+  return ts;
+}
+
+std::string GetTimeFmt(const std::string& fmt);
+
+inline int64_t TimeGm(struct tm* tms) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  return static_cast<int64_t>(_mkgmtime(tms));
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+  // NaCL has no timegm.
+  if (tms)  // Kinda if (true), but avoids "mark as noreturn" errors.
+    PERFETTO_FATAL("timegm not supported");
+  return -1;
+#else
+  return static_cast<int64_t>(timegm(tms));
+#endif
+}
+
+// Creates a time_t-compatible timestamp (seconds since epoch) from a tuple of
+// y-m-d-h-m-s. It's a saner version of timegm(). Some remarks:
+// The year is just the actual year (it's Y-1900 in timegm()).
+// The month ranges 1-12 (it's 0-11 in timegm()).
+inline int64_t MkTime(int year, int month, int day, int h, int m, int s) {
+  PERFETTO_DCHECK(year >= 1900);
+  PERFETTO_DCHECK(month > 0 && month <= 12);
+  PERFETTO_DCHECK(day > 0 && day <= 31);
+  struct tm tms {};
+  tms.tm_year = year - 1900;
+  tms.tm_mon = month - 1;
+  tms.tm_mday = day;
+  tms.tm_hour = h;
+  tms.tm_min = m;
+  tms.tm_sec = s;
+  return TimeGm(&tms);
+}
+
+std::optional<int32_t> GetTimezoneOffsetMins();
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_TIME_H_
+// gen_amalgamated begin header: include/perfetto/tracing/buffer_exhausted_policy.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_BUFFER_EXHAUSTED_POLICY_H_
+#define INCLUDE_PERFETTO_TRACING_BUFFER_EXHAUSTED_POLICY_H_
+
+namespace perfetto {
+
+// Determines how SharedMemoryArbiterImpl::GetNewChunk() behaves when no free
+// chunks are available.
+enum class BufferExhaustedPolicy {
+  // SharedMemoryArbiterImpl::GetNewChunk() will stall if no free SMB chunk is
+  // available and wait for the tracing service to free one. Note that this
+  // requires that messages the arbiter sends to the tracing service (from any
+  // TraceWriter thread) will be received by it, even if all TraceWriter threads
+  // are stalled.
+  kStall,
+
+  // SharedMemoryArbiterImpl::GetNewChunk() will return an invalid chunk if no
+  // free SMB chunk is available. In this case, the TraceWriter will fall back
+  // to a garbage chunk and drop written data until acquiring a future chunk
+  // succeeds again.
+  kDrop,
+
+  // TODO(eseckler): Switch to kDrop by default and change the Android code to
+  // explicitly request kStall instead.
+  kDefault = kStall
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_BUFFER_EXHAUSTED_POLICY_H_
+// gen_amalgamated begin header: include/perfetto/tracing/console_interceptor.h
+// gen_amalgamated begin header: include/perfetto/tracing/interceptor.h
+// gen_amalgamated begin header: include/perfetto/protozero/field.h
+// gen_amalgamated begin header: include/perfetto/protozero/contiguous_memory_range.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_CONTIGUOUS_MEMORY_RANGE_H_
+#define INCLUDE_PERFETTO_PROTOZERO_CONTIGUOUS_MEMORY_RANGE_H_
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+namespace protozero {
+
+// Keep this struct trivially constructible (no ctors, no default initializers).
+struct ContiguousMemoryRange {
+  uint8_t* begin;
+  uint8_t* end;  // STL style: one byte past the end of the buffer.
+
+  inline bool is_valid() const { return begin != nullptr; }
+  inline void reset() { begin = nullptr; }
+  inline size_t size() const { return static_cast<size_t>(end - begin); }
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_CONTIGUOUS_MEMORY_RANGE_H_
+// gen_amalgamated begin header: include/perfetto/protozero/proto_utils.h
+// gen_amalgamated begin header: include/perfetto/public/pb_utils.h
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PUBLIC_PB_UTILS_H_
+#define INCLUDE_PERFETTO_PUBLIC_PB_UTILS_H_
+
+#include <assert.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/public/compiler.h"
+
+// Type of fields that can be found in a protobuf serialized message.
+enum PerfettoPbWireType {
+  PERFETTO_PB_WIRE_TYPE_VARINT = 0,
+  PERFETTO_PB_WIRE_TYPE_FIXED64 = 1,
+  PERFETTO_PB_WIRE_TYPE_DELIMITED = 2,
+  PERFETTO_PB_WIRE_TYPE_FIXED32 = 5,
+};
+
+// Creates a field tag, which encodes the field type and the field id.
+static inline uint32_t PerfettoPbMakeTag(int32_t field_id,
+                                         enum PerfettoPbWireType wire_type) {
+  return ((PERFETTO_STATIC_CAST(uint32_t, field_id)) << 3) |
+         PERFETTO_STATIC_CAST(uint32_t, wire_type);
+}
+
+enum {
+  // Maximum bytes size of a 64-bit integer encoded as a VarInt.
+  PERFETTO_PB_VARINT_MAX_SIZE_64 = 10,
+  // Maximum bytes size of a 32-bit integer encoded as a VarInt.
+  PERFETTO_PB_VARINT_MAX_SIZE_32 = 5,
+};
+
+// Encodes `value` as a VarInt into `*dst`.
+//
+// `dst` must point into a buffer big enough to represent `value`:
+// PERFETTO_PB_VARINT_MAX_SIZE_* can help.
+static inline uint8_t* PerfettoPbWriteVarInt(uint64_t value, uint8_t* dst) {
+  uint8_t byte;
+  while (value >= 0x80) {
+    byte = (value & 0x7f) | 0x80;
+    *dst++ = byte;
+    value >>= 7;
+  }
+  byte = value & 0x7f;
+  *dst++ = byte;
+
+  return dst;
+}
+
+// Encodes `value` as a fixed32 (little endian) into `*dst`.
+//
+// `dst` must point into a buffer with at least 4 bytes of space.
+static inline uint8_t* PerfettoPbWriteFixed32(uint32_t value, uint8_t* buf) {
+  buf[0] = PERFETTO_STATIC_CAST(uint8_t, value);
+  buf[1] = PERFETTO_STATIC_CAST(uint8_t, value >> 8);
+  buf[2] = PERFETTO_STATIC_CAST(uint8_t, value >> 16);
+  buf[3] = PERFETTO_STATIC_CAST(uint8_t, value >> 24);
+  return buf + 4;
+}
+
+// Encodes `value` as a fixed32 (little endian) into `*dst`.
+//
+// `dst` must point into a buffer with at least 8 bytes of space.
+static inline uint8_t* PerfettoPbWriteFixed64(uint64_t value, uint8_t* buf) {
+  buf[0] = PERFETTO_STATIC_CAST(uint8_t, value);
+  buf[1] = PERFETTO_STATIC_CAST(uint8_t, value >> 8);
+  buf[2] = PERFETTO_STATIC_CAST(uint8_t, value >> 16);
+  buf[3] = PERFETTO_STATIC_CAST(uint8_t, value >> 24);
+  buf[4] = PERFETTO_STATIC_CAST(uint8_t, value >> 32);
+  buf[5] = PERFETTO_STATIC_CAST(uint8_t, value >> 40);
+  buf[6] = PERFETTO_STATIC_CAST(uint8_t, value >> 48);
+  buf[7] = PERFETTO_STATIC_CAST(uint8_t, value >> 56);
+  return buf + 8;
+}
+
+// Parses a VarInt from the encoded buffer [start, end). |end| is STL-style and
+// points one byte past the end of buffer.
+// The parsed int value is stored in the output arg |value|. Returns a pointer
+// to the next unconsumed byte (so start < retval <= end) or |start| if the
+// VarInt could not be fully parsed because there was not enough space in the
+// buffer.
+static inline const uint8_t* PerfettoPbParseVarInt(const uint8_t* start,
+                                                   const uint8_t* end,
+                                                   uint64_t* out_value) {
+  const uint8_t* pos = start;
+  uint64_t value = 0;
+  for (uint32_t shift = 0; pos < end && shift < 64u; shift += 7) {
+    // Cache *pos into |cur_byte| to prevent that the compiler dereferences the
+    // pointer twice (here and in the if() below) due to char* aliasing rules.
+    uint8_t cur_byte = *pos++;
+    value |= PERFETTO_STATIC_CAST(uint64_t, cur_byte & 0x7f) << shift;
+    if ((cur_byte & 0x80) == 0) {
+      // In valid cases we get here.
+      *out_value = value;
+      return pos;
+    }
+  }
+  *out_value = 0;
+  return start;
+}
+
+static inline uint32_t PerfettoPbZigZagEncode32(int32_t value) {
+#if defined(__cplusplus) || \
+    (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
+  // Right-shift of negative values is implementation specific.
+  // Assert the implementation does what we expect, which is that shifting an
+  // positive int32_t by 31 gives an all 0 bitmap, and a negative int32_t gives
+  // an all 1 bitmap.
+  static_assert(
+      PERFETTO_STATIC_CAST(uint32_t, INT32_C(-1) >> 31) == ~UINT32_C(0),
+      "implementation does not support assumed rightshift");
+  static_assert(PERFETTO_STATIC_CAST(uint32_t, INT32_C(1) >> 31) == UINT32_C(0),
+                "implementation does not support assumed rightshift");
+#endif
+
+  return (PERFETTO_STATIC_CAST(uint32_t, value) << 1) ^
+         PERFETTO_STATIC_CAST(uint32_t, value >> 31);
+}
+
+static inline uint64_t PerfettoPbZigZagEncode64(int64_t value) {
+#if defined(__cplusplus) || \
+    (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
+  // Right-shift of negative values is implementation specific.
+  // Assert the implementation does what we expect, which is that shifting an
+  // positive int64_t by 63 gives an all 0 bitmap, and a negative int64_t gives
+  // an all 1 bitmap.
+  static_assert(
+      PERFETTO_STATIC_CAST(uint64_t, INT64_C(-1) >> 63) == ~UINT64_C(0),
+      "implementation does not support assumed rightshift");
+  static_assert(PERFETTO_STATIC_CAST(uint64_t, INT64_C(1) >> 63) == UINT64_C(0),
+                "implementation does not support assumed rightshift");
+#endif
+
+  return (PERFETTO_STATIC_CAST(uint64_t, value) << 1) ^
+         PERFETTO_STATIC_CAST(uint64_t, value >> 63);
+}
+
+static inline int32_t PerfettoPbZigZagDecode32(uint32_t value) {
+  uint32_t mask =
+      PERFETTO_STATIC_CAST(uint32_t, -PERFETTO_STATIC_CAST(int32_t, value & 1));
+  return PERFETTO_STATIC_CAST(int32_t, ((value >> 1) ^ mask));
+}
+
+static inline int64_t PerfettoPbZigZagDecode64(uint64_t value) {
+  uint64_t mask =
+      PERFETTO_STATIC_CAST(uint64_t, -PERFETTO_STATIC_CAST(int64_t, value & 1));
+  return PERFETTO_STATIC_CAST(int64_t, ((value >> 1) ^ mask));
+}
+
+#endif  // INCLUDE_PERFETTO_PUBLIC_PB_UTILS_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
+#define INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
+
+#include <stddef.h>
+
+#include <cinttypes>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/public/pb_utils.h"
+
+// Helper macro for the constexpr functions containing
+// the switch statement: if C++14 is supported, this macro
+// resolves to `constexpr` and just `inline` otherwise.
+#if __cpp_constexpr >= 201304
+#define PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE constexpr
+#else
+#define PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE inline
+#endif
+
+namespace protozero {
+namespace proto_utils {
+
+// See https://developers.google.com/protocol-buffers/docs/encoding wire types.
+// This is a type encoded into the proto that provides just enough info to
+// find the length of the following value.
+enum class ProtoWireType : uint32_t {
+  kVarInt = 0,
+  kFixed64 = 1,
+  kLengthDelimited = 2,
+  kFixed32 = 5,
+};
+
+// This is the type defined in the proto for each field. This information
+// is used to decide the translation strategy when writing the trace.
+enum class ProtoSchemaType {
+  kUnknown = 0,
+  kDouble,
+  kFloat,
+  kInt64,
+  kUint64,
+  kInt32,
+  kFixed64,
+  kFixed32,
+  kBool,
+  kString,
+  kGroup,  // Deprecated (proto2 only)
+  kMessage,
+  kBytes,
+  kUint32,
+  kEnum,
+  kSfixed32,
+  kSfixed64,
+  kSint32,
+  kSint64,
+};
+
+inline const char* ProtoSchemaToString(ProtoSchemaType v) {
+  switch (v) {
+    case ProtoSchemaType::kUnknown:
+      return "unknown";
+    case ProtoSchemaType::kDouble:
+      return "double";
+    case ProtoSchemaType::kFloat:
+      return "float";
+    case ProtoSchemaType::kInt64:
+      return "int64";
+    case ProtoSchemaType::kUint64:
+      return "uint64";
+    case ProtoSchemaType::kInt32:
+      return "int32";
+    case ProtoSchemaType::kFixed64:
+      return "fixed64";
+    case ProtoSchemaType::kFixed32:
+      return "fixed32";
+    case ProtoSchemaType::kBool:
+      return "bool";
+    case ProtoSchemaType::kString:
+      return "string";
+    case ProtoSchemaType::kGroup:
+      return "group";
+    case ProtoSchemaType::kMessage:
+      return "message";
+    case ProtoSchemaType::kBytes:
+      return "bytes";
+    case ProtoSchemaType::kUint32:
+      return "uint32";
+    case ProtoSchemaType::kEnum:
+      return "enum";
+    case ProtoSchemaType::kSfixed32:
+      return "sfixed32";
+    case ProtoSchemaType::kSfixed64:
+      return "sfixed64";
+    case ProtoSchemaType::kSint32:
+      return "sint32";
+    case ProtoSchemaType::kSint64:
+      return "sint64";
+  }
+  // For gcc:
+  PERFETTO_DCHECK(false);
+  return "";
+}
+
+// Maximum message size supported: 256 MiB (4 x 7-bit due to varint encoding).
+constexpr size_t kMessageLengthFieldSize = 4;
+constexpr size_t kMaxMessageLength = (1u << (kMessageLengthFieldSize * 7)) - 1;
+constexpr size_t kMaxOneByteMessageLength = (1 << 7) - 1;
+
+// Field tag is encoded as 32-bit varint (5 bytes at most).
+// Largest value of simple (not length-delimited) field is 64-bit varint
+// (10 bytes at most). 15 bytes buffer is enough to store a simple field.
+constexpr size_t kMaxTagEncodedSize = 5;
+constexpr size_t kMaxSimpleFieldEncodedSize = kMaxTagEncodedSize + 10;
+
+// Proto types: (int|uint|sint)(32|64), bool, enum.
+constexpr uint32_t MakeTagVarInt(uint32_t field_id) {
+  return (field_id << 3) | static_cast<uint32_t>(ProtoWireType::kVarInt);
+}
+
+// Proto types: fixed64, sfixed64, fixed32, sfixed32, double, float.
+template <typename T>
+constexpr uint32_t MakeTagFixed(uint32_t field_id) {
+  static_assert(sizeof(T) == 8 || sizeof(T) == 4, "Value must be 4 or 8 bytes");
+  return (field_id << 3) |
+         static_cast<uint32_t>((sizeof(T) == 8 ? ProtoWireType::kFixed64
+                                               : ProtoWireType::kFixed32));
+}
+
+// Proto types: string, bytes, embedded messages.
+constexpr uint32_t MakeTagLengthDelimited(uint32_t field_id) {
+  return (field_id << 3) |
+         static_cast<uint32_t>(ProtoWireType::kLengthDelimited);
+}
+
+// Proto types: sint64, sint32.
+template <typename T>
+inline typename std::make_unsigned<T>::type ZigZagEncode(T value) {
+  using UnsignedType = typename std::make_unsigned<T>::type;
+
+  // Right-shift of negative values is implementation specific.
+  // Assert the implementation does what we expect, which is that shifting any
+  // positive value by sizeof(T) * 8 - 1 gives an all 0 bitmap, and a negative
+  // value gives an all 1 bitmap.
+  constexpr uint64_t kUnsignedZero = 0u;
+  constexpr int64_t kNegativeOne = -1;
+  constexpr int64_t kPositiveOne = 1;
+  static_assert(static_cast<uint64_t>(kNegativeOne >> 63) == ~kUnsignedZero,
+                "implementation does not support assumed rightshift");
+  static_assert(static_cast<uint64_t>(kPositiveOne >> 63) == kUnsignedZero,
+                "implementation does not support assumed rightshift");
+
+  return (static_cast<UnsignedType>(value) << 1) ^
+         static_cast<UnsignedType>(value >> (sizeof(T) * 8 - 1));
+}
+
+// Proto types: sint64, sint32.
+template <typename T>
+inline typename std::make_signed<T>::type ZigZagDecode(T value) {
+  using UnsignedType = typename std::make_unsigned<T>::type;
+  using SignedType = typename std::make_signed<T>::type;
+  auto u_value = static_cast<UnsignedType>(value);
+  auto mask = static_cast<UnsignedType>(-static_cast<SignedType>(u_value & 1));
+  return static_cast<SignedType>((u_value >> 1) ^ mask);
+}
+
+template <typename T>
+auto ExtendValueForVarIntSerialization(T value) -> typename std::make_unsigned<
+    typename std::conditional<std::is_unsigned<T>::value, T, int64_t>::type>::
+    type {
+  // If value is <= 0 we must first sign extend to int64_t (see [1]).
+  // Finally we always cast to an unsigned value to to avoid arithmetic
+  // (sign expanding) shifts in the while loop.
+  // [1]: "If you use int32 or int64 as the type for a negative number, the
+  // resulting varint is always ten bytes long".
+  // - developers.google.com/protocol-buffers/docs/encoding
+  // So for each input type we do the following casts:
+  // uintX_t -> uintX_t -> uintX_t
+  // int8_t  -> int64_t -> uint64_t
+  // int16_t -> int64_t -> uint64_t
+  // int32_t -> int64_t -> uint64_t
+  // int64_t -> int64_t -> uint64_t
+  using MaybeExtendedType =
+      typename std::conditional<std::is_unsigned<T>::value, T, int64_t>::type;
+  using UnsignedType = typename std::make_unsigned<MaybeExtendedType>::type;
+
+  MaybeExtendedType extended_value = static_cast<MaybeExtendedType>(value);
+  UnsignedType unsigned_value = static_cast<UnsignedType>(extended_value);
+
+  return unsigned_value;
+}
+
+template <typename T>
+inline uint8_t* WriteVarInt(T value, uint8_t* target) {
+  auto unsigned_value = ExtendValueForVarIntSerialization(value);
+
+  while (unsigned_value >= 0x80) {
+    *target++ = static_cast<uint8_t>(unsigned_value) | 0x80;
+    unsigned_value >>= 7;
+  }
+  *target = static_cast<uint8_t>(unsigned_value);
+  return target + 1;
+}
+
+// Writes a fixed-size redundant encoding of the given |value|. This is
+// used to backfill fixed-size reservations for the length field using a
+// non-canonical varint encoding (e.g. \x81\x80\x80\x00 instead of \x01).
+// See https://github.com/google/protobuf/issues/1530.
+// This is used mainly in two cases:
+// 1) At trace writing time, when starting a nested messages. The size of a
+//    nested message is not known until all its field have been written.
+//    |kMessageLengthFieldSize| bytes are reserved to encode the size field and
+//    backfilled at the end.
+// 2) When rewriting a message at trace filtering time, in protozero/filtering.
+//    At that point we know only the upper bound of the length (a filtered
+//    message is <= the original one) and we backfill after the message has been
+//    filtered.
+inline void WriteRedundantVarInt(uint32_t value,
+                                 uint8_t* buf,
+                                 size_t size = kMessageLengthFieldSize) {
+  for (size_t i = 0; i < size; ++i) {
+    const uint8_t msb = (i < size - 1) ? 0x80 : 0;
+    buf[i] = static_cast<uint8_t>(value) | msb;
+    value >>= 7;
+  }
+}
+
+template <uint32_t field_id>
+void StaticAssertSingleBytePreamble() {
+  static_assert(field_id < 16,
+                "Proto field id too big to fit in a single byte preamble");
+}
+
+// Parses a VarInt from the encoded buffer [start, end). |end| is STL-style and
+// points one byte past the end of buffer.
+// The parsed int value is stored in the output arg |value|. Returns a pointer
+// to the next unconsumed byte (so start < retval <= end) or |start| if the
+// VarInt could not be fully parsed because there was not enough space in the
+// buffer.
+inline const uint8_t* ParseVarInt(const uint8_t* start,
+                                  const uint8_t* end,
+                                  uint64_t* out_value) {
+  return PerfettoPbParseVarInt(start, end, out_value);
+}
+
+enum class RepetitionType {
+  kNotRepeated,
+  kRepeatedPacked,
+  kRepeatedNotPacked,
+};
+
+// Provide a common base struct for all templated FieldMetadata types to allow
+// simple checks if a given type is a FieldMetadata or not.
+struct FieldMetadataBase {
+  constexpr FieldMetadataBase() = default;
+};
+
+template <uint32_t field_id,
+          RepetitionType repetition_type,
+          ProtoSchemaType proto_schema_type,
+          typename CppFieldType,
+          typename MessageType>
+struct FieldMetadata : public FieldMetadataBase {
+  constexpr FieldMetadata() = default;
+
+  static constexpr int kFieldId = field_id;
+  // Whether this field is repeated, packed (repeated [packed-true]) or not
+  // (optional).
+  static constexpr RepetitionType kRepetitionType = repetition_type;
+  // Proto type of this field (e.g. int64, fixed32 or nested message).
+  static constexpr ProtoSchemaType kProtoFieldType = proto_schema_type;
+  // C++ type of this field (for nested messages - C++ protozero class).
+  using cpp_field_type = CppFieldType;
+  // Protozero message which this field belongs to.
+  using message_type = MessageType;
+};
+
+}  // namespace proto_utils
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_PROTO_UTILS_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_FIELD_H_
+#define INCLUDE_PERFETTO_PROTOZERO_FIELD_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+struct ConstBytes {
+  std::string ToStdString() const {
+    return std::string(reinterpret_cast<const char*>(data), size);
+  }
+
+  const uint8_t* data;
+  size_t size;
+};
+
+struct ConstChars {
+  // Allow implicit conversion to perfetto's base::StringView without depending
+  // on perfetto/base or viceversa.
+  static constexpr bool kConvertibleToStringView = true;
+  std::string ToStdString() const { return std::string(data, size); }
+
+  const char* data;
+  size_t size;
+};
+
+// A protobuf field decoded by the protozero proto decoders. It exposes
+// convenience accessors with minimal debug checks.
+// This class is used both by the iterator-based ProtoDecoder and by the
+// one-shot TypedProtoDecoder.
+// If the field is not valid the accessors consistently return zero-integers or
+// null strings.
+class Field {
+ public:
+  bool valid() const { return id_ != 0; }
+  uint32_t id() const { return id_; }
+  explicit operator bool() const { return valid(); }
+
+  proto_utils::ProtoWireType type() const {
+    auto res = static_cast<proto_utils::ProtoWireType>(type_);
+    PERFETTO_DCHECK(res == proto_utils::ProtoWireType::kVarInt ||
+                    res == proto_utils::ProtoWireType::kLengthDelimited ||
+                    res == proto_utils::ProtoWireType::kFixed32 ||
+                    res == proto_utils::ProtoWireType::kFixed64);
+    return res;
+  }
+
+  bool as_bool() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt);
+    return static_cast<bool>(int_value_);
+  }
+
+  uint32_t as_uint32() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
+                    type() == proto_utils::ProtoWireType::kFixed32);
+    return static_cast<uint32_t>(int_value_);
+  }
+
+  int32_t as_int32() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
+                    type() == proto_utils::ProtoWireType::kFixed32);
+    return static_cast<int32_t>(int_value_);
+  }
+
+  int32_t as_sint32() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt);
+    return proto_utils::ZigZagDecode(static_cast<uint32_t>(int_value_));
+  }
+
+  uint64_t as_uint64() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
+                    type() == proto_utils::ProtoWireType::kFixed32 ||
+                    type() == proto_utils::ProtoWireType::kFixed64);
+    return int_value_;
+  }
+
+  int64_t as_int64() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt ||
+                    type() == proto_utils::ProtoWireType::kFixed32 ||
+                    type() == proto_utils::ProtoWireType::kFixed64);
+    return static_cast<int64_t>(int_value_);
+  }
+
+  int64_t as_sint64() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kVarInt);
+    return proto_utils::ZigZagDecode(static_cast<uint64_t>(int_value_));
+  }
+
+  float as_float() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kFixed32);
+    float res;
+    uint32_t value32 = static_cast<uint32_t>(int_value_);
+    memcpy(&res, &value32, sizeof(res));
+    return res;
+  }
+
+  double as_double() const {
+    PERFETTO_DCHECK(!valid() || type() == proto_utils::ProtoWireType::kFixed64);
+    double res;
+    memcpy(&res, &int_value_, sizeof(res));
+    return res;
+  }
+
+  ConstChars as_string() const {
+    PERFETTO_DCHECK(!valid() ||
+                    type() == proto_utils::ProtoWireType::kLengthDelimited);
+    return ConstChars{reinterpret_cast<const char*>(data()), size_};
+  }
+
+  std::string as_std_string() const { return as_string().ToStdString(); }
+
+  ConstBytes as_bytes() const {
+    PERFETTO_DCHECK(!valid() ||
+                    type() == proto_utils::ProtoWireType::kLengthDelimited);
+    return ConstBytes{data(), size_};
+  }
+
+  const uint8_t* data() const {
+    PERFETTO_DCHECK(!valid() ||
+                    type() == proto_utils::ProtoWireType::kLengthDelimited);
+    return reinterpret_cast<const uint8_t*>(int_value_);
+  }
+
+  size_t size() const {
+    PERFETTO_DCHECK(!valid() ||
+                    type() == proto_utils::ProtoWireType::kLengthDelimited);
+    return size_;
+  }
+
+  uint64_t raw_int_value() const { return int_value_; }
+
+  void initialize(uint32_t id,
+                  uint8_t type,
+                  uint64_t int_value,
+                  uint32_t size) {
+    id_ = id & kMaxId;
+    type_ = type;
+    int_value_ = int_value;
+    size_ = size;
+  }
+
+  // For use with templates. This is used by RepeatedFieldIterator::operator*().
+  void get(bool* val) const { *val = as_bool(); }
+  void get(uint32_t* val) const { *val = as_uint32(); }
+  void get(int32_t* val) const { *val = as_int32(); }
+  void get(uint64_t* val) const { *val = as_uint64(); }
+  void get(int64_t* val) const { *val = as_int64(); }
+  void get(float* val) const { *val = as_float(); }
+  void get(double* val) const { *val = as_double(); }
+  void get(std::string* val) const { *val = as_std_string(); }
+  void get(ConstChars* val) const { *val = as_string(); }
+  void get(ConstBytes* val) const { *val = as_bytes(); }
+  void get_signed(int32_t* val) const { *val = as_sint32(); }
+  void get_signed(int64_t* val) const { *val = as_sint64(); }
+
+  // For enum types.
+  template <typename T,
+            typename = typename std::enable_if<std::is_enum<T>::value, T>::type>
+  void get(T* val) const {
+    *val = static_cast<T>(as_int32());
+  }
+
+  // Serializes the field back into a proto-encoded byte stream and appends it
+  // to |dst|. |dst| is resized accordingly.
+  void SerializeAndAppendTo(std::string* dst) const;
+
+  // Serializes the field back into a proto-encoded byte stream and appends it
+  // to |dst|. |dst| is resized accordingly.
+  void SerializeAndAppendTo(std::vector<uint8_t>* dst) const;
+
+  static constexpr uint32_t kMaxId = (1 << 24) - 1;  // See id_ : 24 below.
+ private:
+  template <typename Container>
+  void SerializeAndAppendToInternal(Container* dst) const;
+
+  // Fields are deliberately not initialized to keep the class trivially
+  // constructible. It makes a large perf difference for ProtoDecoder.
+  uint64_t int_value_;  // In kLengthDelimited this contains the data() addr.
+  uint32_t size_;       // Only valid when when type == kLengthDelimited.
+
+  // Note: MSVC and clang-cl require bit-fields to be of the same type, hence
+  // the `: 8` below rather than uint8_t.
+  uint32_t id_ : 24;   // Proto field ordinal.
+  uint32_t type_ : 8;  // proto_utils::ProtoWireType.
+};
+// The Field struct is used in a lot of perf-sensitive contexts.
+static_assert(sizeof(Field) == 16, "Field struct too big");
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_FIELD_H_
+// gen_amalgamated begin header: include/perfetto/tracing/core/forward_decls.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_FORWARD_DECLS_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_FORWARD_DECLS_H_
+
+// Forward declares classes that are generated at build-time from protos.
+// First of all, why are we forward declaring at all?
+//  1. Chromium diverges from the Google style guide on this, because forward
+//     declarations typically make build times faster, and that's a desirable
+//     property for a large and complex codebase.
+//  2. Adding #include to build-time-generated headers from headers typically
+//     creates subtle build errors that are hard to spot in GN. This is because
+//     once a standard header (say foo.h) has an #include "protos/foo.gen.h",
+//     the build target that depends on foo.h needs to depend on the genrule
+//     that generates foo.gen.h. This is achievable using public_deps in GN but
+//     is not testable / enforceable, hence too easy to get wrong.
+
+// Historically the classes below used to be generated from the corresponding
+// .proto(s) at CL *check-in* time (!= build time) in the ::perfetto namespace.
+// Nowadays we have code everywhere that assume the right class is
+// ::perfetto::TraceConfig or the like. Back then other headers could just
+// forward declared ::perfetto::TraceConfig. These days, the real class is
+// ::perfetto::protos::gen::TraceConfig and core/trace_config.h aliases that as
+// using ::perfetto::TraceConfig = ::perfetto::protos::gen::TraceConfig.
+// In C++ one cannot forward declare a type alias (but only the aliased type).
+// Hence this header, which should be used every time one wants to forward
+// declare classes like TraceConfig.
+
+// The overall plan is that, when one of the classes below is needed:
+// The .h file includes this file.
+// The .cc file includes perfetto/tracing/core/trace_config.h (or equiv). That
+// header will pull the full declaration from trace_config.gen.h and will also
+// setup the alias in the ::perfetto namespace.
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class ChromeConfig;
+class CommitDataRequest;
+class DataSourceConfig;
+class DataSourceDescriptor;
+class ObservableEvents;
+class TraceConfig;
+class TraceStats;
+class TracingServiceCapabilities;
+class TracingServiceState;
+
+}  // namespace gen
+}  // namespace protos
+
+using ChromeConfig = ::perfetto::protos::gen::ChromeConfig;
+using CommitDataRequest = ::perfetto::protos::gen::CommitDataRequest;
+using DataSourceConfig = ::perfetto::protos::gen::DataSourceConfig;
+using DataSourceDescriptor = ::perfetto::protos::gen::DataSourceDescriptor;
+using ObservableEvents = ::perfetto::protos::gen::ObservableEvents;
+using TraceConfig = ::perfetto::protos::gen::TraceConfig;
+using TraceStats = ::perfetto::protos::gen::TraceStats;
+using TracingServiceCapabilities =
+    ::perfetto::protos::gen::TracingServiceCapabilities;
+using TracingServiceState = ::perfetto::protos::gen::TracingServiceState;
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_FORWARD_DECLS_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/basic_types.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_BASIC_TYPES_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_BASIC_TYPES_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace perfetto {
+namespace internal {
+
+// A static_assert in tracing_muxer_impl.cc guarantees that this stays in sync
+// with the definition in tracing/core/basic_types.h
+using BufferId = uint16_t;
+
+// This is an id of a backend in the TracingMuxer::producer_backends_ list.
+// Backends are only added and never removed.
+using TracingBackendId = size_t;
+
+// Max numbers of data sources that can be registered in a process.
+constexpr size_t kMaxDataSources = 32;
+
+// Max instances for each data source type. This typically matches the
+// "max number of concurrent tracing sessions". However remember that a data
+// source can be instantiated more than once within one tracing session by
+// creating two entries for it in the trace config.
+constexpr size_t kMaxDataSourceInstances = 8;
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_BASIC_TYPES_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/data_source_internal.h
+// gen_amalgamated begin header: include/perfetto/tracing/core/data_source_config.h
+// gen_amalgamated begin header: gen/protos/perfetto/config/data_source_config.gen.h
+// gen_amalgamated begin header: include/perfetto/protozero/cpp_message_obj.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_CPP_MESSAGE_OBJ_H_
+#define INCLUDE_PERFETTO_PROTOZERO_CPP_MESSAGE_OBJ_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace protozero {
+
+// Base class for generated .gen.h classes, which are full C++ objects that
+// support both ser and deserialization (but are not zero-copy).
+// This is only used by the "cpp" targets not the "pbzero" ones.
+class PERFETTO_EXPORT_COMPONENT CppMessageObj {
+ public:
+  virtual ~CppMessageObj();
+  virtual std::string SerializeAsString() const = 0;
+  virtual std::vector<uint8_t> SerializeAsArray() const = 0;
+  virtual bool ParseFromArray(const void*, size_t) = 0;
+
+  bool ParseFromString(const std::string& str) {
+    return ParseFromArray(str.data(), str.size());
+  }
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_CPP_MESSAGE_OBJ_H_
+// gen_amalgamated begin header: include/perfetto/protozero/copyable_ptr.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_COPYABLE_PTR_H_
+#define INCLUDE_PERFETTO_PROTOZERO_COPYABLE_PTR_H_
+
+#include <memory>
+
+namespace protozero {
+
+// This class is essentially a std::vector<T> of fixed size = 1.
+// It's a pointer wrapper with deep copying and deep equality comparison.
+// At all effects this wrapper behaves like the underlying T, with the exception
+// of the heap indirection.
+// Conversely to a std::unique_ptr, the pointer will be always valid, never
+// null. The problem it solves is the following: when generating C++ classes
+// from proto files, we want to keep each header hermetic (i.e. not #include
+// headers of dependent types). As such we can't directly instantiate T
+// field members but we can instead rely on pointers, so only the .cc file needs
+// to see the actual definition of T. If the generated classes were move-only we
+// could just use a unique_ptr there. But they aren't, hence this wrapper.
+// Converesely to unique_ptr, this wrapper:
+// - Default constructs the T instance in its constructor.
+// - Implements deep comparison in operator== instead of pointer comparison.
+template <typename T>
+class CopyablePtr {
+ public:
+  CopyablePtr() : ptr_(new T()) {}
+  ~CopyablePtr() = default;
+
+  // Copy operators.
+  CopyablePtr(const CopyablePtr& other) : ptr_(new T(*other.ptr_)) {}
+  CopyablePtr& operator=(const CopyablePtr& other) {
+    *ptr_ = *other.ptr_;
+    return *this;
+  }
+
+  // Move operators.
+  CopyablePtr(CopyablePtr&& other) noexcept : ptr_(std::move(other.ptr_)) {
+    other.ptr_.reset(new T());
+  }
+
+  CopyablePtr& operator=(CopyablePtr&& other) {
+    ptr_ = std::move(other.ptr_);
+    other.ptr_.reset(new T());
+    return *this;
+  }
+
+  T* get() { return ptr_.get(); }
+  const T* get() const { return ptr_.get(); }
+
+  T* operator->() { return ptr_.get(); }
+  const T* operator->() const { return ptr_.get(); }
+
+  T& operator*() { return *ptr_; }
+  const T& operator*() const { return *ptr_; }
+
+  friend bool operator==(const CopyablePtr& lhs, const CopyablePtr& rhs) {
+    return *lhs == *rhs;
+  }
+
+  friend bool operator!=(const CopyablePtr& lhs, const CopyablePtr& rhs) {
+    // In theory the underlying type might have a special operator!=
+    // implementation which is not just !(x == y). Respect that.
+    return *lhs != *rhs;
+  }
+
+ private:
+  std::unique_ptr<T> ptr_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_COPYABLE_PTR_H_
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum DataSourceConfig_SessionInitiator : int {
+  DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED = 0,
+  DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM = 1,
+};
+
+class PERFETTO_EXPORT_COMPONENT DataSourceConfig : public ::protozero::CppMessageObj {
+ public:
+  using SessionInitiator = DataSourceConfig_SessionInitiator;
+  static constexpr auto SESSION_INITIATOR_UNSPECIFIED = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED;
+  static constexpr auto SESSION_INITIATOR_TRUSTED_SYSTEM = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM;
+  static constexpr auto SessionInitiator_MIN = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_UNSPECIFIED;
+  static constexpr auto SessionInitiator_MAX = DataSourceConfig_SessionInitiator_SESSION_INITIATOR_TRUSTED_SYSTEM;
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kTargetBufferFieldNumber = 2,
+    kTraceDurationMsFieldNumber = 3,
+    kPreferSuspendClockForDurationFieldNumber = 122,
+    kStopTimeoutMsFieldNumber = 7,
+    kEnableExtraGuardrailsFieldNumber = 6,
+    kSessionInitiatorFieldNumber = 8,
+    kTracingSessionIdFieldNumber = 4,
+    kFtraceConfigFieldNumber = 100,
+    kInodeFileConfigFieldNumber = 102,
+    kProcessStatsConfigFieldNumber = 103,
+    kSysStatsConfigFieldNumber = 104,
+    kHeapprofdConfigFieldNumber = 105,
+    kJavaHprofConfigFieldNumber = 110,
+    kAndroidPowerConfigFieldNumber = 106,
+    kAndroidLogConfigFieldNumber = 107,
+    kGpuCounterConfigFieldNumber = 108,
+    kAndroidGameInterventionListConfigFieldNumber = 116,
+    kPackagesListConfigFieldNumber = 109,
+    kPerfEventConfigFieldNumber = 111,
+    kVulkanMemoryConfigFieldNumber = 112,
+    kTrackEventConfigFieldNumber = 113,
+    kAndroidPolledStateConfigFieldNumber = 114,
+    kAndroidSystemPropertyConfigFieldNumber = 118,
+    kStatsdTracingConfigFieldNumber = 117,
+    kSystemInfoConfigFieldNumber = 119,
+    kChromeConfigFieldNumber = 101,
+    kInterceptorConfigFieldNumber = 115,
+    kNetworkPacketTraceConfigFieldNumber = 120,
+    kSurfaceflingerLayersConfigFieldNumber = 121,
+    kSurfaceflingerTransactionsConfigFieldNumber = 123,
+    kAndroidSdkSyspropGuardConfigFieldNumber = 124,
+    kEtwConfigFieldNumber = 125,
+    kLegacyConfigFieldNumber = 1000,
+    kForTestingFieldNumber = 1001,
+  };
+
+  DataSourceConfig();
+  ~DataSourceConfig() override;
+  DataSourceConfig(DataSourceConfig&&) noexcept;
+  DataSourceConfig& operator=(DataSourceConfig&&);
+  DataSourceConfig(const DataSourceConfig&);
+  DataSourceConfig& operator=(const DataSourceConfig&);
+  bool operator==(const DataSourceConfig&) const;
+  bool operator!=(const DataSourceConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_target_buffer() const { return _has_field_[2]; }
+  uint32_t target_buffer() const { return target_buffer_; }
+  void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(2); }
+
+  bool has_trace_duration_ms() const { return _has_field_[3]; }
+  uint32_t trace_duration_ms() const { return trace_duration_ms_; }
+  void set_trace_duration_ms(uint32_t value) { trace_duration_ms_ = value; _has_field_.set(3); }
+
+  bool has_prefer_suspend_clock_for_duration() const { return _has_field_[122]; }
+  bool prefer_suspend_clock_for_duration() const { return prefer_suspend_clock_for_duration_; }
+  void set_prefer_suspend_clock_for_duration(bool value) { prefer_suspend_clock_for_duration_ = value; _has_field_.set(122); }
+
+  bool has_stop_timeout_ms() const { return _has_field_[7]; }
+  uint32_t stop_timeout_ms() const { return stop_timeout_ms_; }
+  void set_stop_timeout_ms(uint32_t value) { stop_timeout_ms_ = value; _has_field_.set(7); }
+
+  bool has_enable_extra_guardrails() const { return _has_field_[6]; }
+  bool enable_extra_guardrails() const { return enable_extra_guardrails_; }
+  void set_enable_extra_guardrails(bool value) { enable_extra_guardrails_ = value; _has_field_.set(6); }
+
+  bool has_session_initiator() const { return _has_field_[8]; }
+  DataSourceConfig_SessionInitiator session_initiator() const { return session_initiator_; }
+  void set_session_initiator(DataSourceConfig_SessionInitiator value) { session_initiator_ = value; _has_field_.set(8); }
+
+  bool has_tracing_session_id() const { return _has_field_[4]; }
+  uint64_t tracing_session_id() const { return tracing_session_id_; }
+  void set_tracing_session_id(uint64_t value) { tracing_session_id_ = value; _has_field_.set(4); }
+
+  const std::string& ftrace_config_raw() const { return ftrace_config_; }
+  void set_ftrace_config_raw(const std::string& raw) { ftrace_config_ = raw; _has_field_.set(100); }
+
+  const std::string& inode_file_config_raw() const { return inode_file_config_; }
+  void set_inode_file_config_raw(const std::string& raw) { inode_file_config_ = raw; _has_field_.set(102); }
+
+  const std::string& process_stats_config_raw() const { return process_stats_config_; }
+  void set_process_stats_config_raw(const std::string& raw) { process_stats_config_ = raw; _has_field_.set(103); }
+
+  const std::string& sys_stats_config_raw() const { return sys_stats_config_; }
+  void set_sys_stats_config_raw(const std::string& raw) { sys_stats_config_ = raw; _has_field_.set(104); }
+
+  const std::string& heapprofd_config_raw() const { return heapprofd_config_; }
+  void set_heapprofd_config_raw(const std::string& raw) { heapprofd_config_ = raw; _has_field_.set(105); }
+
+  const std::string& java_hprof_config_raw() const { return java_hprof_config_; }
+  void set_java_hprof_config_raw(const std::string& raw) { java_hprof_config_ = raw; _has_field_.set(110); }
+
+  const std::string& android_power_config_raw() const { return android_power_config_; }
+  void set_android_power_config_raw(const std::string& raw) { android_power_config_ = raw; _has_field_.set(106); }
+
+  const std::string& android_log_config_raw() const { return android_log_config_; }
+  void set_android_log_config_raw(const std::string& raw) { android_log_config_ = raw; _has_field_.set(107); }
+
+  const std::string& gpu_counter_config_raw() const { return gpu_counter_config_; }
+  void set_gpu_counter_config_raw(const std::string& raw) { gpu_counter_config_ = raw; _has_field_.set(108); }
+
+  const std::string& android_game_intervention_list_config_raw() const { return android_game_intervention_list_config_; }
+  void set_android_game_intervention_list_config_raw(const std::string& raw) { android_game_intervention_list_config_ = raw; _has_field_.set(116); }
+
+  const std::string& packages_list_config_raw() const { return packages_list_config_; }
+  void set_packages_list_config_raw(const std::string& raw) { packages_list_config_ = raw; _has_field_.set(109); }
+
+  const std::string& perf_event_config_raw() const { return perf_event_config_; }
+  void set_perf_event_config_raw(const std::string& raw) { perf_event_config_ = raw; _has_field_.set(111); }
+
+  const std::string& vulkan_memory_config_raw() const { return vulkan_memory_config_; }
+  void set_vulkan_memory_config_raw(const std::string& raw) { vulkan_memory_config_ = raw; _has_field_.set(112); }
+
+  const std::string& track_event_config_raw() const { return track_event_config_; }
+  void set_track_event_config_raw(const std::string& raw) { track_event_config_ = raw; _has_field_.set(113); }
+
+  const std::string& android_polled_state_config_raw() const { return android_polled_state_config_; }
+  void set_android_polled_state_config_raw(const std::string& raw) { android_polled_state_config_ = raw; _has_field_.set(114); }
+
+  const std::string& android_system_property_config_raw() const { return android_system_property_config_; }
+  void set_android_system_property_config_raw(const std::string& raw) { android_system_property_config_ = raw; _has_field_.set(118); }
+
+  const std::string& statsd_tracing_config_raw() const { return statsd_tracing_config_; }
+  void set_statsd_tracing_config_raw(const std::string& raw) { statsd_tracing_config_ = raw; _has_field_.set(117); }
+
+  bool has_system_info_config() const { return _has_field_[119]; }
+  const SystemInfoConfig& system_info_config() const { return *system_info_config_; }
+  SystemInfoConfig* mutable_system_info_config() { _has_field_.set(119); return system_info_config_.get(); }
+
+  bool has_chrome_config() const { return _has_field_[101]; }
+  const ChromeConfig& chrome_config() const { return *chrome_config_; }
+  ChromeConfig* mutable_chrome_config() { _has_field_.set(101); return chrome_config_.get(); }
+
+  bool has_interceptor_config() const { return _has_field_[115]; }
+  const InterceptorConfig& interceptor_config() const { return *interceptor_config_; }
+  InterceptorConfig* mutable_interceptor_config() { _has_field_.set(115); return interceptor_config_.get(); }
+
+  const std::string& network_packet_trace_config_raw() const { return network_packet_trace_config_; }
+  void set_network_packet_trace_config_raw(const std::string& raw) { network_packet_trace_config_ = raw; _has_field_.set(120); }
+
+  const std::string& surfaceflinger_layers_config_raw() const { return surfaceflinger_layers_config_; }
+  void set_surfaceflinger_layers_config_raw(const std::string& raw) { surfaceflinger_layers_config_ = raw; _has_field_.set(121); }
+
+  const std::string& surfaceflinger_transactions_config_raw() const { return surfaceflinger_transactions_config_; }
+  void set_surfaceflinger_transactions_config_raw(const std::string& raw) { surfaceflinger_transactions_config_ = raw; _has_field_.set(123); }
+
+  const std::string& android_sdk_sysprop_guard_config_raw() const { return android_sdk_sysprop_guard_config_; }
+  void set_android_sdk_sysprop_guard_config_raw(const std::string& raw) { android_sdk_sysprop_guard_config_ = raw; _has_field_.set(124); }
+
+  const std::string& etw_config_raw() const { return etw_config_; }
+  void set_etw_config_raw(const std::string& raw) { etw_config_ = raw; _has_field_.set(125); }
+
+  bool has_legacy_config() const { return _has_field_[1000]; }
+  const std::string& legacy_config() const { return legacy_config_; }
+  void set_legacy_config(const std::string& value) { legacy_config_ = value; _has_field_.set(1000); }
+
+  bool has_for_testing() const { return _has_field_[1001]; }
+  const TestConfig& for_testing() const { return *for_testing_; }
+  TestConfig* mutable_for_testing() { _has_field_.set(1001); return for_testing_.get(); }
+
+ private:
+  std::string name_{};
+  uint32_t target_buffer_{};
+  uint32_t trace_duration_ms_{};
+  bool prefer_suspend_clock_for_duration_{};
+  uint32_t stop_timeout_ms_{};
+  bool enable_extra_guardrails_{};
+  DataSourceConfig_SessionInitiator session_initiator_{};
+  uint64_t tracing_session_id_{};
+  std::string ftrace_config_;  // [lazy=true]
+  std::string inode_file_config_;  // [lazy=true]
+  std::string process_stats_config_;  // [lazy=true]
+  std::string sys_stats_config_;  // [lazy=true]
+  std::string heapprofd_config_;  // [lazy=true]
+  std::string java_hprof_config_;  // [lazy=true]
+  std::string android_power_config_;  // [lazy=true]
+  std::string android_log_config_;  // [lazy=true]
+  std::string gpu_counter_config_;  // [lazy=true]
+  std::string android_game_intervention_list_config_;  // [lazy=true]
+  std::string packages_list_config_;  // [lazy=true]
+  std::string perf_event_config_;  // [lazy=true]
+  std::string vulkan_memory_config_;  // [lazy=true]
+  std::string track_event_config_;  // [lazy=true]
+  std::string android_polled_state_config_;  // [lazy=true]
+  std::string android_system_property_config_;  // [lazy=true]
+  std::string statsd_tracing_config_;  // [lazy=true]
+  ::protozero::CopyablePtr<SystemInfoConfig> system_info_config_;
+  ::protozero::CopyablePtr<ChromeConfig> chrome_config_;
+  ::protozero::CopyablePtr<InterceptorConfig> interceptor_config_;
+  std::string network_packet_trace_config_;  // [lazy=true]
+  std::string surfaceflinger_layers_config_;  // [lazy=true]
+  std::string surfaceflinger_transactions_config_;  // [lazy=true]
+  std::string android_sdk_sysprop_guard_config_;  // [lazy=true]
+  std::string etw_config_;  // [lazy=true]
+  std::string legacy_config_{};
+  ::protozero::CopyablePtr<TestConfig> for_testing_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<1002> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_CPP_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_CONFIG_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_CONFIG_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_CONFIG_H_
+// gen_amalgamated begin header: include/perfetto/tracing/trace_writer_base.h
+// gen_amalgamated begin header: include/perfetto/protozero/message_handle.h
+// gen_amalgamated begin header: include/perfetto/protozero/message.h
+// gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_writer.h
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_WRITER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_WRITER_H_
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
+
+namespace protozero {
+
+// This class deals with the following problem: append-only proto messages want
+// to write a stream of bytes, without caring about the implementation of the
+// underlying buffer (which concretely will be either the trace ring buffer
+// or a heap-allocated buffer). The main deal is: proto messages don't know in
+// advance what their size will be.
+// Due to the tracing buffer being split into fixed-size chunks, on some
+// occasions, these writes need to be spread over two (or more) non-contiguous
+// chunks of memory. Similarly, when the buffer is backed by the heap, we want
+// to avoid realloc() calls, as they might cause a full copy of the contents
+// of the buffer.
+// The purpose of this class is to abstract away the non-contiguous write logic.
+// This class knows how to deal with writes as long as they fall in the same
+// ContiguousMemoryRange and defers the chunk-chaining logic to the Delegate.
+class PERFETTO_EXPORT_COMPONENT ScatteredStreamWriter {
+ public:
+  class PERFETTO_EXPORT_COMPONENT Delegate {
+   public:
+    static constexpr size_t kPatchSize = 4;
+    virtual ~Delegate();
+
+    // Returns a new chunk for writing.
+    virtual ContiguousMemoryRange GetNewBuffer() = 0;
+
+    // Signals the delegate that the location pointed by `to_patch` (which must
+    // be in the last chunk returned by GetNewBuffer()), kPatchSize long, needs
+    // to be updated later (after potentially multiple GetNewBuffer calls).
+    //
+    // The caller must write to the returned location later. If the returned
+    // pointer is nullptr, the caller should not write anything.
+    //
+    // The implementation considers the patch ready to apply when the caller
+    // writes the first byte a value that's different than 0 (the
+    // implementation periodically checks for this).
+    virtual uint8_t* AnnotatePatch(uint8_t* patch_addr);
+  };
+
+  explicit ScatteredStreamWriter(Delegate* delegate);
+  ~ScatteredStreamWriter();
+
+  inline void WriteByte(uint8_t value) {
+    if (write_ptr_ >= cur_range_.end)
+      Extend();
+    *write_ptr_++ = value;
+  }
+
+  // Assumes that the caller checked that there is enough headroom.
+  // TODO(primiano): perf optimization, this is a tracing hot path. The
+  // compiler can make strong optimization on std::copy if the size arg is a
+  // constexpr. Make a templated variant of this for fixed-size writes.
+  // TODO(primiano): restrict / noalias might also help.
+  inline void WriteBytesUnsafe(const uint8_t* src, size_t size) {
+    uint8_t* const end = write_ptr_ + size;
+    assert(end <= cur_range_.end);
+    std::copy(src, src + size, write_ptr_);
+    write_ptr_ = end;
+  }
+
+  inline void WriteBytes(const uint8_t* src,
+                         size_t size) PERFETTO_NO_SANITIZE_UNDEFINED {
+    // If the stream writer hasn't been initialized, constructing the end
+    // pointer below invokes undefined behavior because `write_ptr_` is null.
+    // Since this function is on the hot path, we suppress the warning instead
+    // of adding a conditional branch.
+    uint8_t* const end = write_ptr_ + size;
+    if (PERFETTO_LIKELY(end <= cur_range_.end))
+      return WriteBytesUnsafe(src, size);
+    WriteBytesSlowPath(src, size);
+  }
+
+  void WriteBytesSlowPath(const uint8_t* src, size_t size);
+
+  // Reserves a fixed amount of bytes to be backfilled later. The reserved range
+  // is guaranteed to be contiguous and not span across chunks. |size| has to be
+  // <= than the size of a new buffer returned by the Delegate::GetNewBuffer().
+  uint8_t* ReserveBytes(size_t size);
+
+  // Fast (but unsafe) version of the above. The caller must have previously
+  // checked that there are at least |size| contiguous bytes available.
+  // Returns only the start pointer of the reservation.
+  uint8_t* ReserveBytesUnsafe(size_t size) {
+    uint8_t* begin = write_ptr_;
+    write_ptr_ += size;
+    assert(write_ptr_ <= cur_range_.end);
+    return begin;
+  }
+
+  // Shifts the previously written `size` bytes backwards in memory by `offset`
+  // bytes, moving the write pointer back accordingly. The shifted result must
+  // still be fully contained by the current range.
+  void Rewind(size_t size, size_t offset) {
+    uint8_t* src = write_ptr_ - size;
+    uint8_t* dst = src - offset;
+    PERFETTO_DCHECK(src >= cur_range_.begin);
+    PERFETTO_DCHECK(src + size <= cur_range_.end);
+    PERFETTO_DCHECK(dst >= cur_range_.begin);
+    PERFETTO_DCHECK(dst + size <= cur_range_.end);
+    memmove(dst, src, size);
+    write_ptr_ -= offset;
+  }
+
+  // Resets the buffer boundaries and the write pointer to the given |range|.
+  // Subsequent WriteByte(s) will write into |range|.
+  void Reset(ContiguousMemoryRange range);
+
+  // Commits the current chunk and gets a new chunk from the delegate.
+  void Extend();
+
+  // Number of contiguous free bytes in |cur_range_| that can be written without
+  // requesting a new buffer.
+  size_t bytes_available() const {
+    return static_cast<size_t>(cur_range_.end - write_ptr_);
+  }
+
+  ContiguousMemoryRange cur_range() const { return cur_range_; }
+
+  uint8_t* write_ptr() const { return write_ptr_; }
+
+  void set_write_ptr(uint8_t* write_ptr) {
+    assert(cur_range_.begin <= write_ptr && write_ptr <= cur_range_.end);
+    write_ptr_ = write_ptr;
+  }
+
+  uint64_t written() const {
+    return written_previously_ +
+           static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
+  }
+
+  uint64_t written_previously() const { return written_previously_; }
+
+  uint8_t* AnnotatePatch(uint8_t* patch_addr) {
+    return delegate_->AnnotatePatch(patch_addr);
+  }
+
+ private:
+  ScatteredStreamWriter(const ScatteredStreamWriter&) = delete;
+  ScatteredStreamWriter& operator=(const ScatteredStreamWriter&) = delete;
+
+  Delegate* const delegate_;
+  ContiguousMemoryRange cur_range_;
+  uint8_t* write_ptr_;
+  uint64_t written_previously_ = 0;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_WRITER_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_MESSAGE_H_
+#define INCLUDE_PERFETTO_PROTOZERO_MESSAGE_H_
+
+#include <assert.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace perfetto {
+namespace shm_fuzz {
+class FakeProducer;
+}  // namespace shm_fuzz
+}  // namespace perfetto
+
+namespace protozero {
+
+class MessageArena;
+class MessageHandleBase;
+
+// Base class extended by the proto C++ stubs generated by the ProtoZero
+// compiler. This class provides the minimal runtime required to support
+// append-only operations and is designed for performance. None of the methods
+// require any dynamic memory allocation, unless more than 16 nested messages
+// are created via BeginNestedMessage() calls.
+class PERFETTO_EXPORT_COMPONENT Message {
+ public:
+  friend class MessageHandleBase;
+
+  // The ctor is deliberately a no-op to avoid forwarding args from all
+  // subclasses. The real initialization is performed by Reset().
+  // Nested messages are allocated via placement new by MessageArena and
+  // implictly destroyed when the RootMessage's arena goes away. This is
+  // fine as long as all the fields are PODs, which is checked by the
+  // static_assert()s in the Reset() method.
+  Message() = default;
+
+  // Clears up the state, allowing the message to be reused as a fresh one.
+  void Reset(ScatteredStreamWriter*, MessageArena*);
+
+  // Commits all the changes to the buffer (backfills the size field of this and
+  // all nested messages) and seals the message. Returns the size of the message
+  // (and all nested sub-messages), without taking into account any chunking.
+  // Finalize is idempotent and can be called several times w/o side effects.
+  // Short messages may be compacted in memory into the size field, since their
+  // size can be represented with fewer than
+  // proto_utils::kMessageLengthFieldSize bytes.
+  uint32_t Finalize();
+
+  // Optional. If is_valid() == true, the corresponding memory region (its
+  // length == proto_utils::kMessageLengthFieldSize) is backfilled with the size
+  // of this message. This is the mechanism used by messages to backfill their
+  // corresponding size field in the parent message. In most cases this is only
+  // used for nested messages and the ScatteredStreamWriter::Delegate (e.g.
+  // TraceWriterImpl), takes case of the outer message.
+  uint8_t* size_field() const { return size_field_; }
+  void set_size_field(uint8_t* size_field) { size_field_ = size_field; }
+
+  Message* nested_message() { return nested_message_; }
+
+  bool is_finalized() const {
+    return message_state_ != MessageState::kNotFinalized;
+  }
+
+#if PERFETTO_DCHECK_IS_ON()
+  void set_handle(MessageHandleBase* handle) { handle_ = handle; }
+#endif
+
+  // Proto types: uint64, uint32, int64, int32, bool, enum.
+  template <typename T>
+  void AppendVarInt(uint32_t field_id, T value) {
+    if (nested_message_)
+      EndNestedMessage();
+
+    uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
+    uint8_t* pos = buffer;
+
+    pos = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), pos);
+    // WriteVarInt encodes signed values in two's complement form.
+    pos = proto_utils::WriteVarInt(value, pos);
+    WriteToStream(buffer, pos);
+  }
+
+  // Proto types: sint64, sint32.
+  template <typename T>
+  void AppendSignedVarInt(uint32_t field_id, T value) {
+    AppendVarInt(field_id, proto_utils::ZigZagEncode(value));
+  }
+
+  // Proto types: bool, enum (small).
+  // Faster version of AppendVarInt for tiny numbers.
+  void AppendTinyVarInt(uint32_t field_id, int32_t value) {
+    PERFETTO_DCHECK(0 <= value && value < 0x80);
+    if (nested_message_)
+      EndNestedMessage();
+
+    uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
+    uint8_t* pos = buffer;
+    // MakeTagVarInt gets super optimized here for constexpr.
+    pos = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), pos);
+    *pos++ = static_cast<uint8_t>(value);
+    WriteToStream(buffer, pos);
+  }
+
+  // Proto types: fixed64, sfixed64, fixed32, sfixed32, double, float.
+  template <typename T>
+  void AppendFixed(uint32_t field_id, T value) {
+    if (nested_message_)
+      EndNestedMessage();
+
+    uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
+    uint8_t* pos = buffer;
+
+    pos = proto_utils::WriteVarInt(proto_utils::MakeTagFixed<T>(field_id), pos);
+    memcpy(pos, &value, sizeof(T));
+    pos += sizeof(T);
+    // TODO: Optimize memcpy performance, see http://crbug.com/624311 .
+    WriteToStream(buffer, pos);
+  }
+
+  void AppendString(uint32_t field_id, const char* str);
+
+  void AppendString(uint32_t field_id, const std::string& str) {
+    AppendBytes(field_id, str.data(), str.size());
+  }
+
+  void AppendBytes(uint32_t field_id, const void* value, size_t size);
+
+  // Append raw bytes for a field, using the supplied |ranges| to
+  // copy from |num_ranges| individual buffers.
+  size_t AppendScatteredBytes(uint32_t field_id,
+                              ContiguousMemoryRange* ranges,
+                              size_t num_ranges);
+
+  // Begins a nested message. The returned object is owned by the MessageArena
+  // of the root message. The nested message ends either when Finalize() is
+  // called or when any other Append* method is called in the parent class.
+  // The template argument T is supposed to be a stub class auto generated from
+  // a .proto, hence a subclass of Message.
+  template <class T>
+  T* BeginNestedMessage(uint32_t field_id) {
+    // This is to prevent subclasses (which should be autogenerated, though), to
+    // introduce extra state fields (which wouldn't be initialized by Reset()).
+    static_assert(std::is_base_of<Message, T>::value,
+                  "T must be a subclass of Message");
+    static_assert(sizeof(T) == sizeof(Message),
+                  "Message subclasses cannot introduce extra state.");
+    return static_cast<T*>(BeginNestedMessageInternal(field_id));
+  }
+
+  // Gives read-only access to the underlying stream_writer. This is used only
+  // by few internals to query the state of the underlying buffer. It is almost
+  // always a bad idea to poke at the stream_writer() internals.
+  const ScatteredStreamWriter* stream_writer() const { return stream_writer_; }
+
+  // Appends some raw bytes to the message. The use-case for this is preserving
+  // unknown fields in the decode -> re-encode path of xxx.gen.cc classes
+  // generated by the cppgen_plugin.cc.
+  // The caller needs to guarantee that the appended data is properly
+  // proto-encoded and each field has a proto preamble.
+  void AppendRawProtoBytes(const void* data, size_t size) {
+    if (nested_message_)
+      EndNestedMessage();
+    const uint8_t* src = reinterpret_cast<const uint8_t*>(data);
+    WriteToStream(src, src + size);
+  }
+
+ private:
+  Message(const Message&) = delete;
+  Message& operator=(const Message&) = delete;
+
+  Message* BeginNestedMessageInternal(uint32_t field_id);
+
+  // Called by Finalize and Append* methods.
+  void EndNestedMessage();
+
+  void WriteToStream(const uint8_t* src_begin, const uint8_t* src_end) {
+    PERFETTO_DCHECK(!is_finalized());
+    PERFETTO_DCHECK(src_begin <= src_end);
+    const uint32_t size = static_cast<uint32_t>(src_end - src_begin);
+    stream_writer_->WriteBytes(src_begin, size);
+    size_ += size;
+  }
+
+  // Only POD fields are allowed. This class's dtor is never called.
+  // See the comment on the static_assert in the corresponding .cc file.
+
+  // The stream writer interface used for the serialization.
+  ScatteredStreamWriter* stream_writer_;
+
+  // The storage used to allocate nested Message objects.
+  // This is owned by RootMessage<T>.
+  MessageArena* arena_;
+
+  // Pointer to the last child message created through BeginNestedMessage(), if
+  // any, nullptr otherwise. There is no need to keep track of more than one
+  // message per nesting level as the proto-zero API contract mandates that
+  // nested fields can be filled only in a stacked fashion. In other words,
+  // nested messages are finalized and sealed when any other field is set in the
+  // parent message (or the parent message itself is finalized) and cannot be
+  // accessed anymore afterwards.
+  Message* nested_message_;
+
+  // [optional] Pointer to a non-aligned pre-reserved var-int slot of
+  // kMessageLengthFieldSize bytes. When set, the Finalize() method will write
+  // the size of proto-encoded message in the pointed memory region.
+  uint8_t* size_field_;
+
+  // Keeps track of the size of the current message.
+  uint32_t size_;
+
+  enum class MessageState : uint8_t {
+    // Message is still being written to.
+    kNotFinalized,
+    // Finalized, no more changes to the message are allowed. This is to DCHECK
+    // attempts of writing to a message which has been Finalize()-d.
+    kFinalized,
+    // Finalized, and additionally the message data has been partially or fully
+    // compacted into the last 3 bytes of `size_field_`. See the comment in
+    // Finalize().
+    kFinalizedWithCompaction,
+  };
+
+  MessageState message_state_;
+
+#if PERFETTO_DCHECK_IS_ON()
+  // Current generation of message. Incremented on Reset.
+  // Used to detect stale handles.
+  uint32_t generation_;
+
+  MessageHandleBase* handle_;
+#endif
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_MESSAGE_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_H_
+#define INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_H_
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace protozero {
+
+class Message;
+
+// MessageHandle allows to decouple the lifetime of a proto message
+// from the underlying storage. It gives the following guarantees:
+// - The underlying message is finalized (if still alive) if the handle goes
+//   out of scope.
+// - In Debug / DCHECK_ALWAYS_ON builds, the handle becomes null once the
+//   message is finalized. This is to enforce the append-only API. For instance
+//   when adding two repeated messages, the addition of the 2nd one forces
+//   the finalization of the first.
+// Think about this as a WeakPtr<Message> which calls
+// Message::Finalize() when going out of scope.
+
+class PERFETTO_EXPORT_COMPONENT MessageHandleBase {
+ public:
+  ~MessageHandleBase() {
+    if (message_) {
+#if PERFETTO_DCHECK_IS_ON()
+      PERFETTO_DCHECK(generation_ == message_->generation_);
+#endif
+      FinalizeMessage();
+    }
+  }
+
+  // Move-only type.
+  MessageHandleBase(MessageHandleBase&& other) noexcept {
+    Move(std::move(other));
+  }
+
+  MessageHandleBase& operator=(MessageHandleBase&& other) noexcept {
+    // If the current handle was pointing to a message and is being reset to a
+    // new one, finalize the old message. However, if the other message is the
+    // same as the one we point to, don't finalize.
+    if (message_ && message_ != other.message_)
+      FinalizeMessage();
+    Move(std::move(other));
+    return *this;
+  }
+
+  explicit operator bool() const {
+#if PERFETTO_DCHECK_IS_ON()
+    PERFETTO_DCHECK(!message_ || generation_ == message_->generation_);
+#endif
+    return !!message_;
+  }
+
+  // Returns a (non-owned, it should not be deleted) pointer to the
+  // ScatteredStreamWriter used to write the message data. The Message becomes
+  // unusable after this point.
+  //
+  // The caller can now write directly, without using protozero::Message.
+  ScatteredStreamWriter* TakeStreamWriter() {
+    ScatteredStreamWriter* stream_writer = message_->stream_writer_;
+#if PERFETTO_DCHECK_IS_ON()
+    message_->set_handle(nullptr);
+#endif
+    message_ = nullptr;
+    return stream_writer;
+  }
+
+ protected:
+  explicit MessageHandleBase(Message* message = nullptr) : message_(message) {
+#if PERFETTO_DCHECK_IS_ON()
+    generation_ = message_ ? message->generation_ : 0;
+    if (message_)
+      message_->set_handle(this);
+#endif
+  }
+
+  Message* operator->() const {
+#if PERFETTO_DCHECK_IS_ON()
+    PERFETTO_DCHECK(!message_ || generation_ == message_->generation_);
+#endif
+    return message_;
+  }
+  Message& operator*() const { return *(operator->()); }
+
+ private:
+  friend class Message;
+  MessageHandleBase(const MessageHandleBase&) = delete;
+  MessageHandleBase& operator=(const MessageHandleBase&) = delete;
+
+  void reset_message() {
+    // This is called by Message::Finalize().
+    PERFETTO_DCHECK(message_->is_finalized());
+    message_ = nullptr;
+  }
+
+  void Move(MessageHandleBase&& other) {
+    message_ = other.message_;
+    other.message_ = nullptr;
+#if PERFETTO_DCHECK_IS_ON()
+    if (message_) {
+      generation_ = message_->generation_;
+      message_->set_handle(this);
+    }
+#endif
+  }
+
+  void FinalizeMessage() { message_->Finalize(); }
+
+  Message* message_;
+#if PERFETTO_DCHECK_IS_ON()
+  uint32_t generation_;
+#endif
+};
+
+template <typename T>
+class MessageHandle : public MessageHandleBase {
+ public:
+  MessageHandle() : MessageHandle(nullptr) {}
+  explicit MessageHandle(T* message) : MessageHandleBase(message) {}
+
+  explicit operator bool() const { return MessageHandleBase::operator bool(); }
+
+  T& operator*() const {
+    return static_cast<T&>(MessageHandleBase::operator*());
+  }
+
+  T* operator->() const {
+    return static_cast<T*>(MessageHandleBase::operator->());
+  }
+
+  T* get() const { return static_cast<T*>(MessageHandleBase::operator->()); }
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_MESSAGE_HANDLE_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_H_
+#define INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_H_
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+
+namespace perfetto {
+
+namespace protos {
+namespace pbzero {
+class TracePacket;
+}  // namespace pbzero
+}  // namespace protos
+
+// This is a single-thread write interface that allows to write protobufs
+// directly into the tracing shared buffer without making any copies.
+// The idea is that each data source creates one (or more) TraceWriter for each
+// thread it wants to write from. Each TraceWriter will get its own dedicated
+// chunk and will write into the shared buffer without any locking most of the
+// time.
+
+class TraceWriterBase {
+ public:
+  virtual ~TraceWriterBase();
+
+  // Creates a new trace packet and returns a handle to a protozero Message that
+  // will write to it. The message will be finalized either by calling directly
+  // handle.Finalize() or by letting the handle go out of scope (the message
+  // should be finalized before a new call to NewTracePacket is made). The
+  // returned handle can be std::move()'d but cannot be used after either: (i)
+  // the TraceWriter instance is destroyed, (ii) a subsequence NewTracePacket()
+  // call is made on the same TraceWriter instance.
+  //
+  // The caller can use protozero::MessageHandle::TakeStreamWriter() to write.
+  //
+  // The caller must call ->Finalize() on the returned trace packet (the handle
+  // destructor will take care of that) or explicitly call FinishTracePacket (if
+  // using TakeStreamWriter) before calling any method on the same TraceWriter
+  // instance.
+  //
+  // The returned packet handle is always valid, but note that, when using
+  // BufferExhaustedPolicy::kDrop and the SMB is exhausted, it may be assigned
+  // a garbage chunk and any trace data written into it will be lost. For more
+  // details on buffer size choices: https://perfetto.dev/docs/concepts/buffers.
+  virtual protozero::MessageHandle<protos::pbzero::TracePacket>
+  NewTracePacket() = 0;
+
+  // Tells the TraceWriterBase that the previous packet started with
+  // NewTracePacket() is finished.
+  //
+  // Calling this is optional: the TraceWriterBase can realize that the previous
+  // packet is finished when the next NewTracePacket() is called. It is still
+  // useful, because the next NewTracePacket may not happen for a while.
+  virtual void FinishTracePacket() = 0;
+
+  // Commits the data pending for the current chunk. This can be called
+  // only if the handle returned by NewTracePacket() has been destroyed (i.e. we
+  // cannot Flush() while writing a TracePacket).
+  //
+  // Note: Flush() also happens implicitly when destroying the TraceWriter.
+  //
+  // |callback| is an optional callback. When non-null it will request the
+  // service to ACK the flush and will be invoked after the service has
+  // acknowledged it. The callback might be NEVER INVOKED if the service crashes
+  // or the IPC connection is dropped. The callback should be used only by tests
+  // and best-effort features (logging).
+  virtual void Flush(std::function<void()> callback = {}) = 0;
+
+  // Bytes written since creation. Not reset when new chunks are acquired.
+  virtual uint64_t written() const = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACE_WRITER_BASE_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_INTERNAL_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_INTERNAL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <array>
+#include <atomic>
+#include <functional>
+#include <memory>
+#include <mutex>
+
+// No perfetto headers (other than tracing/api and protozero) should be here.
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+namespace perfetto {
+
+class DataSourceBase;
+class InterceptorBase;
+class TraceWriterBase;
+
+namespace internal {
+
+class TracingTLS;
+
+// This maintains the internal state of a data source instance that is used only
+// to implement the tracing mechanics and is not exposed to the API client.
+// There is one of these object per DataSource instance (up to
+// kMaxDataSourceInstances).
+struct DataSourceState {
+  // This boolean flag determines whether the DataSource::Trace() method should
+  // do something or be a no-op. This flag doesn't give the full guarantee
+  // that tracing data will be visible in the trace, it just makes it so that
+  // the client attemps writing trace data and interacting with the service.
+  // For instance, when a tracing session ends the service will reject data
+  // commits that arrive too late even if the producer hasn't received the stop
+  // IPC message.
+  // This flag is set right before calling OnStart() and cleared right before
+  // calling OnStop(), unless using HandleStopAsynchronously() (see comments
+  // in data_source.h).
+  // Keep this flag as the first field. This allows the compiler to directly
+  // dereference the DataSourceState* pointer in the trace fast-path without
+  // doing extra pointr arithmetic.
+  std::atomic<bool> trace_lambda_enabled{false};
+
+  // The overall TracingMuxerImpl instance id, which gets incremented by
+  // ResetForTesting.
+  uint32_t muxer_id_for_testing = 0;
+
+  // The central buffer id that all TraceWriter(s) created by this data source
+  // must target.
+  BufferId buffer_id = 0;
+
+  // The index within TracingMuxerImpl.backends_. Practically it allows to
+  // lookup the Producer object, and hence the IPC channel, for this data
+  // source.
+  TracingBackendId backend_id = 0;
+
+  // Each backend may connect to the tracing service multiple times if a
+  // disconnection occurs. This counter is used to uniquely identify each
+  // connection so that trace writers don't get reused across connections.
+  uint32_t backend_connection_id = 0;
+
+  // The instance id as assigned by the tracing service. Note that because a
+  // process can be connected to >1 services, this ID is not globally unique but
+  // is only unique within the scope of its backend.
+  // Only the tuple (backend_id, data_source_instance_id) is globally unique.
+  uint64_t data_source_instance_id = 0;
+
+  // Set to a non-0 target buffer reservation ID iff startup tracing is
+  // currently enabled for this data source.
+  std::atomic<uint16_t> startup_target_buffer_reservation{0};
+
+  // If the data source was originally started for startup tracing, this is set
+  // to the startup session's ID.
+  uint64_t startup_session_id = 0;
+
+  // The trace config used by this instance. This is used to de-duplicate
+  // instances for data sources with identical names (e.g., track event).
+  // We store it as a pointer to be able to free memory after the datasource
+  // is stopped.
+  std::unique_ptr<DataSourceConfig> config;
+
+  // If this data source is being intercepted (see Interceptor), this field
+  // contains the non-zero id of a registered interceptor which should receive
+  // trace packets for this session. Note: interceptor id 1 refers to the first
+  // element of TracingMuxerImpl::interceptors_ with successive numbers using
+  // the following slots.
+  uint32_t interceptor_id = 0;
+
+  // This lock is not held to implement Trace() and it's used only if the trace
+  // code wants to access its own data source state.
+  // This is to prevent that accessing the data source on an arbitrary embedder
+  // thread races with the internal IPC thread destroying the data source
+  // because of a end-of-tracing notification from the service.
+  // This lock is also used to protect access to a possible interceptor for this
+  // data source session.
+  std::recursive_mutex lock;
+  std::unique_ptr<DataSourceBase> data_source;
+  std::unique_ptr<InterceptorBase> interceptor;
+};
+
+// This is to allow lazy-initialization and avoid static initializers and
+// at-exit destructors. All the entries are initialized via placement-new when
+// DataSource::Register() is called, see TracingMuxerImpl::RegisterDataSource().
+struct DataSourceStateStorage {
+  alignas(DataSourceState) char storage[sizeof(DataSourceState)]{};
+};
+
+// Per-DataSource-type global state.
+struct DataSourceStaticState {
+  // System-wide unique id of the data source.
+  uint64_t id = 0;
+
+  // Unique index of the data source, assigned at registration time.
+  uint32_t index = kMaxDataSources;
+
+  // A bitmap that tells about the validity of each |instances| entry. When the
+  // i-th bit of the bitmap it's set, instances[i] is valid.
+  std::atomic<uint32_t> valid_instances{};
+  std::array<DataSourceStateStorage, kMaxDataSourceInstances> instances{};
+
+  // Incremented whenever incremental state should be reset for any instance of
+  // this data source.
+  std::atomic<uint32_t> incremental_state_generation{};
+
+  // Can be used with a cached |valid_instances| bitmap.
+  DataSourceState* TryGetCached(uint32_t cached_bitmap, size_t n) {
+    return cached_bitmap & (1 << n)
+               ? reinterpret_cast<DataSourceState*>(&instances[n])
+               : nullptr;
+  }
+
+  DataSourceState* TryGet(size_t n) {
+    return TryGetCached(valid_instances.load(std::memory_order_acquire), n);
+  }
+
+  void CompilerAsserts() {
+    static_assert(sizeof(valid_instances.load()) * 8 >= kMaxDataSourceInstances,
+                  "kMaxDataSourceInstances too high");
+  }
+
+  void ResetForTesting() {
+    id = 0;
+    index = kMaxDataSources;
+    valid_instances.store(0, std::memory_order_release);
+    instances = {};
+    incremental_state_generation.store(0, std::memory_order_release);
+  }
+};
+
+// Per-DataSource-instance thread-local state.
+struct DataSourceInstanceThreadLocalState {
+  void Reset() { *this = DataSourceInstanceThreadLocalState{}; }
+
+  std::unique_ptr<TraceWriterBase> trace_writer;
+  using ObjectWithDeleter = std::unique_ptr<void, void (*)(void*)>;
+  ObjectWithDeleter incremental_state = {nullptr, [](void*) {}};
+  ObjectWithDeleter data_source_custom_tls = {nullptr, [](void*) {}};
+  uint32_t incremental_state_generation = 0;
+  uint32_t muxer_id_for_testing = 0;
+  TracingBackendId backend_id = 0;
+  uint32_t backend_connection_id = 0;
+  BufferId buffer_id = 0;
+  uint64_t data_source_instance_id = 0;
+  bool is_intercepted = false;
+  uint64_t last_empty_packet_position = 0;
+  uint16_t startup_target_buffer_reservation = 0;
+};
+
+// Per-DataSource-type thread-local state.
+struct DataSourceThreadLocalState {
+  DataSourceStaticState* static_state = nullptr;
+
+  // Pointer to the parent tls object that holds us. Used to retrieve the
+  // generation, which is per-global-TLS and not per data-source.
+  TracingTLS* root_tls = nullptr;
+
+  // One entry per each data source instance.
+  std::array<DataSourceInstanceThreadLocalState, kMaxDataSourceInstances>
+      per_instance{};
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_INTERNAL_H_
+// gen_amalgamated begin header: include/perfetto/tracing/locked_handle.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_LOCKED_HANDLE_H_
+#define INCLUDE_PERFETTO_TRACING_LOCKED_HANDLE_H_
+
+#include <mutex>
+
+namespace perfetto {
+
+// This is used for GetDataSourceLocked(), in the (rare) case where the
+// tracing code wants to access the state of its data source from the Trace()
+// method.
+template <typename T>
+class LockedHandle {
+ public:
+  LockedHandle(std::unique_lock<std::recursive_mutex> lock, T* obj)
+      : lock_(std::move(lock)), obj_(obj) {}
+  LockedHandle() = default;  // For the invalid case.
+  LockedHandle(LockedHandle&&) = default;
+  LockedHandle& operator=(LockedHandle&&) = default;
+
+  bool valid() const { return obj_; }
+  explicit operator bool() const { return valid(); }
+
+  T* operator->() {
+    assert(valid());
+    return obj_;
+  }
+
+  T& operator*() { return *(this->operator->()); }
+
+ private:
+  std::unique_lock<std::recursive_mutex> lock_;
+  T* obj_ = nullptr;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_LOCKED_HANDLE_H_
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERCEPTOR_H_
+#define INCLUDE_PERFETTO_TRACING_INTERCEPTOR_H_
+
+// An interceptor is used to redirect trace packets written by a data source
+// into a custom backend instead of the normal Perfetto tracing service. For
+// example, the console interceptor prints all trace packets to the console as
+// they are generated. Another potential use is exporting trace data to another
+// tracing service such as Android ATrace or Windows ETW.
+//
+// An interceptor is defined by subclassing the perfetto::Interceptor template:
+//
+// class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
+//  public:
+//   ~MyInterceptor() override = default;
+//
+//   // This function is called for each intercepted trace packet. |context|
+//   // contains information about the trace packet as well as other state
+//   // tracked by the interceptor (e.g., see ThreadLocalState).
+//   //
+//   // Intercepted trace data is provided in the form of serialized protobuf
+//   // bytes, accessed through the |context.packet_data| field.
+//   //
+//   // Warning: this function can be called on any thread at any time. See
+//   // below for how to safely access shared interceptor data from here.
+//   static void OnTracePacket(InterceptorContext context) {
+//     perfetto::protos::pbzero::TracePacket::Decoder packet(
+//         context.packet_data.data, context.packet_data.size);
+//     // ... Write |packet| to the desired destination ...
+//   }
+// };
+//
+// An interceptor should be registered before any tracing sessions are started.
+// Note that the interceptor also needs to be activated through the trace config
+// as shown below.
+//
+//   perfetto::InterceptorDescriptor desc;
+//   desc.set_name("my_interceptor");
+//   MyInterceptor::Register(desc);
+//
+// Finally, an interceptor is enabled through the trace config like this:
+//
+//   perfetto::TraceConfig cfg;
+//   auto* ds_cfg = cfg.add_data_sources()->mutable_config();
+//   ds_cfg->set_name("data_source_to_intercept");   // e.g. "track_event"
+//   ds_cfg->mutable_interceptor_config()->set_name("my_interceptor");
+//
+// Once an interceptor is enabled, all data from the affected data sources is
+// sent to the interceptor instead of the main tracing buffer.
+//
+// Interceptor state
+// =================
+//
+// Besides the serialized trace packet data, the |OnTracePacket| interceptor
+// function can access three other types of state:
+//
+// 1. Global state: this is no different from a normal static function, but care
+//    must be taken because |OnTracePacket| can be called concurrently on any
+//    thread at any time.
+//
+// 2. Per-data source instance state: since the interceptor class is
+//    automatically instantiated for each intercepted data source, its fields
+//    can be used to store per-instance data such as the trace config. This data
+//    can be maintained through the OnSetup/OnStart/OnStop callbacks:
+//
+//    class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
+//     public:
+//      void OnSetup(const SetupArgs& args) override {
+//        enable_foo_ = args.config.interceptor_config().enable_foo();
+//      }
+//
+//      bool enable_foo_{};
+//    };
+//
+//    In the interceptor function this data must be accessed through a scoped
+//    lock for safety:
+//
+//    class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
+//      ...
+//      static void OnTracePacket(InterceptorContext context) {
+//        auto my_interceptor = context.GetInterceptorLocked();
+//        if (my_interceptor) {
+//           // Access fields of MyInterceptor here.
+//           if (my_interceptor->enable_foo_) { ... }
+//        }
+//        ...
+//      }
+//    };
+//
+//    Since accessing this data involves holding a lock, it should be done
+//    sparingly.
+//
+// 3. Per-thread/TraceWriter state: many data sources use interning to avoid
+//    repeating common data in the trace. Since the interning dictionaries are
+//    typically kept individually for each TraceWriter sequence (i.e., per
+//    thread), an interceptor can declare a data structure with lifetime
+//    matching the TraceWriter:
+//
+//    class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
+//     public:
+//      struct ThreadLocalState
+//          : public perfetto::InterceptorBase::ThreadLocalState {
+//        ThreadLocalState(ThreadLocalStateArgs&) override = default;
+//        ~ThreadLocalState() override = default;
+//
+//        std::map<size_t, std::string> event_names;
+//      };
+//    };
+//
+//    This per-thread state can then be accessed and maintained in
+//    |OnTracePacket| like this:
+//
+//    class MyInterceptor : public perfetto::Interceptor<MyInterceptor> {
+//      ...
+//      static void OnTracePacket(InterceptorContext context) {
+//        // Updating interned data.
+//        auto& tls = context.GetThreadLocalState();
+//        if (parsed_packet.sequence_flags() & perfetto::protos::pbzero::
+//                TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
+//          tls.event_names.clear();
+//        }
+//        for (const auto& entry : parsed_packet.interned_data().event_names())
+//          tls.event_names[entry.iid()] = entry.name();
+//
+//        // Looking up interned data.
+//        if (parsed_packet.has_track_event()) {
+//          size_t name_iid = parsed_packet.track_event().name_iid();
+//          const std::string& event_name = tls.event_names[name_iid];
+//        }
+//        ...
+//      }
+//    };
+//
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/locked_handle.h"
+
+namespace {
+class MockTracingMuxer;
+}
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class DataSourceConfig;
+class InterceptorDescriptor;
+}  // namespace gen
+}  // namespace protos
+
+using protos::gen::InterceptorDescriptor;
+
+namespace internal {
+class InterceptorTraceWriter;
+class InterceptorTraceWriterTest;
+class TracingMuxer;
+class TracingMuxerFake;
+class TracingMuxerImpl;
+}  // namespace internal
+
+// A virtual base class for interceptors. Users should derive from the templated
+// subclass below instead of this one.
+class PERFETTO_EXPORT_COMPONENT InterceptorBase {
+ public:
+  virtual ~InterceptorBase();
+
+  // A virtual base class for thread-local state needed by the interceptor.
+  // To define your own state, subclass this with the same name in the
+  // interceptor class. A reference to the state can then be looked up through
+  // context.GetThreadLocalState() in the trace packet interceptor function.
+  class PERFETTO_EXPORT_COMPONENT ThreadLocalState {
+   public:
+    virtual ~ThreadLocalState();
+  };
+
+  struct SetupArgs {
+    const DataSourceConfig& config;
+  };
+  struct StartArgs {};
+  struct StopArgs {};
+
+  // Called when an intercepted data source is set up. Both the interceptor's
+  // and the data source's configuration is available in
+  // |SetupArgs|. Called on an internal Perfetto service thread, but not
+  // concurrently.
+  virtual void OnSetup(const SetupArgs&) {}
+
+  // Called when an intercepted data source starts. Called on an internal
+  // Perfetto service thread, but not concurrently.
+  virtual void OnStart(const StartArgs&) {}
+
+  // Called when an intercepted data source stops. Called on an internal
+  // Perfetto service thread, but not concurrently.
+  virtual void OnStop(const StopArgs&) {}
+
+ private:
+  friend class internal::InterceptorTraceWriter;
+  friend class internal::InterceptorTraceWriterTest;
+  friend class internal::TracingMuxer;
+  friend class internal::TracingMuxerFake;
+  friend class internal::TracingMuxerImpl;
+  friend MockTracingMuxer;
+  template <class T>
+  friend class Interceptor;
+
+  // Data passed from DataSource::Trace() into the interceptor.
+  struct TracePacketCallbackArgs {
+    internal::DataSourceStaticState* static_state;
+    uint32_t instance_index;
+    protozero::ConstBytes packet_data;
+    ThreadLocalState* tls;
+  };
+
+  // These callback functions are defined as stateless to avoid accidentally
+  // introducing cross-thread data races.
+  using TLSFactory = std::unique_ptr<ThreadLocalState> (*)(
+      internal::DataSourceStaticState*,
+      uint32_t data_source_instance_index);
+  using TracePacketCallback = void (*)(TracePacketCallbackArgs);
+
+  static void RegisterImpl(
+      const InterceptorDescriptor& descriptor,
+      std::function<std::unique_ptr<InterceptorBase>()> factory,
+      InterceptorBase::TLSFactory tls_factory,
+      InterceptorBase::TracePacketCallback on_trace_packet);
+};
+
+// Templated interceptor instantiation. See above for usage.
+template <class InterceptorType>
+class PERFETTO_EXPORT_COMPONENT Interceptor : public InterceptorBase {
+ public:
+  // A context object provided to the ThreadLocalState constructor. Provides
+  // access to the per-instance interceptor object.
+  class ThreadLocalStateArgs {
+   public:
+    ~ThreadLocalStateArgs() = default;
+
+    ThreadLocalStateArgs(const ThreadLocalStateArgs&) = delete;
+    ThreadLocalStateArgs& operator=(const ThreadLocalStateArgs&) = delete;
+
+    ThreadLocalStateArgs(ThreadLocalStateArgs&&) noexcept = default;
+    ThreadLocalStateArgs& operator=(ThreadLocalStateArgs&&) noexcept = default;
+
+    // Return a locked reference to the interceptor session. The session object
+    // will remain valid as long as the returned handle is in scope.
+    LockedHandle<InterceptorType> GetInterceptorLocked() {
+      auto* internal_state = static_state_->TryGet(data_source_instance_index_);
+      if (!internal_state)
+        return LockedHandle<InterceptorType>();
+      std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
+      return LockedHandle<InterceptorType>(
+          std::move(lock),
+          static_cast<InterceptorType*>(internal_state->interceptor.get()));
+    }
+
+   private:
+    friend class Interceptor<InterceptorType>;
+    friend class InterceptorContext;
+    friend class TracingMuxerImpl;
+
+    ThreadLocalStateArgs(internal::DataSourceStaticState* static_state,
+                         uint32_t data_source_instance_index)
+        : static_state_(static_state),
+          data_source_instance_index_(data_source_instance_index) {}
+
+    internal::DataSourceStaticState* const static_state_;
+    const uint32_t data_source_instance_index_;
+  };
+
+  // A context object provided to each call into |OnTracePacket|. Contains the
+  // intercepted serialized trace packet data.
+  class InterceptorContext {
+   public:
+    InterceptorContext(InterceptorContext&&) noexcept = default;
+    ~InterceptorContext() = default;
+
+    // Return a locked reference to the interceptor session. The session object
+    // will remain valid as long as the returned handle is in scope.
+    LockedHandle<InterceptorType> GetInterceptorLocked() {
+      return tls_args_.GetInterceptorLocked();
+    }
+
+    // Return the thread-local state for this interceptor. See
+    // InterceptorBase::ThreadLocalState.
+    typename InterceptorType::ThreadLocalState& GetThreadLocalState() {
+      return static_cast<typename InterceptorType::ThreadLocalState&>(*tls_);
+    }
+
+    // A buffer containing the serialized TracePacket protocol buffer message.
+    // This memory is only valid during the call to OnTracePacket.
+    protozero::ConstBytes packet_data;
+
+   private:
+    friend class Interceptor<InterceptorType>;
+    InterceptorContext(TracePacketCallbackArgs args)
+        : packet_data(args.packet_data),
+          tls_args_(args.static_state, args.instance_index),
+          tls_(args.tls) {}
+    InterceptorContext(const InterceptorContext&) = delete;
+    InterceptorContext& operator=(const InterceptorContext&) = delete;
+
+    ThreadLocalStateArgs tls_args_;
+    InterceptorBase::ThreadLocalState* const tls_;
+  };
+
+  // Register the interceptor for use in tracing sessions.
+  // The optional |constructor_args| will be passed to the interceptor when it
+  // is constructed.
+  template <class... Args>
+  static void Register(const InterceptorDescriptor& descriptor,
+                       const Args&... constructor_args) {
+    auto factory = [constructor_args...]() {
+      return std::unique_ptr<InterceptorBase>(
+          new InterceptorType(constructor_args...));
+    };
+    auto tls_factory = [](internal::DataSourceStaticState* static_state,
+                          uint32_t data_source_instance_index) {
+      // Don't bother allocating TLS state unless the interceptor is actually
+      // using it.
+      if (std::is_same<typename InterceptorType::ThreadLocalState,
+                       InterceptorBase::ThreadLocalState>::value) {
+        return std::unique_ptr<InterceptorBase::ThreadLocalState>(nullptr);
+      }
+      ThreadLocalStateArgs args(static_state, data_source_instance_index);
+      return std::unique_ptr<InterceptorBase::ThreadLocalState>(
+          new typename InterceptorType::ThreadLocalState(args));
+    };
+    auto on_trace_packet = [](TracePacketCallbackArgs args) {
+      InterceptorType::OnTracePacket(InterceptorContext(std::move(args)));
+    };
+    RegisterImpl(descriptor, std::move(factory), std::move(tls_factory),
+                 std::move(on_trace_packet));
+  }
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERCEPTOR_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event_state_tracker.h
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_event.pbzero.h
+// gen_amalgamated begin header: include/perfetto/protozero/field_writer.h
+/*
+ * 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.
+ */
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
+
+namespace protozero {
+namespace internal {
+
+template <proto_utils::ProtoSchemaType proto_schema_type>
+struct FieldWriter {
+  static_assert(proto_schema_type != proto_utils::ProtoSchemaType::kMessage,
+                "FieldWriter can't be used with nested messages");
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kDouble> {
+  inline static void Append(Message& message, uint32_t field_id, double value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kFloat> {
+  inline static void Append(Message& message, uint32_t field_id, float value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kBool> {
+  inline static void Append(Message& message, uint32_t field_id, bool value) {
+    message.AppendTinyVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kInt32> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int32_t value) {
+    message.AppendVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kInt64> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int64_t value) {
+    message.AppendVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kUint32> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            uint32_t value) {
+    message.AppendVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kUint64> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            uint64_t value) {
+    message.AppendVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kSint32> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int32_t value) {
+    message.AppendSignedVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kSint64> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int64_t value) {
+    message.AppendSignedVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kFixed32> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            uint32_t value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kFixed64> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            uint64_t value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kSfixed32> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int32_t value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kSfixed64> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            int64_t value) {
+    message.AppendFixed(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kEnum> {
+  template <typename EnumType>
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            EnumType value) {
+    message.AppendVarInt(field_id, value);
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kString> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            const char* data,
+                            size_t size) {
+    message.AppendBytes(field_id, data, size);
+  }
+
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            const std::string& value) {
+    message.AppendBytes(field_id, value.data(), value.size());
+  }
+};
+
+template <>
+struct FieldWriter<proto_utils::ProtoSchemaType::kBytes> {
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            const uint8_t* data,
+                            size_t size) {
+    message.AppendBytes(field_id, data, size);
+  }
+
+  inline static void Append(Message& message,
+                            uint32_t field_id,
+                            const std::string& value) {
+    message.AppendBytes(field_id, value.data(), value.size());
+  }
+};
+
+}  // namespace internal
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_FIELD_WRITER_H_
+// gen_amalgamated begin header: include/perfetto/protozero/packed_repeated_fields.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_PACKED_REPEATED_FIELDS_H_
+#define INCLUDE_PERFETTO_PROTOZERO_PACKED_REPEATED_FIELDS_H_
+
+#include <stdint.h>
+
+#include <array>
+#include <memory>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+// This file contains classes used when encoding packed repeated fields.
+// To encode such a field, the caller is first expected to accumulate all of the
+// values in one of the following types (depending on the wire type of the
+// individual elements), defined below:
+// * protozero::PackedVarInt
+// * protozero::PackedFixedSizeInt</*element_type=*/ uint32_t>
+// Then that buffer is passed to the protozero-generated setters as an argument.
+// After calling the setter, the buffer can be destroyed.
+//
+// An example of encoding a packed field:
+//   protozero::HeapBuffered<protozero::Message> msg;
+//   protozero::PackedVarInt buf;
+//   buf.Append(42);
+//   buf.Append(-1);
+//   msg->set_fieldname(buf);
+//   msg.SerializeAsString();
+
+class PackedBufferBase {
+ public:
+  PackedBufferBase() { Reset(); }
+
+  // Copy or move is disabled due to pointers to stack addresses.
+  PackedBufferBase(const PackedBufferBase&) = delete;
+  PackedBufferBase(PackedBufferBase&&) = delete;
+  PackedBufferBase& operator=(const PackedBufferBase&) = delete;
+  PackedBufferBase& operator=(PackedBufferBase&&) = delete;
+
+  void Reset();
+
+  const uint8_t* data() const { return storage_begin_; }
+
+  size_t size() const {
+    return static_cast<size_t>(write_ptr_ - storage_begin_);
+  }
+
+ protected:
+  void GrowIfNeeded() {
+    PERFETTO_DCHECK(write_ptr_ >= storage_begin_ && write_ptr_ <= storage_end_);
+    if (PERFETTO_UNLIKELY(write_ptr_ + kMaxElementSize > storage_end_)) {
+      GrowSlowpath();
+    }
+  }
+
+  void GrowSlowpath();
+
+  // max(uint64_t varint encoding, biggest fixed type (uint64)).
+  static constexpr size_t kMaxElementSize = 10;
+
+  // So sizeof(this) == 8k.
+  static constexpr size_t kOnStackStorageSize = 8192 - 32;
+
+  uint8_t* storage_begin_;
+  uint8_t* storage_end_;
+  uint8_t* write_ptr_;
+  std::unique_ptr<uint8_t[]> heap_buf_;
+  alignas(uint64_t) uint8_t stack_buf_[kOnStackStorageSize];
+};
+
+class PackedVarInt : public PackedBufferBase {
+ public:
+  template <typename T>
+  void Append(T value) {
+    GrowIfNeeded();
+    write_ptr_ = proto_utils::WriteVarInt(value, write_ptr_);
+  }
+};
+
+template <typename T /* e.g. uint32_t for Fixed32 */>
+class PackedFixedSizeInt : public PackedBufferBase {
+ public:
+  void Append(T value) {
+    static_assert(sizeof(T) == 4 || sizeof(T) == 8,
+                  "PackedFixedSizeInt should be used only with 32/64-bit ints");
+    static_assert(sizeof(T) <= kMaxElementSize,
+                  "kMaxElementSize needs to be updated");
+    GrowIfNeeded();
+    PERFETTO_DCHECK(reinterpret_cast<size_t>(write_ptr_) % alignof(T) == 0);
+    memcpy(reinterpret_cast<T*>(write_ptr_), &value, sizeof(T));
+    write_ptr_ += sizeof(T);
+  }
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_PACKED_REPEATED_FIELDS_H_
+// gen_amalgamated begin header: include/perfetto/protozero/proto_decoder.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_PROTO_DECODER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_PROTO_DECODER_H_
+
+#include <stdint.h>
+#include <array>
+#include <memory>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/field.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace protozero {
+
+// A generic protobuf decoder. Doesn't require any knowledge about the proto
+// schema. It tokenizes fields, retrieves their ID and type and exposes
+// accessors to retrieve its values.
+// It does NOT recurse in nested submessages, instead it just computes their
+// boundaries, recursion is left to the caller.
+// This class is designed to be used in perf-sensitive contexts. It does not
+// allocate and does not perform any proto semantic checks (e.g. repeated /
+// required / optional). It's supposedly safe wrt out-of-bounds memory accesses
+// (see proto_decoder_fuzzer.cc).
+// This class serves also as a building block for TypedProtoDecoder, used when
+// the schema is known at compile time.
+class PERFETTO_EXPORT_COMPONENT ProtoDecoder {
+ public:
+  // Creates a ProtoDecoder using the given |buffer| with size |length| bytes.
+  ProtoDecoder(const void* buffer, size_t length)
+      : begin_(reinterpret_cast<const uint8_t*>(buffer)),
+        end_(begin_ + length),
+        read_ptr_(begin_) {}
+  ProtoDecoder(const std::string& str) : ProtoDecoder(str.data(), str.size()) {}
+  ProtoDecoder(const ConstBytes& cb) : ProtoDecoder(cb.data, cb.size) {}
+
+  // Reads the next field from the buffer and advances the read cursor. If a
+  // full field cannot be read, the returned Field will be invalid (i.e.
+  // field.valid() == false).
+  Field ReadField();
+
+  // Finds the first field with the given id. Doesn't affect the read cursor.
+  Field FindField(uint32_t field_id);
+
+  // Resets the read cursor to the start of the buffer.
+  void Reset() { read_ptr_ = begin_; }
+
+  // Resets the read cursor to the given position (must be within the buffer).
+  void Reset(const uint8_t* pos) {
+    PERFETTO_DCHECK(pos >= begin_ && pos < end_);
+    read_ptr_ = pos;
+  }
+
+  // Returns the position of read cursor, relative to the start of the buffer.
+  size_t read_offset() const { return static_cast<size_t>(read_ptr_ - begin_); }
+
+  size_t bytes_left() const {
+    PERFETTO_DCHECK(read_ptr_ <= end_);
+    return static_cast<size_t>(end_ - read_ptr_);
+  }
+
+  const uint8_t* begin() const { return begin_; }
+  const uint8_t* end() const { return end_; }
+
+ protected:
+  const uint8_t* const begin_;
+  const uint8_t* const end_;
+  const uint8_t* read_ptr_ = nullptr;
+};
+
+// An iterator-like class used to iterate through repeated fields. Used by
+// TypedProtoDecoder. The iteration sequence is a bit counter-intuitive due to
+// the fact that fields_[field_id] holds the *last* value of the field, not the
+// first, but the remaining storage holds repeated fields in FIFO order.
+// Assume that we push the 10,11,12 into a repeated field with ID=1.
+//
+// Decoder memory layout:  [  fields storage  ] [ repeated fields storage ]
+// 1st iteration:           10
+// 2nd iteration:           11                   10
+// 3rd iteration:           12                   10 11
+//
+// We start the iteration @ fields_[num_fields], which is the start of the
+// repeated fields storage, proceed until the end and lastly jump @ fields_[id].
+template <typename T>
+class RepeatedFieldIterator {
+ public:
+  RepeatedFieldIterator(uint32_t field_id,
+                        const Field* begin,
+                        const Field* end,
+                        const Field* last)
+      : field_id_(field_id), iter_(begin), end_(end), last_(last) {
+    FindNextMatchingId();
+  }
+
+  // Constructs an invalid iterator.
+  RepeatedFieldIterator()
+      : field_id_(0u), iter_(nullptr), end_(nullptr), last_(nullptr) {}
+
+  explicit operator bool() const { return iter_ != end_; }
+  const Field& field() const { return *iter_; }
+
+  T operator*() const {
+    T val{};
+    iter_->get(&val);
+    return val;
+  }
+  const Field* operator->() const { return iter_; }
+
+  RepeatedFieldIterator& operator++() {
+    PERFETTO_DCHECK(iter_ != end_);
+    if (iter_ == last_) {
+      iter_ = end_;
+      return *this;
+    }
+    ++iter_;
+    FindNextMatchingId();
+    return *this;
+  }
+
+  RepeatedFieldIterator operator++(int) {
+    PERFETTO_DCHECK(iter_ != end_);
+    RepeatedFieldIterator it(*this);
+    ++(*this);
+    return it;
+  }
+
+ private:
+  void FindNextMatchingId() {
+    PERFETTO_DCHECK(iter_ != last_);
+    for (; iter_ != end_; ++iter_) {
+      if (iter_->id() == field_id_)
+        return;
+    }
+    iter_ = last_->valid() ? last_ : end_;
+  }
+
+  uint32_t field_id_;
+
+  // Initially points to the beginning of the repeated field storage, then is
+  // incremented as we call operator++().
+  const Field* iter_;
+
+  // Always points to fields_[size_], i.e. past the end of the storage.
+  const Field* end_;
+
+  // Always points to fields_[field_id].
+  const Field* last_;
+};
+
+// As RepeatedFieldIterator, but allows iterating over a packed repeated field
+// (which will be initially stored as a single length-delimited field).
+// See |GetPackedRepeatedField| for details.
+//
+// Assumes little endianness, and that the input buffers are well formed -
+// containing an exact multiple of encoded elements.
+template <proto_utils::ProtoWireType wire_type, typename CppType>
+class PackedRepeatedFieldIterator {
+ public:
+  PackedRepeatedFieldIterator(const uint8_t* data_begin,
+                              size_t size,
+                              bool* parse_error_ptr)
+      : data_end_(data_begin ? data_begin + size : nullptr),
+        read_ptr_(data_begin),
+        parse_error_(parse_error_ptr) {
+    using proto_utils::ProtoWireType;
+    static_assert(wire_type == ProtoWireType::kVarInt ||
+                      wire_type == ProtoWireType::kFixed32 ||
+                      wire_type == ProtoWireType::kFixed64,
+                  "invalid type");
+
+    PERFETTO_DCHECK(parse_error_ptr);
+
+    // Either the field is unset (and there are no data pointer), or the field
+    // is set with a zero length payload. Mark the iterator as invalid in both
+    // cases.
+    if (size == 0) {
+      curr_value_valid_ = false;
+      return;
+    }
+
+    if ((wire_type == ProtoWireType::kFixed32 && (size % 4) != 0) ||
+        (wire_type == ProtoWireType::kFixed64 && (size % 8) != 0)) {
+      *parse_error_ = true;
+      curr_value_valid_ = false;
+      return;
+    }
+
+    ++(*this);
+  }
+
+  const CppType operator*() const { return curr_value_; }
+  explicit operator bool() const { return curr_value_valid_; }
+
+  PackedRepeatedFieldIterator& operator++() {
+    using proto_utils::ProtoWireType;
+
+    if (PERFETTO_UNLIKELY(!curr_value_valid_))
+      return *this;
+
+    if (PERFETTO_UNLIKELY(read_ptr_ == data_end_)) {
+      curr_value_valid_ = false;
+      return *this;
+    }
+
+    if (wire_type == ProtoWireType::kVarInt) {
+      uint64_t new_value = 0;
+      const uint8_t* new_pos =
+          proto_utils::ParseVarInt(read_ptr_, data_end_, &new_value);
+
+      if (PERFETTO_UNLIKELY(new_pos == read_ptr_)) {
+        // Failed to decode the varint (probably incomplete buffer).
+        *parse_error_ = true;
+        curr_value_valid_ = false;
+      } else {
+        read_ptr_ = new_pos;
+        curr_value_ = static_cast<CppType>(new_value);
+      }
+    } else {  // kFixed32 or kFixed64
+      constexpr size_t kStep = wire_type == ProtoWireType::kFixed32 ? 4 : 8;
+
+      // NB: the raw buffer is not guaranteed to be aligned, so neither are
+      // these copies.
+      memcpy(&curr_value_, read_ptr_, sizeof(CppType));
+      read_ptr_ += kStep;
+    }
+
+    return *this;
+  }
+
+  PackedRepeatedFieldIterator operator++(int) {
+    PackedRepeatedFieldIterator it(*this);
+    ++(*this);
+    return it;
+  }
+
+ private:
+  // Might be null if the backing proto field isn't set.
+  const uint8_t* const data_end_;
+
+  // The iterator looks ahead by an element, so |curr_value| holds the value
+  // to be returned when the caller dereferences the iterator, and |read_ptr_|
+  // points at the start of the next element to be decoded.
+  // |read_ptr_| might be null if the backing proto field isn't set.
+  const uint8_t* read_ptr_;
+  CppType curr_value_ = {};
+
+  // Set to false once we've exhausted the iterator, or encountered an error.
+  bool curr_value_valid_ = true;
+
+  // Where to set parsing errors, supplied by the caller.
+  bool* const parse_error_;
+};
+
+// This decoder loads all fields upfront, without recursing in nested messages.
+// It is used as a base class for typed decoders generated by the pbzero plugin.
+// The split between TypedProtoDecoderBase and TypedProtoDecoder<> is to have
+// unique definition of functions like ParseAllFields() and ExpandHeapStorage().
+// The storage (either on-stack or on-heap) for this class is organized as
+// follows:
+// |-------------------------- fields_ ----------------------|
+// [ field 0 (invalid) ] [ fields 1 .. N ] [ repeated fields ]
+//                                        ^                  ^
+//                                        num_fields_        size_
+// Note that if a message has high field numbers, upon creation |size_| can be
+// < |num_fields_| (until a heap expansion is hit while inserting).
+class PERFETTO_EXPORT_COMPONENT TypedProtoDecoderBase : public ProtoDecoder {
+ public:
+  // If the field |id| is known at compile time, prefer the templated
+  // specialization at<kFieldNumber>().
+  const Field& Get(uint32_t id) const {
+    if (PERFETTO_LIKELY(id < num_fields_ && id < size_))
+      return fields_[id];
+    // If id >= num_fields_, the field id is invalid (was not known in the
+    // .proto) and we return the 0th field, which is always !valid().
+    // If id >= size_ and <= num_fields, the id is valid but the field has not
+    // been seen while decoding (hence the stack storage has not been expanded)
+    // so we return the 0th invalid field.
+    return fields_[0];
+  }
+
+  // Returns an object that allows to iterate over all instances of a repeated
+  // field given its id. Example usage:
+  //   for (auto it = decoder.GetRepeated<int32_t>(N); it; ++it) { ... }
+  template <typename T>
+  RepeatedFieldIterator<T> GetRepeated(uint32_t field_id) const {
+    const Field* repeated_begin;
+    // The storage for repeated fields starts after the slot for the highest
+    // field id (refer to the diagram in the class-level comment). However, if
+    // a message has more than INITIAL_STACK_CAPACITY field there will be no
+    // slots available for the repeated fields (if ExpandHeapStorage() was not
+    // called). Imagine a message that has highest field id = 102 and that is
+    // still using the stack:
+    // [ F0 ] [ F1 ] ... [ F100 ] [ F101 ] [ F1012] [ repeated fields ]
+    //                                            ^ num_fields_
+    //                          ^ size (== capacity)
+    if (PERFETTO_LIKELY(num_fields_ < size_)) {
+      repeated_begin = &fields_[num_fields_];
+    } else {
+      // This is the case of not having any storage space for repeated fields.
+      // This makes it so begin == end, so the iterator will just skip @ last.
+      repeated_begin = &fields_[size_];
+    }
+    const Field* repeated_end = &fields_[size_];
+    const Field* last = &Get(field_id);
+    return RepeatedFieldIterator<T>(field_id, repeated_begin, repeated_end,
+                                    last);
+  }
+
+  // Returns an objects that allows to iterate over all entries of a packed
+  // repeated field given its id and type. The |wire_type| is necessary for
+  // decoding the packed field, the |cpp_type| is for convenience & stronger
+  // typing.
+  //
+  // The caller must also supply a pointer to a bool that is set to true if the
+  // packed buffer is found to be malformed while iterating (so you need to
+  // exhaust the iterator if you want to check the full extent of the buffer).
+  //
+  // Note that unlike standard protobuf parsers, protozero does not allow
+  // treating of packed repeated fields as non-packed and vice-versa (therefore
+  // not making the packed option forwards and backwards compatible). So
+  // the caller needs to use the right accessor for correct results.
+  template <proto_utils::ProtoWireType wire_type, typename cpp_type>
+  PackedRepeatedFieldIterator<wire_type, cpp_type> GetPackedRepeated(
+      uint32_t field_id,
+      bool* parse_error_location) const {
+    const Field& field = Get(field_id);
+    if (field.valid() &&
+        field.type() == proto_utils::ProtoWireType::kLengthDelimited) {
+      return PackedRepeatedFieldIterator<wire_type, cpp_type>(
+          field.data(), field.size(), parse_error_location);
+    }
+    return PackedRepeatedFieldIterator<wire_type, cpp_type>(
+        nullptr, 0, parse_error_location);
+  }
+
+ protected:
+  TypedProtoDecoderBase(Field* storage,
+                        uint32_t num_fields,
+                        uint32_t capacity,
+                        const uint8_t* buffer,
+                        size_t length)
+      : ProtoDecoder(buffer, length),
+        fields_(storage),
+        num_fields_(num_fields),
+        // The reason for "capacity -1" is to avoid hitting the expansion path
+        // in TypedProtoDecoderBase::ParseAllFields() when we are just setting
+        // fields < INITIAL_STACK_CAPACITY (which is the most common case).
+        size_(std::min(num_fields, capacity - 1)),
+        capacity_(capacity) {
+    // The reason why Field needs to be trivially de/constructible is to avoid
+    // implicit initializers on all the ~1000 entries. We need it to initialize
+    // only on the first |max_field_id| fields, the remaining capacity doesn't
+    // require initialization.
+    static_assert(std::is_trivially_constructible<Field>::value &&
+                      std::is_trivially_destructible<Field>::value &&
+                      std::is_trivial<Field>::value,
+                  "Field must be a trivial aggregate type");
+    memset(fields_, 0, sizeof(Field) * capacity_);
+    PERFETTO_DCHECK(capacity > 0);
+  }
+
+  void ParseAllFields();
+
+  // Called when the default on-stack storage is exhausted and new repeated
+  // fields need to be pushed.
+  void ExpandHeapStorage();
+
+  // Used only in presence of a large number of repeated fields, when the
+  // default on-stack storage is exhausted.
+  std::unique_ptr<Field[]> heap_storage_;
+
+  // Points to the storage, either on-stack (default, provided by the template
+  // specialization) or |heap_storage_| after ExpandHeapStorage() is called, in
+  // case of a large number of repeated fields.
+  Field* fields_;
+
+  // Number of known fields, without accounting repeated storage. This is equal
+  // to MAX_FIELD_ID + 1 (to account for the invalid 0th field). It never
+  // changes after construction.
+  // This is unrelated with |size_| and |capacity_|. If the highest field id of
+  // a proto message is 131, |num_fields_| will be = 132 but, on initialization,
+  // |size_| = |capacity_| = 100 (INITIAL_STACK_CAPACITY).
+  // One cannot generally assume that |fields_| has enough storage to
+  // dereference every field. That is only true:
+  // - For field ids < INITIAL_STACK_CAPACITY.
+  // - After the first call to ExpandHeapStorage().
+  uint32_t num_fields_;
+
+  // Number of active |fields_| entries. This is initially equal to
+  // min(num_fields_, INITIAL_STACK_CAPACITY - 1) and after ExpandHeapStorage()
+  // becomes == |num_fields_|. If the message has non-packed repeated fields, it
+  // can grow further, up to |capacity_|.
+  // |size_| is always <= |capacity_|. But |num_fields_| can be > |size_|.
+  uint32_t size_;
+
+  // Initially equal to kFieldsCapacity of the TypedProtoDecoder
+  // specialization. Can grow when falling back on heap-based storage, in which
+  // case it represents the size (#fields with each entry of a repeated field
+  // counted individually) of the |heap_storage_| array.
+  uint32_t capacity_;
+};
+
+// This constant is a tradeoff between having a larger stack frame and being
+// able to decode field IDs up to N (or N - num_fields repeated fields) without
+// falling back on the heap.
+#define PROTOZERO_DECODER_INITIAL_STACK_CAPACITY 100
+
+// Template class instantiated by the auto-generated decoder classes declared in
+// xxx.pbzero.h files.
+template <int MAX_FIELD_ID, bool HAS_NONPACKED_REPEATED_FIELDS>
+class TypedProtoDecoder : public TypedProtoDecoderBase {
+ public:
+  TypedProtoDecoder(const uint8_t* buffer, size_t length)
+      : TypedProtoDecoderBase(on_stack_storage_,
+                              /*num_fields=*/MAX_FIELD_ID + 1,
+                              PROTOZERO_DECODER_INITIAL_STACK_CAPACITY,
+                              buffer,
+                              length) {
+    TypedProtoDecoderBase::ParseAllFields();
+  }
+
+  template <uint32_t FIELD_ID>
+  const Field& at() const {
+    static_assert(FIELD_ID <= MAX_FIELD_ID, "FIELD_ID > MAX_FIELD_ID");
+    // If the field id is < the on-stack capacity, it's safe to always
+    // dereference |fields_|, whether it's still using the stack or it fell
+    // back on the heap. Because both terms of the if () are known at compile
+    // time, the compiler elides the branch for ids < INITIAL_STACK_CAPACITY.
+    if (FIELD_ID < PROTOZERO_DECODER_INITIAL_STACK_CAPACITY) {
+      return fields_[FIELD_ID];
+    } else {
+      // Otherwise use the slowpath Get() which will do a runtime check.
+      return Get(FIELD_ID);
+    }
+  }
+
+  TypedProtoDecoder(TypedProtoDecoder&& other) noexcept
+      : TypedProtoDecoderBase(std::move(other)) {
+    // If the moved-from decoder was using on-stack storage, we need to update
+    // our pointer to point to this decoder's on-stack storage.
+    if (fields_ == other.on_stack_storage_) {
+      fields_ = on_stack_storage_;
+      memcpy(on_stack_storage_, other.on_stack_storage_,
+             sizeof(on_stack_storage_));
+    }
+  }
+
+ private:
+  Field on_stack_storage_[PROTOZERO_DECODER_INITIAL_STACK_CAPACITY];
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_PROTO_DECODER_H_
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeActiveProcesses;
+class ChromeApplicationStateInfo;
+class ChromeCompositorSchedulerState;
+class ChromeContentSettingsEventInfo;
+class ChromeFrameReporter;
+class ChromeHistogramSample;
+class ChromeKeyedService;
+class ChromeLatencyInfo;
+class ChromeLegacyIpc;
+class ChromeMessagePump;
+class ChromeMojoEventInfo;
+class ChromeRendererSchedulerState;
+class ChromeUserEvent;
+class ChromeWindowHandleEventInfo;
+class DebugAnnotation;
+class LogMessage;
+class Screenshot;
+class SourceLocation;
+class TaskExecution;
+class TrackEvent_LegacyEvent;
+namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
+enum FlowDirection : int32_t;
+}  // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
+using TrackEvent_LegacyEvent_FlowDirection = perfetto_pbzero_enum_TrackEvent_LegacyEvent::FlowDirection;
+namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
+enum InstantEventScope : int32_t;
+}  // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
+using TrackEvent_LegacyEvent_InstantEventScope = perfetto_pbzero_enum_TrackEvent_LegacyEvent::InstantEventScope;
+namespace perfetto_pbzero_enum_TrackEvent {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_TrackEvent
+using TrackEvent_Type = perfetto_pbzero_enum_TrackEvent::Type;
+
+namespace perfetto_pbzero_enum_TrackEvent {
+enum Type : int32_t {
+  TYPE_UNSPECIFIED = 0,
+  TYPE_SLICE_BEGIN = 1,
+  TYPE_SLICE_END = 2,
+  TYPE_INSTANT = 3,
+  TYPE_COUNTER = 4,
+};
+} // namespace perfetto_pbzero_enum_TrackEvent
+using TrackEvent_Type = perfetto_pbzero_enum_TrackEvent::Type;
+
+
+constexpr TrackEvent_Type TrackEvent_Type_MIN = TrackEvent_Type::TYPE_UNSPECIFIED;
+constexpr TrackEvent_Type TrackEvent_Type_MAX = TrackEvent_Type::TYPE_COUNTER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TrackEvent_Type_Name(::perfetto::protos::pbzero::TrackEvent_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_UNSPECIFIED:
+    return "TYPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_SLICE_BEGIN:
+    return "TYPE_SLICE_BEGIN";
+
+  case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_SLICE_END:
+    return "TYPE_SLICE_END";
+
+  case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_INSTANT:
+    return "TYPE_INSTANT";
+
+  case ::perfetto::protos::pbzero::TrackEvent_Type::TYPE_COUNTER:
+    return "TYPE_COUNTER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
+enum FlowDirection : int32_t {
+  FLOW_UNSPECIFIED = 0,
+  FLOW_IN = 1,
+  FLOW_OUT = 2,
+  FLOW_INOUT = 3,
+};
+} // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
+using TrackEvent_LegacyEvent_FlowDirection = perfetto_pbzero_enum_TrackEvent_LegacyEvent::FlowDirection;
+
+
+constexpr TrackEvent_LegacyEvent_FlowDirection TrackEvent_LegacyEvent_FlowDirection_MIN = TrackEvent_LegacyEvent_FlowDirection::FLOW_UNSPECIFIED;
+constexpr TrackEvent_LegacyEvent_FlowDirection TrackEvent_LegacyEvent_FlowDirection_MAX = TrackEvent_LegacyEvent_FlowDirection::FLOW_INOUT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TrackEvent_LegacyEvent_FlowDirection_Name(::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_UNSPECIFIED:
+    return "FLOW_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_IN:
+    return "FLOW_IN";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_OUT:
+    return "FLOW_OUT";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection::FLOW_INOUT:
+    return "FLOW_INOUT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent {
+enum InstantEventScope : int32_t {
+  SCOPE_UNSPECIFIED = 0,
+  SCOPE_GLOBAL = 1,
+  SCOPE_PROCESS = 2,
+  SCOPE_THREAD = 3,
+};
+} // namespace perfetto_pbzero_enum_TrackEvent_LegacyEvent
+using TrackEvent_LegacyEvent_InstantEventScope = perfetto_pbzero_enum_TrackEvent_LegacyEvent::InstantEventScope;
+
+
+constexpr TrackEvent_LegacyEvent_InstantEventScope TrackEvent_LegacyEvent_InstantEventScope_MIN = TrackEvent_LegacyEvent_InstantEventScope::SCOPE_UNSPECIFIED;
+constexpr TrackEvent_LegacyEvent_InstantEventScope TrackEvent_LegacyEvent_InstantEventScope_MAX = TrackEvent_LegacyEvent_InstantEventScope::SCOPE_THREAD;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TrackEvent_LegacyEvent_InstantEventScope_Name(::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_UNSPECIFIED:
+    return "SCOPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_GLOBAL:
+    return "SCOPE_GLOBAL";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_PROCESS:
+    return "SCOPE_PROCESS";
+
+  case ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope::SCOPE_THREAD:
+    return "SCOPE_THREAD";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class EventName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EventName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EventName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EventName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class EventName : public ::protozero::Message {
+ public:
+  using Decoder = EventName_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EventName"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EventName>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EventName>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class EventCategory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EventCategory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EventCategory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EventCategory_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class EventCategory : public ::protozero::Message {
+ public:
+  using Decoder = EventCategory_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EventCategory"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EventCategory>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EventCategory>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrackEventDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/45, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TrackEventDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEventDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEventDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_track_uuid() const { return at<11>().valid(); }
+  uint64_t track_uuid() const { return at<11>().as_uint64(); }
+  bool has_extra_counter_track_uuids() const { return at<31>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> extra_counter_track_uuids() const { return GetRepeated<uint64_t>(31); }
+  bool has_extra_double_counter_track_uuids() const { return at<45>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> extra_double_counter_track_uuids() const { return GetRepeated<uint64_t>(45); }
+};
+
+class TrackEventDefaults : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventDefaults_Decoder;
+  enum : int32_t {
+    kTrackUuidFieldNumber = 11,
+    kExtraCounterTrackUuidsFieldNumber = 31,
+    kExtraDoubleCounterTrackUuidsFieldNumber = 45,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEventDefaults"; }
+
+
+  using FieldMetadata_TrackUuid =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEventDefaults>;
+
+  static constexpr FieldMetadata_TrackUuid kTrackUuid{};
+  void set_track_uuid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrackUuid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExtraCounterTrackUuids =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEventDefaults>;
+
+  static constexpr FieldMetadata_ExtraCounterTrackUuids kExtraCounterTrackUuids{};
+  void add_extra_counter_track_uuids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraCounterTrackUuids::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExtraDoubleCounterTrackUuids =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEventDefaults>;
+
+  static constexpr FieldMetadata_ExtraDoubleCounterTrackUuids kExtraDoubleCounterTrackUuids{};
+  void add_extra_double_counter_track_uuids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraDoubleCounterTrackUuids::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrackEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/50, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TrackEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_category_iids() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> category_iids() const { return GetRepeated<uint64_t>(3); }
+  bool has_categories() const { return at<22>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> categories() const { return GetRepeated<::protozero::ConstChars>(22); }
+  bool has_name_iid() const { return at<10>().valid(); }
+  uint64_t name_iid() const { return at<10>().as_uint64(); }
+  bool has_name() const { return at<23>().valid(); }
+  ::protozero::ConstChars name() const { return at<23>().as_string(); }
+  bool has_type() const { return at<9>().valid(); }
+  int32_t type() const { return at<9>().as_int32(); }
+  bool has_track_uuid() const { return at<11>().valid(); }
+  uint64_t track_uuid() const { return at<11>().as_uint64(); }
+  bool has_counter_value() const { return at<30>().valid(); }
+  int64_t counter_value() const { return at<30>().as_int64(); }
+  bool has_double_counter_value() const { return at<44>().valid(); }
+  double double_counter_value() const { return at<44>().as_double(); }
+  bool has_extra_counter_track_uuids() const { return at<31>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> extra_counter_track_uuids() const { return GetRepeated<uint64_t>(31); }
+  bool has_extra_counter_values() const { return at<12>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> extra_counter_values() const { return GetRepeated<int64_t>(12); }
+  bool has_extra_double_counter_track_uuids() const { return at<45>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> extra_double_counter_track_uuids() const { return GetRepeated<uint64_t>(45); }
+  bool has_extra_double_counter_values() const { return at<46>().valid(); }
+  ::protozero::RepeatedFieldIterator<double> extra_double_counter_values() const { return GetRepeated<double>(46); }
+  bool has_flow_ids_old() const { return at<36>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> flow_ids_old() const { return GetRepeated<uint64_t>(36); }
+  bool has_flow_ids() const { return at<47>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> flow_ids() const { return GetRepeated<uint64_t>(47); }
+  bool has_terminating_flow_ids_old() const { return at<42>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> terminating_flow_ids_old() const { return GetRepeated<uint64_t>(42); }
+  bool has_terminating_flow_ids() const { return at<48>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> terminating_flow_ids() const { return GetRepeated<uint64_t>(48); }
+  bool has_debug_annotations() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotations() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_task_execution() const { return at<5>().valid(); }
+  ::protozero::ConstBytes task_execution() const { return at<5>().as_bytes(); }
+  bool has_log_message() const { return at<21>().valid(); }
+  ::protozero::ConstBytes log_message() const { return at<21>().as_bytes(); }
+  bool has_cc_scheduler_state() const { return at<24>().valid(); }
+  ::protozero::ConstBytes cc_scheduler_state() const { return at<24>().as_bytes(); }
+  bool has_chrome_user_event() const { return at<25>().valid(); }
+  ::protozero::ConstBytes chrome_user_event() const { return at<25>().as_bytes(); }
+  bool has_chrome_keyed_service() const { return at<26>().valid(); }
+  ::protozero::ConstBytes chrome_keyed_service() const { return at<26>().as_bytes(); }
+  bool has_chrome_legacy_ipc() const { return at<27>().valid(); }
+  ::protozero::ConstBytes chrome_legacy_ipc() const { return at<27>().as_bytes(); }
+  bool has_chrome_histogram_sample() const { return at<28>().valid(); }
+  ::protozero::ConstBytes chrome_histogram_sample() const { return at<28>().as_bytes(); }
+  bool has_chrome_latency_info() const { return at<29>().valid(); }
+  ::protozero::ConstBytes chrome_latency_info() const { return at<29>().as_bytes(); }
+  bool has_chrome_frame_reporter() const { return at<32>().valid(); }
+  ::protozero::ConstBytes chrome_frame_reporter() const { return at<32>().as_bytes(); }
+  bool has_chrome_application_state_info() const { return at<39>().valid(); }
+  ::protozero::ConstBytes chrome_application_state_info() const { return at<39>().as_bytes(); }
+  bool has_chrome_renderer_scheduler_state() const { return at<40>().valid(); }
+  ::protozero::ConstBytes chrome_renderer_scheduler_state() const { return at<40>().as_bytes(); }
+  bool has_chrome_window_handle_event_info() const { return at<41>().valid(); }
+  ::protozero::ConstBytes chrome_window_handle_event_info() const { return at<41>().as_bytes(); }
+  bool has_chrome_content_settings_event_info() const { return at<43>().valid(); }
+  ::protozero::ConstBytes chrome_content_settings_event_info() const { return at<43>().as_bytes(); }
+  bool has_chrome_active_processes() const { return at<49>().valid(); }
+  ::protozero::ConstBytes chrome_active_processes() const { return at<49>().as_bytes(); }
+  bool has_screenshot() const { return at<50>().valid(); }
+  ::protozero::ConstBytes screenshot() const { return at<50>().as_bytes(); }
+  bool has_source_location() const { return at<33>().valid(); }
+  ::protozero::ConstBytes source_location() const { return at<33>().as_bytes(); }
+  bool has_source_location_iid() const { return at<34>().valid(); }
+  uint64_t source_location_iid() const { return at<34>().as_uint64(); }
+  bool has_chrome_message_pump() const { return at<35>().valid(); }
+  ::protozero::ConstBytes chrome_message_pump() const { return at<35>().as_bytes(); }
+  bool has_chrome_mojo_event_info() const { return at<38>().valid(); }
+  ::protozero::ConstBytes chrome_mojo_event_info() const { return at<38>().as_bytes(); }
+  bool has_timestamp_delta_us() const { return at<1>().valid(); }
+  int64_t timestamp_delta_us() const { return at<1>().as_int64(); }
+  bool has_timestamp_absolute_us() const { return at<16>().valid(); }
+  int64_t timestamp_absolute_us() const { return at<16>().as_int64(); }
+  bool has_thread_time_delta_us() const { return at<2>().valid(); }
+  int64_t thread_time_delta_us() const { return at<2>().as_int64(); }
+  bool has_thread_time_absolute_us() const { return at<17>().valid(); }
+  int64_t thread_time_absolute_us() const { return at<17>().as_int64(); }
+  bool has_thread_instruction_count_delta() const { return at<8>().valid(); }
+  int64_t thread_instruction_count_delta() const { return at<8>().as_int64(); }
+  bool has_thread_instruction_count_absolute() const { return at<20>().valid(); }
+  int64_t thread_instruction_count_absolute() const { return at<20>().as_int64(); }
+  bool has_legacy_event() const { return at<6>().valid(); }
+  ::protozero::ConstBytes legacy_event() const { return at<6>().as_bytes(); }
+};
+
+class TrackEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrackEvent_Decoder;
+  enum : int32_t {
+    kCategoryIidsFieldNumber = 3,
+    kCategoriesFieldNumber = 22,
+    kNameIidFieldNumber = 10,
+    kNameFieldNumber = 23,
+    kTypeFieldNumber = 9,
+    kTrackUuidFieldNumber = 11,
+    kCounterValueFieldNumber = 30,
+    kDoubleCounterValueFieldNumber = 44,
+    kExtraCounterTrackUuidsFieldNumber = 31,
+    kExtraCounterValuesFieldNumber = 12,
+    kExtraDoubleCounterTrackUuidsFieldNumber = 45,
+    kExtraDoubleCounterValuesFieldNumber = 46,
+    kFlowIdsOldFieldNumber = 36,
+    kFlowIdsFieldNumber = 47,
+    kTerminatingFlowIdsOldFieldNumber = 42,
+    kTerminatingFlowIdsFieldNumber = 48,
+    kDebugAnnotationsFieldNumber = 4,
+    kTaskExecutionFieldNumber = 5,
+    kLogMessageFieldNumber = 21,
+    kCcSchedulerStateFieldNumber = 24,
+    kChromeUserEventFieldNumber = 25,
+    kChromeKeyedServiceFieldNumber = 26,
+    kChromeLegacyIpcFieldNumber = 27,
+    kChromeHistogramSampleFieldNumber = 28,
+    kChromeLatencyInfoFieldNumber = 29,
+    kChromeFrameReporterFieldNumber = 32,
+    kChromeApplicationStateInfoFieldNumber = 39,
+    kChromeRendererSchedulerStateFieldNumber = 40,
+    kChromeWindowHandleEventInfoFieldNumber = 41,
+    kChromeContentSettingsEventInfoFieldNumber = 43,
+    kChromeActiveProcessesFieldNumber = 49,
+    kScreenshotFieldNumber = 50,
+    kSourceLocationFieldNumber = 33,
+    kSourceLocationIidFieldNumber = 34,
+    kChromeMessagePumpFieldNumber = 35,
+    kChromeMojoEventInfoFieldNumber = 38,
+    kTimestampDeltaUsFieldNumber = 1,
+    kTimestampAbsoluteUsFieldNumber = 16,
+    kThreadTimeDeltaUsFieldNumber = 2,
+    kThreadTimeAbsoluteUsFieldNumber = 17,
+    kThreadInstructionCountDeltaFieldNumber = 8,
+    kThreadInstructionCountAbsoluteFieldNumber = 20,
+    kLegacyEventFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEvent"; }
+
+  using LegacyEvent = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent;
+
+  using Type = ::perfetto::protos::pbzero::TrackEvent_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::TrackEvent_Type_Name(value);
+  }
+  static inline const Type TYPE_UNSPECIFIED = Type::TYPE_UNSPECIFIED;
+  static inline const Type TYPE_SLICE_BEGIN = Type::TYPE_SLICE_BEGIN;
+  static inline const Type TYPE_SLICE_END = Type::TYPE_SLICE_END;
+  static inline const Type TYPE_INSTANT = Type::TYPE_INSTANT;
+  static inline const Type TYPE_COUNTER = Type::TYPE_COUNTER;
+
+  using FieldMetadata_CategoryIids =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_CategoryIids kCategoryIids{};
+  void add_category_iids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CategoryIids::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Categories =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_Categories kCategories{};
+  void add_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, data, size);
+  }
+  void add_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, chars.data, chars.size);
+  }
+  void add_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Categories::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_NameIid kNameIid{};
+  void set_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TrackEvent_Type,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(::perfetto::protos::pbzero::TrackEvent_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TrackUuid =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TrackUuid kTrackUuid{};
+  void set_track_uuid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrackUuid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CounterValue =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_CounterValue kCounterValue{};
+  void set_counter_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoubleCounterValue =
+    ::protozero::proto_utils::FieldMetadata<
+      44,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_DoubleCounterValue kDoubleCounterValue{};
+  void set_double_counter_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleCounterValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExtraCounterTrackUuids =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ExtraCounterTrackUuids kExtraCounterTrackUuids{};
+  void add_extra_counter_track_uuids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraCounterTrackUuids::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExtraCounterValues =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ExtraCounterValues kExtraCounterValues{};
+  void add_extra_counter_values(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraCounterValues::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExtraDoubleCounterTrackUuids =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ExtraDoubleCounterTrackUuids kExtraDoubleCounterTrackUuids{};
+  void add_extra_double_counter_track_uuids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraDoubleCounterTrackUuids::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExtraDoubleCounterValues =
+    ::protozero::proto_utils::FieldMetadata<
+      46,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ExtraDoubleCounterValues kExtraDoubleCounterValues{};
+  void add_extra_double_counter_values(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraDoubleCounterValues::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FlowIdsOld =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_FlowIdsOld kFlowIdsOld{};
+  void add_flow_ids_old(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlowIdsOld::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FlowIds =
+    ::protozero::proto_utils::FieldMetadata<
+      47,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_FlowIds kFlowIds{};
+  void add_flow_ids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlowIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TerminatingFlowIdsOld =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TerminatingFlowIdsOld kTerminatingFlowIdsOld{};
+  void add_terminating_flow_ids_old(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TerminatingFlowIdsOld::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TerminatingFlowIds =
+    ::protozero::proto_utils::FieldMetadata<
+      48,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TerminatingFlowIds kTerminatingFlowIds{};
+  void add_terminating_flow_ids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TerminatingFlowIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DebugAnnotations =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations{};
+  template <typename T = DebugAnnotation> T* add_debug_annotations() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_TaskExecution =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TaskExecution,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TaskExecution kTaskExecution{};
+  template <typename T = TaskExecution> T* set_task_execution() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_LogMessage =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LogMessage,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_LogMessage kLogMessage{};
+  template <typename T = LogMessage> T* set_log_message() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_CcSchedulerState =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeCompositorSchedulerState,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_CcSchedulerState kCcSchedulerState{};
+  template <typename T = ChromeCompositorSchedulerState> T* set_cc_scheduler_state() {
+    return BeginNestedMessage<T>(24);
+  }
+
+
+  using FieldMetadata_ChromeUserEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeUserEvent,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeUserEvent kChromeUserEvent{};
+  template <typename T = ChromeUserEvent> T* set_chrome_user_event() {
+    return BeginNestedMessage<T>(25);
+  }
+
+
+  using FieldMetadata_ChromeKeyedService =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeKeyedService,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeKeyedService kChromeKeyedService{};
+  template <typename T = ChromeKeyedService> T* set_chrome_keyed_service() {
+    return BeginNestedMessage<T>(26);
+  }
+
+
+  using FieldMetadata_ChromeLegacyIpc =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeLegacyIpc,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeLegacyIpc kChromeLegacyIpc{};
+  template <typename T = ChromeLegacyIpc> T* set_chrome_legacy_ipc() {
+    return BeginNestedMessage<T>(27);
+  }
+
+
+  using FieldMetadata_ChromeHistogramSample =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeHistogramSample,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeHistogramSample kChromeHistogramSample{};
+  template <typename T = ChromeHistogramSample> T* set_chrome_histogram_sample() {
+    return BeginNestedMessage<T>(28);
+  }
+
+
+  using FieldMetadata_ChromeLatencyInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeLatencyInfo,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeLatencyInfo kChromeLatencyInfo{};
+  template <typename T = ChromeLatencyInfo> T* set_chrome_latency_info() {
+    return BeginNestedMessage<T>(29);
+  }
+
+
+  using FieldMetadata_ChromeFrameReporter =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeFrameReporter,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeFrameReporter kChromeFrameReporter{};
+  template <typename T = ChromeFrameReporter> T* set_chrome_frame_reporter() {
+    return BeginNestedMessage<T>(32);
+  }
+
+
+  using FieldMetadata_ChromeApplicationStateInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeApplicationStateInfo,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeApplicationStateInfo kChromeApplicationStateInfo{};
+  template <typename T = ChromeApplicationStateInfo> T* set_chrome_application_state_info() {
+    return BeginNestedMessage<T>(39);
+  }
+
+
+  using FieldMetadata_ChromeRendererSchedulerState =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeRendererSchedulerState,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeRendererSchedulerState kChromeRendererSchedulerState{};
+  template <typename T = ChromeRendererSchedulerState> T* set_chrome_renderer_scheduler_state() {
+    return BeginNestedMessage<T>(40);
+  }
+
+
+  using FieldMetadata_ChromeWindowHandleEventInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeWindowHandleEventInfo,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeWindowHandleEventInfo kChromeWindowHandleEventInfo{};
+  template <typename T = ChromeWindowHandleEventInfo> T* set_chrome_window_handle_event_info() {
+    return BeginNestedMessage<T>(41);
+  }
+
+
+  using FieldMetadata_ChromeContentSettingsEventInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      43,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeContentSettingsEventInfo,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeContentSettingsEventInfo kChromeContentSettingsEventInfo{};
+  template <typename T = ChromeContentSettingsEventInfo> T* set_chrome_content_settings_event_info() {
+    return BeginNestedMessage<T>(43);
+  }
+
+
+  using FieldMetadata_ChromeActiveProcesses =
+    ::protozero::proto_utils::FieldMetadata<
+      49,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeActiveProcesses,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeActiveProcesses kChromeActiveProcesses{};
+  template <typename T = ChromeActiveProcesses> T* set_chrome_active_processes() {
+    return BeginNestedMessage<T>(49);
+  }
+
+
+  using FieldMetadata_Screenshot =
+    ::protozero::proto_utils::FieldMetadata<
+      50,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Screenshot,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_Screenshot kScreenshot{};
+  template <typename T = Screenshot> T* set_screenshot() {
+    return BeginNestedMessage<T>(50);
+  }
+
+
+  using FieldMetadata_SourceLocation =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SourceLocation,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_SourceLocation kSourceLocation{};
+  template <typename T = SourceLocation> T* set_source_location() {
+    return BeginNestedMessage<T>(33);
+  }
+
+
+  using FieldMetadata_SourceLocationIid =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid{};
+  void set_source_location_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceLocationIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChromeMessagePump =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeMessagePump,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeMessagePump kChromeMessagePump{};
+  template <typename T = ChromeMessagePump> T* set_chrome_message_pump() {
+    return BeginNestedMessage<T>(35);
+  }
+
+
+  using FieldMetadata_ChromeMojoEventInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeMojoEventInfo,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ChromeMojoEventInfo kChromeMojoEventInfo{};
+  template <typename T = ChromeMojoEventInfo> T* set_chrome_mojo_event_info() {
+    return BeginNestedMessage<T>(38);
+  }
+
+
+  using FieldMetadata_TimestampDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TimestampDeltaUs kTimestampDeltaUs{};
+  void set_timestamp_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimestampAbsoluteUs =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_TimestampAbsoluteUs kTimestampAbsoluteUs{};
+  void set_timestamp_absolute_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampAbsoluteUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadTimeDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ThreadTimeDeltaUs kThreadTimeDeltaUs{};
+  void set_thread_time_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadTimeDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadTimeAbsoluteUs =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ThreadTimeAbsoluteUs kThreadTimeAbsoluteUs{};
+  void set_thread_time_absolute_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadTimeAbsoluteUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadInstructionCountDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ThreadInstructionCountDelta kThreadInstructionCountDelta{};
+  void set_thread_instruction_count_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadInstructionCountDelta::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadInstructionCountAbsolute =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_ThreadInstructionCountAbsolute kThreadInstructionCountAbsolute{};
+  void set_thread_instruction_count_absolute(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadInstructionCountAbsolute::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LegacyEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEvent_LegacyEvent,
+      TrackEvent>;
+
+  static constexpr FieldMetadata_LegacyEvent kLegacyEvent{};
+  template <typename T = TrackEvent_LegacyEvent> T* set_legacy_event() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class TrackEvent_LegacyEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrackEvent_LegacyEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEvent_LegacyEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEvent_LegacyEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name_iid() const { return at<1>().valid(); }
+  uint64_t name_iid() const { return at<1>().as_uint64(); }
+  bool has_phase() const { return at<2>().valid(); }
+  int32_t phase() const { return at<2>().as_int32(); }
+  bool has_duration_us() const { return at<3>().valid(); }
+  int64_t duration_us() const { return at<3>().as_int64(); }
+  bool has_thread_duration_us() const { return at<4>().valid(); }
+  int64_t thread_duration_us() const { return at<4>().as_int64(); }
+  bool has_thread_instruction_delta() const { return at<15>().valid(); }
+  int64_t thread_instruction_delta() const { return at<15>().as_int64(); }
+  bool has_unscoped_id() const { return at<6>().valid(); }
+  uint64_t unscoped_id() const { return at<6>().as_uint64(); }
+  bool has_local_id() const { return at<10>().valid(); }
+  uint64_t local_id() const { return at<10>().as_uint64(); }
+  bool has_global_id() const { return at<11>().valid(); }
+  uint64_t global_id() const { return at<11>().as_uint64(); }
+  bool has_id_scope() const { return at<7>().valid(); }
+  ::protozero::ConstChars id_scope() const { return at<7>().as_string(); }
+  bool has_use_async_tts() const { return at<9>().valid(); }
+  bool use_async_tts() const { return at<9>().as_bool(); }
+  bool has_bind_id() const { return at<8>().valid(); }
+  uint64_t bind_id() const { return at<8>().as_uint64(); }
+  bool has_bind_to_enclosing() const { return at<12>().valid(); }
+  bool bind_to_enclosing() const { return at<12>().as_bool(); }
+  bool has_flow_direction() const { return at<13>().valid(); }
+  int32_t flow_direction() const { return at<13>().as_int32(); }
+  bool has_instant_event_scope() const { return at<14>().valid(); }
+  int32_t instant_event_scope() const { return at<14>().as_int32(); }
+  bool has_pid_override() const { return at<18>().valid(); }
+  int32_t pid_override() const { return at<18>().as_int32(); }
+  bool has_tid_override() const { return at<19>().valid(); }
+  int32_t tid_override() const { return at<19>().as_int32(); }
+};
+
+class TrackEvent_LegacyEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrackEvent_LegacyEvent_Decoder;
+  enum : int32_t {
+    kNameIidFieldNumber = 1,
+    kPhaseFieldNumber = 2,
+    kDurationUsFieldNumber = 3,
+    kThreadDurationUsFieldNumber = 4,
+    kThreadInstructionDeltaFieldNumber = 15,
+    kUnscopedIdFieldNumber = 6,
+    kLocalIdFieldNumber = 10,
+    kGlobalIdFieldNumber = 11,
+    kIdScopeFieldNumber = 7,
+    kUseAsyncTtsFieldNumber = 9,
+    kBindIdFieldNumber = 8,
+    kBindToEnclosingFieldNumber = 12,
+    kFlowDirectionFieldNumber = 13,
+    kInstantEventScopeFieldNumber = 14,
+    kPidOverrideFieldNumber = 18,
+    kTidOverrideFieldNumber = 19,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEvent.LegacyEvent"; }
+
+
+  using FlowDirection = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection;
+  static inline const char* FlowDirection_Name(FlowDirection value) {
+    return ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection_Name(value);
+  }
+
+  using InstantEventScope = ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope;
+  static inline const char* InstantEventScope_Name(InstantEventScope value) {
+    return ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope_Name(value);
+  }
+  static inline const FlowDirection FLOW_UNSPECIFIED = FlowDirection::FLOW_UNSPECIFIED;
+  static inline const FlowDirection FLOW_IN = FlowDirection::FLOW_IN;
+  static inline const FlowDirection FLOW_OUT = FlowDirection::FLOW_OUT;
+  static inline const FlowDirection FLOW_INOUT = FlowDirection::FLOW_INOUT;
+  static inline const InstantEventScope SCOPE_UNSPECIFIED = InstantEventScope::SCOPE_UNSPECIFIED;
+  static inline const InstantEventScope SCOPE_GLOBAL = InstantEventScope::SCOPE_GLOBAL;
+  static inline const InstantEventScope SCOPE_PROCESS = InstantEventScope::SCOPE_PROCESS;
+  static inline const InstantEventScope SCOPE_THREAD = InstantEventScope::SCOPE_THREAD;
+
+  using FieldMetadata_NameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_NameIid kNameIid{};
+  void set_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Phase =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_Phase kPhase{};
+  void set_phase(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Phase::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DurationUs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_DurationUs kDurationUs{};
+  void set_duration_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DurationUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadDurationUs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_ThreadDurationUs kThreadDurationUs{};
+  void set_thread_duration_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadDurationUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadInstructionDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_ThreadInstructionDelta kThreadInstructionDelta{};
+  void set_thread_instruction_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadInstructionDelta::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UnscopedId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_UnscopedId kUnscopedId{};
+  void set_unscoped_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnscopedId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LocalId =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_LocalId kLocalId{};
+  void set_local_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LocalId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GlobalId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_GlobalId kGlobalId{};
+  void set_global_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GlobalId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IdScope =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_IdScope kIdScope{};
+  void set_id_scope(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_IdScope::kFieldId, data, size);
+  }
+  void set_id_scope(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_IdScope::kFieldId, chars.data, chars.size);
+  }
+  void set_id_scope(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_IdScope::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UseAsyncTts =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_UseAsyncTts kUseAsyncTts{};
+  void set_use_async_tts(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_UseAsyncTts::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BindId =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_BindId kBindId{};
+  void set_bind_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BindId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BindToEnclosing =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_BindToEnclosing kBindToEnclosing{};
+  void set_bind_to_enclosing(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BindToEnclosing::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FlowDirection =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_FlowDirection kFlowDirection{};
+  void set_flow_direction(::perfetto::protos::pbzero::TrackEvent_LegacyEvent_FlowDirection value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlowDirection::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InstantEventScope =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_InstantEventScope kInstantEventScope{};
+  void set_instant_event_scope(::perfetto::protos::pbzero::TrackEvent_LegacyEvent_InstantEventScope value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstantEventScope::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PidOverride =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_PidOverride kPidOverride{};
+  void set_pid_override(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PidOverride::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TidOverride =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrackEvent_LegacyEvent>;
+
+  static constexpr FieldMetadata_TidOverride kTidOverride{};
+  void set_tid_override(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TidOverride::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class TracePacket_Decoder;
+class TrackEvent;
+class TrackEvent_Decoder;
+}  // namespace pbzero
+}  // namespace protos
+
+// A helper for keeping track of incremental state when intercepting track
+// events.
+class PERFETTO_EXPORT_COMPONENT TrackEventStateTracker {
+ public:
+  ~TrackEventStateTracker();
+
+  struct StackFrame {
+    uint64_t timestamp{};
+
+    // Only one of |name| and |name_iid| will be set.
+    std::string name;
+    uint64_t name_iid{};
+    uint64_t name_hash{};
+
+    // Only one of |category| and |category_iid| will be set.
+    std::string category;
+    uint64_t category_iid{};
+  };
+
+  struct Track {
+    uint64_t uuid{};
+    uint32_t index{};  // Ordinal number for the track in the tracing session.
+
+    std::string name;
+    int64_t pid{};
+    int64_t tid{};
+
+    // Opaque user data associated with the track.
+    std::vector<uint8_t> user_data;
+
+    // Stack of opened slices on this track.
+    std::vector<StackFrame> stack;
+  };
+
+  // State for a single trace writer sequence (typically a single thread).
+  struct SequenceState {
+    // Trace packet sequence defaults.
+    Track track;
+
+    // Interned state.
+#if PERFETTO_DCHECK_IS_ON()
+    uint32_t sequence_id{};
+#endif
+    std::map<uint64_t /*iid*/, std::string> event_names;
+    std::map<uint64_t /*iid*/, std::string> event_categories;
+    std::map<uint64_t /*iid*/, std::string> debug_annotation_names;
+    // Current absolute timestamp of the incremental clock.
+    uint64_t most_recent_absolute_time_ns = 0;
+    // default_clock_id == 0 means, no default clock_id is set.
+    uint32_t default_clock_id = 0;
+  };
+
+  // State for the entire tracing session. Shared by all trace writer sequences
+  // participating in the session.
+  struct SessionState {
+    // Non-thread-bound tracks.
+    std::map<uint64_t /*uuid*/, Track> tracks;
+  };
+
+  // Represents a single decoded track event (without arguments).
+  struct ParsedTrackEvent {
+    explicit ParsedTrackEvent(
+        const perfetto::protos::pbzero::TrackEvent::Decoder&);
+
+    // Underlying event.
+    const perfetto::protos::pbzero::TrackEvent::Decoder& track_event;
+
+    // Event metadata.
+    uint64_t timestamp_ns{};
+    uint64_t duration_ns{};
+
+    size_t stack_depth{};
+
+    protozero::ConstChars category{};
+    protozero::ConstChars name{};
+    uint64_t name_hash{};
+  };
+
+  // Interface used by the tracker to access tracing session and sequence state
+  // and to report parsed track events.
+  class PERFETTO_EXPORT_COMPONENT Delegate {
+   public:
+    virtual ~Delegate();
+
+    // Called to retrieve the session-global state shared by all sequences. The
+    // returned pointer must remain valid (locked) throughout the call to
+    // |ProcessTracePacket|.
+    virtual SessionState* GetSessionState() = 0;
+
+    // Called when the metadata (e.g., name) for a track changes. |Track| can be
+    // modified by the callback to attach user data.
+    virtual void OnTrackUpdated(Track&) = 0;
+
+    // If the packet given to |ProcessTracePacket| contains a track event, this
+    // method is called to report the properties of that event. Note that memory
+    // pointers in |TrackEvent| will only be valid during this call.
+    virtual void OnTrackEvent(const Track&, const ParsedTrackEvent&) = 0;
+  };
+
+  // Process a single trace packet, reporting any contained track event back via
+  // the delegate interface. |SequenceState| must correspond to the sequence
+  // that was used to write the packet.
+  static void ProcessTracePacket(Delegate&,
+                                 SequenceState&,
+                                 const protos::pbzero::TracePacket_Decoder&);
+
+ private:
+  static void UpdateIncrementalState(
+      Delegate&,
+      SequenceState&,
+      const protos::pbzero::TracePacket_Decoder&);
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
+#define INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_state_tracker.h"
+
+#include <stdarg.h>
+
+#include <functional>
+#include <map>
+#include <vector>
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+#define PERFETTO_PRINTF_ATTR \
+  __attribute__((format(printf, /*format_index=*/2, /*first_to_check=*/3)))
+#else
+#define PERFETTO_PRINTF_ATTR
+#endif
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && !defined(STDOUT_FILENO)
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+#endif
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DebugAnnotation_Decoder;
+class TracePacket_Decoder;
+class TrackEvent_Decoder;
+}  // namespace pbzero
+}  // namespace protos
+
+struct ConsoleColor;
+
+class PERFETTO_EXPORT_COMPONENT ConsoleInterceptor
+    : public Interceptor<ConsoleInterceptor> {
+ public:
+  ~ConsoleInterceptor() override;
+
+  static void Register();
+  static void OnTracePacket(InterceptorContext context);
+
+  static void SetOutputFdForTesting(int fd);
+
+  void OnSetup(const SetupArgs&) override;
+  void OnStart(const StartArgs&) override;
+  void OnStop(const StopArgs&) override;
+
+  struct ThreadLocalState : public InterceptorBase::ThreadLocalState {
+    ThreadLocalState(ThreadLocalStateArgs&);
+    ~ThreadLocalState() override;
+
+    // Destination file. Assumed to stay valid until the program ends (i.e., is
+    // stderr or stdout).
+    int fd{};
+    bool use_colors{};
+
+    // Messages up to this length are buffered and written atomically. If a
+    // message is longer, it will be printed with multiple writes.
+    std::array<char, 1024> message_buffer{};
+    size_t buffer_pos{};
+
+    // We only support a single trace writer sequence per thread, so the
+    // sequence state is stored in TLS.
+    TrackEventStateTracker::SequenceState sequence_state;
+    uint64_t start_time_ns{};
+  };
+
+ private:
+  class Delegate;
+
+  // Appends a formatted message to |message_buffer_| or directly to the output
+  // file if the buffer is full.
+  static void Printf(InterceptorContext& context,
+                     const char* format,
+                     ...) PERFETTO_PRINTF_ATTR;
+  static void Flush(InterceptorContext& context);
+  static void SetColor(InterceptorContext& context, const ConsoleColor&);
+  static void SetColor(InterceptorContext& context, const char*);
+
+  static void PrintDebugAnnotations(InterceptorContext&,
+                                    const protos::pbzero::TrackEvent_Decoder&,
+                                    const ConsoleColor& slice_color,
+                                    const ConsoleColor& highlight_color);
+  static void PrintDebugAnnotationName(
+      InterceptorContext&,
+      const perfetto::protos::pbzero::DebugAnnotation_Decoder& annotation);
+  static void PrintDebugAnnotationValue(
+      InterceptorContext&,
+      const perfetto::protos::pbzero::DebugAnnotation_Decoder& annotation);
+
+  int fd_ = STDOUT_FILENO;
+  bool use_colors_ = true;
+
+  TrackEventStateTracker::SessionState session_state_;
+  uint64_t start_time_ns_{};
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_CONSOLE_INTERCEPTOR_H_
+// gen_amalgamated begin header: include/perfetto/tracing/core/data_source_descriptor.h
+// gen_amalgamated begin header: gen/protos/perfetto/common/data_source_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class DataSourceDescriptor;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT DataSourceDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kIdFieldNumber = 7,
+    kWillNotifyOnStopFieldNumber = 2,
+    kWillNotifyOnStartFieldNumber = 3,
+    kHandlesIncrementalStateClearFieldNumber = 4,
+    kNoFlushFieldNumber = 9,
+    kGpuCounterDescriptorFieldNumber = 5,
+    kTrackEventDescriptorFieldNumber = 6,
+    kFtraceDescriptorFieldNumber = 8,
+  };
+
+  DataSourceDescriptor();
+  ~DataSourceDescriptor() override;
+  DataSourceDescriptor(DataSourceDescriptor&&) noexcept;
+  DataSourceDescriptor& operator=(DataSourceDescriptor&&);
+  DataSourceDescriptor(const DataSourceDescriptor&);
+  DataSourceDescriptor& operator=(const DataSourceDescriptor&);
+  bool operator==(const DataSourceDescriptor&) const;
+  bool operator!=(const DataSourceDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_id() const { return _has_field_[7]; }
+  uint64_t id() const { return id_; }
+  void set_id(uint64_t value) { id_ = value; _has_field_.set(7); }
+
+  bool has_will_notify_on_stop() const { return _has_field_[2]; }
+  bool will_notify_on_stop() const { return will_notify_on_stop_; }
+  void set_will_notify_on_stop(bool value) { will_notify_on_stop_ = value; _has_field_.set(2); }
+
+  bool has_will_notify_on_start() const { return _has_field_[3]; }
+  bool will_notify_on_start() const { return will_notify_on_start_; }
+  void set_will_notify_on_start(bool value) { will_notify_on_start_ = value; _has_field_.set(3); }
+
+  bool has_handles_incremental_state_clear() const { return _has_field_[4]; }
+  bool handles_incremental_state_clear() const { return handles_incremental_state_clear_; }
+  void set_handles_incremental_state_clear(bool value) { handles_incremental_state_clear_ = value; _has_field_.set(4); }
+
+  bool has_no_flush() const { return _has_field_[9]; }
+  bool no_flush() const { return no_flush_; }
+  void set_no_flush(bool value) { no_flush_ = value; _has_field_.set(9); }
+
+  const std::string& gpu_counter_descriptor_raw() const { return gpu_counter_descriptor_; }
+  void set_gpu_counter_descriptor_raw(const std::string& raw) { gpu_counter_descriptor_ = raw; _has_field_.set(5); }
+
+  const std::string& track_event_descriptor_raw() const { return track_event_descriptor_; }
+  void set_track_event_descriptor_raw(const std::string& raw) { track_event_descriptor_ = raw; _has_field_.set(6); }
+
+  const std::string& ftrace_descriptor_raw() const { return ftrace_descriptor_; }
+  void set_ftrace_descriptor_raw(const std::string& raw) { ftrace_descriptor_ = raw; _has_field_.set(8); }
+
+ private:
+  std::string name_{};
+  uint64_t id_{};
+  bool will_notify_on_stop_{};
+  bool will_notify_on_start_{};
+  bool handles_incremental_state_clear_{};
+  bool no_flush_{};
+  std::string gpu_counter_descriptor_;  // [lazy=true]
+  std::string track_event_descriptor_;  // [lazy=true]
+  std::string ftrace_descriptor_;  // [lazy=true]
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<10> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_CPP_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
+// gen_amalgamated begin header: include/perfetto/tracing/core/trace_config.h
+// gen_amalgamated begin header: gen/protos/perfetto/config/trace_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TraceConfig;
+class TraceConfig_CmdTraceStartDelay;
+class TraceConfig_AndroidReportConfig;
+class TraceConfig_TraceFilter;
+class TraceConfig_TraceFilter_StringFilterChain;
+class TraceConfig_TraceFilter_StringFilterRule;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_ProducerConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_DataSource;
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+class TraceConfig_BufferConfig;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TraceFilter_StringFilterPolicy : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+enum TraceConfig_BufferConfig_FillPolicy : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum TraceConfig_LockdownModeOperation : int {
+  TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED = 0,
+  TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR = 1,
+  TraceConfig_LockdownModeOperation_LOCKDOWN_SET = 2,
+};
+enum TraceConfig_CompressionType : int {
+  TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED = 0,
+  TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE = 1,
+};
+enum TraceConfig_StatsdLogging : int {
+  TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED = 0,
+  TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED = 1,
+  TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED = 2,
+};
+enum TraceConfig_TraceFilter_StringFilterPolicy : int {
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_UNSPECIFIED = 0,
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_REDACT_GROUPS = 1,
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_REDACT_GROUPS = 2,
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_BREAK = 3,
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_BREAK = 4,
+  TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS = 5,
+};
+enum TraceConfig_TriggerConfig_TriggerMode : int {
+  TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
+  TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
+  TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
+  TraceConfig_TriggerConfig_TriggerMode_CLONE_SNAPSHOT = 4,
+};
+enum TraceConfig_BufferConfig_FillPolicy : int {
+  TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
+  TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
+  TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig : public ::protozero::CppMessageObj {
+ public:
+  using BufferConfig = TraceConfig_BufferConfig;
+  using DataSource = TraceConfig_DataSource;
+  using BuiltinDataSource = TraceConfig_BuiltinDataSource;
+  using ProducerConfig = TraceConfig_ProducerConfig;
+  using StatsdMetadata = TraceConfig_StatsdMetadata;
+  using GuardrailOverrides = TraceConfig_GuardrailOverrides;
+  using TriggerConfig = TraceConfig_TriggerConfig;
+  using IncrementalStateConfig = TraceConfig_IncrementalStateConfig;
+  using IncidentReportConfig = TraceConfig_IncidentReportConfig;
+  using TraceFilter = TraceConfig_TraceFilter;
+  using AndroidReportConfig = TraceConfig_AndroidReportConfig;
+  using CmdTraceStartDelay = TraceConfig_CmdTraceStartDelay;
+  using LockdownModeOperation = TraceConfig_LockdownModeOperation;
+  static constexpr auto LOCKDOWN_UNCHANGED = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
+  static constexpr auto LOCKDOWN_CLEAR = TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR;
+  static constexpr auto LOCKDOWN_SET = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
+  static constexpr auto LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
+  static constexpr auto LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
+  using CompressionType = TraceConfig_CompressionType;
+  static constexpr auto COMPRESSION_TYPE_UNSPECIFIED = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
+  static constexpr auto COMPRESSION_TYPE_DEFLATE = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
+  static constexpr auto CompressionType_MIN = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
+  static constexpr auto CompressionType_MAX = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
+  using StatsdLogging = TraceConfig_StatsdLogging;
+  static constexpr auto STATSD_LOGGING_UNSPECIFIED = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
+  static constexpr auto STATSD_LOGGING_ENABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED;
+  static constexpr auto STATSD_LOGGING_DISABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
+  static constexpr auto StatsdLogging_MIN = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
+  static constexpr auto StatsdLogging_MAX = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
+  enum FieldNumbers {
+    kBuffersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    kBuiltinDataSourcesFieldNumber = 20,
+    kDurationMsFieldNumber = 3,
+    kPreferSuspendClockForDurationFieldNumber = 36,
+    kEnableExtraGuardrailsFieldNumber = 4,
+    kLockdownModeFieldNumber = 5,
+    kProducersFieldNumber = 6,
+    kStatsdMetadataFieldNumber = 7,
+    kWriteIntoFileFieldNumber = 8,
+    kOutputPathFieldNumber = 29,
+    kFileWritePeriodMsFieldNumber = 9,
+    kMaxFileSizeBytesFieldNumber = 10,
+    kGuardrailOverridesFieldNumber = 11,
+    kDeferredStartFieldNumber = 12,
+    kFlushPeriodMsFieldNumber = 13,
+    kFlushTimeoutMsFieldNumber = 14,
+    kDataSourceStopTimeoutMsFieldNumber = 23,
+    kNotifyTraceurFieldNumber = 16,
+    kBugreportScoreFieldNumber = 30,
+    kTriggerConfigFieldNumber = 17,
+    kActivateTriggersFieldNumber = 18,
+    kIncrementalStateConfigFieldNumber = 21,
+    kAllowUserBuildTracingFieldNumber = 19,
+    kUniqueSessionNameFieldNumber = 22,
+    kCompressionTypeFieldNumber = 24,
+    kCompressFromCliFieldNumber = 37,
+    kIncidentReportConfigFieldNumber = 25,
+    kStatsdLoggingFieldNumber = 31,
+    kTraceUuidMsbFieldNumber = 27,
+    kTraceUuidLsbFieldNumber = 28,
+    kTraceFilterFieldNumber = 33,
+    kAndroidReportConfigFieldNumber = 34,
+    kCmdTraceStartDelayFieldNumber = 35,
+  };
+
+  TraceConfig();
+  ~TraceConfig() override;
+  TraceConfig(TraceConfig&&) noexcept;
+  TraceConfig& operator=(TraceConfig&&);
+  TraceConfig(const TraceConfig&);
+  TraceConfig& operator=(const TraceConfig&);
+  bool operator==(const TraceConfig&) const;
+  bool operator!=(const TraceConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TraceConfig_BufferConfig>& buffers() const { return buffers_; }
+  std::vector<TraceConfig_BufferConfig>* mutable_buffers() { return &buffers_; }
+  int buffers_size() const;
+  void clear_buffers();
+  TraceConfig_BufferConfig* add_buffers();
+
+  const std::vector<TraceConfig_DataSource>& data_sources() const { return data_sources_; }
+  std::vector<TraceConfig_DataSource>* mutable_data_sources() { return &data_sources_; }
+  int data_sources_size() const;
+  void clear_data_sources();
+  TraceConfig_DataSource* add_data_sources();
+
+  bool has_builtin_data_sources() const { return _has_field_[20]; }
+  const TraceConfig_BuiltinDataSource& builtin_data_sources() const { return *builtin_data_sources_; }
+  TraceConfig_BuiltinDataSource* mutable_builtin_data_sources() { _has_field_.set(20); return builtin_data_sources_.get(); }
+
+  bool has_duration_ms() const { return _has_field_[3]; }
+  uint32_t duration_ms() const { return duration_ms_; }
+  void set_duration_ms(uint32_t value) { duration_ms_ = value; _has_field_.set(3); }
+
+  bool has_prefer_suspend_clock_for_duration() const { return _has_field_[36]; }
+  bool prefer_suspend_clock_for_duration() const { return prefer_suspend_clock_for_duration_; }
+  void set_prefer_suspend_clock_for_duration(bool value) { prefer_suspend_clock_for_duration_ = value; _has_field_.set(36); }
+
+  bool has_enable_extra_guardrails() const { return _has_field_[4]; }
+  bool enable_extra_guardrails() const { return enable_extra_guardrails_; }
+  void set_enable_extra_guardrails(bool value) { enable_extra_guardrails_ = value; _has_field_.set(4); }
+
+  bool has_lockdown_mode() const { return _has_field_[5]; }
+  TraceConfig_LockdownModeOperation lockdown_mode() const { return lockdown_mode_; }
+  void set_lockdown_mode(TraceConfig_LockdownModeOperation value) { lockdown_mode_ = value; _has_field_.set(5); }
+
+  const std::vector<TraceConfig_ProducerConfig>& producers() const { return producers_; }
+  std::vector<TraceConfig_ProducerConfig>* mutable_producers() { return &producers_; }
+  int producers_size() const;
+  void clear_producers();
+  TraceConfig_ProducerConfig* add_producers();
+
+  bool has_statsd_metadata() const { return _has_field_[7]; }
+  const TraceConfig_StatsdMetadata& statsd_metadata() const { return *statsd_metadata_; }
+  TraceConfig_StatsdMetadata* mutable_statsd_metadata() { _has_field_.set(7); return statsd_metadata_.get(); }
+
+  bool has_write_into_file() const { return _has_field_[8]; }
+  bool write_into_file() const { return write_into_file_; }
+  void set_write_into_file(bool value) { write_into_file_ = value; _has_field_.set(8); }
+
+  bool has_output_path() const { return _has_field_[29]; }
+  const std::string& output_path() const { return output_path_; }
+  void set_output_path(const std::string& value) { output_path_ = value; _has_field_.set(29); }
+
+  bool has_file_write_period_ms() const { return _has_field_[9]; }
+  uint32_t file_write_period_ms() const { return file_write_period_ms_; }
+  void set_file_write_period_ms(uint32_t value) { file_write_period_ms_ = value; _has_field_.set(9); }
+
+  bool has_max_file_size_bytes() const { return _has_field_[10]; }
+  uint64_t max_file_size_bytes() const { return max_file_size_bytes_; }
+  void set_max_file_size_bytes(uint64_t value) { max_file_size_bytes_ = value; _has_field_.set(10); }
+
+  bool has_guardrail_overrides() const { return _has_field_[11]; }
+  const TraceConfig_GuardrailOverrides& guardrail_overrides() const { return *guardrail_overrides_; }
+  TraceConfig_GuardrailOverrides* mutable_guardrail_overrides() { _has_field_.set(11); return guardrail_overrides_.get(); }
+
+  bool has_deferred_start() const { return _has_field_[12]; }
+  bool deferred_start() const { return deferred_start_; }
+  void set_deferred_start(bool value) { deferred_start_ = value; _has_field_.set(12); }
+
+  bool has_flush_period_ms() const { return _has_field_[13]; }
+  uint32_t flush_period_ms() const { return flush_period_ms_; }
+  void set_flush_period_ms(uint32_t value) { flush_period_ms_ = value; _has_field_.set(13); }
+
+  bool has_flush_timeout_ms() const { return _has_field_[14]; }
+  uint32_t flush_timeout_ms() const { return flush_timeout_ms_; }
+  void set_flush_timeout_ms(uint32_t value) { flush_timeout_ms_ = value; _has_field_.set(14); }
+
+  bool has_data_source_stop_timeout_ms() const { return _has_field_[23]; }
+  uint32_t data_source_stop_timeout_ms() const { return data_source_stop_timeout_ms_; }
+  void set_data_source_stop_timeout_ms(uint32_t value) { data_source_stop_timeout_ms_ = value; _has_field_.set(23); }
+
+  bool has_notify_traceur() const { return _has_field_[16]; }
+  bool notify_traceur() const { return notify_traceur_; }
+  void set_notify_traceur(bool value) { notify_traceur_ = value; _has_field_.set(16); }
+
+  bool has_bugreport_score() const { return _has_field_[30]; }
+  int32_t bugreport_score() const { return bugreport_score_; }
+  void set_bugreport_score(int32_t value) { bugreport_score_ = value; _has_field_.set(30); }
+
+  bool has_trigger_config() const { return _has_field_[17]; }
+  const TraceConfig_TriggerConfig& trigger_config() const { return *trigger_config_; }
+  TraceConfig_TriggerConfig* mutable_trigger_config() { _has_field_.set(17); return trigger_config_.get(); }
+
+  const std::vector<std::string>& activate_triggers() const { return activate_triggers_; }
+  std::vector<std::string>* mutable_activate_triggers() { return &activate_triggers_; }
+  int activate_triggers_size() const { return static_cast<int>(activate_triggers_.size()); }
+  void clear_activate_triggers() { activate_triggers_.clear(); }
+  void add_activate_triggers(std::string value) { activate_triggers_.emplace_back(value); }
+  std::string* add_activate_triggers() { activate_triggers_.emplace_back(); return &activate_triggers_.back(); }
+
+  bool has_incremental_state_config() const { return _has_field_[21]; }
+  const TraceConfig_IncrementalStateConfig& incremental_state_config() const { return *incremental_state_config_; }
+  TraceConfig_IncrementalStateConfig* mutable_incremental_state_config() { _has_field_.set(21); return incremental_state_config_.get(); }
+
+  bool has_allow_user_build_tracing() const { return _has_field_[19]; }
+  bool allow_user_build_tracing() const { return allow_user_build_tracing_; }
+  void set_allow_user_build_tracing(bool value) { allow_user_build_tracing_ = value; _has_field_.set(19); }
+
+  bool has_unique_session_name() const { return _has_field_[22]; }
+  const std::string& unique_session_name() const { return unique_session_name_; }
+  void set_unique_session_name(const std::string& value) { unique_session_name_ = value; _has_field_.set(22); }
+
+  bool has_compression_type() const { return _has_field_[24]; }
+  TraceConfig_CompressionType compression_type() const { return compression_type_; }
+  void set_compression_type(TraceConfig_CompressionType value) { compression_type_ = value; _has_field_.set(24); }
+
+  bool has_compress_from_cli() const { return _has_field_[37]; }
+  bool compress_from_cli() const { return compress_from_cli_; }
+  void set_compress_from_cli(bool value) { compress_from_cli_ = value; _has_field_.set(37); }
+
+  bool has_incident_report_config() const { return _has_field_[25]; }
+  const TraceConfig_IncidentReportConfig& incident_report_config() const { return *incident_report_config_; }
+  TraceConfig_IncidentReportConfig* mutable_incident_report_config() { _has_field_.set(25); return incident_report_config_.get(); }
+
+  bool has_statsd_logging() const { return _has_field_[31]; }
+  TraceConfig_StatsdLogging statsd_logging() const { return statsd_logging_; }
+  void set_statsd_logging(TraceConfig_StatsdLogging value) { statsd_logging_ = value; _has_field_.set(31); }
+
+  bool has_trace_uuid_msb() const { return _has_field_[27]; }
+  int64_t trace_uuid_msb() const { return trace_uuid_msb_; }
+  void set_trace_uuid_msb(int64_t value) { trace_uuid_msb_ = value; _has_field_.set(27); }
+
+  bool has_trace_uuid_lsb() const { return _has_field_[28]; }
+  int64_t trace_uuid_lsb() const { return trace_uuid_lsb_; }
+  void set_trace_uuid_lsb(int64_t value) { trace_uuid_lsb_ = value; _has_field_.set(28); }
+
+  bool has_trace_filter() const { return _has_field_[33]; }
+  const TraceConfig_TraceFilter& trace_filter() const { return *trace_filter_; }
+  TraceConfig_TraceFilter* mutable_trace_filter() { _has_field_.set(33); return trace_filter_.get(); }
+
+  bool has_android_report_config() const { return _has_field_[34]; }
+  const TraceConfig_AndroidReportConfig& android_report_config() const { return *android_report_config_; }
+  TraceConfig_AndroidReportConfig* mutable_android_report_config() { _has_field_.set(34); return android_report_config_.get(); }
+
+  bool has_cmd_trace_start_delay() const { return _has_field_[35]; }
+  const TraceConfig_CmdTraceStartDelay& cmd_trace_start_delay() const { return *cmd_trace_start_delay_; }
+  TraceConfig_CmdTraceStartDelay* mutable_cmd_trace_start_delay() { _has_field_.set(35); return cmd_trace_start_delay_.get(); }
+
+ private:
+  std::vector<TraceConfig_BufferConfig> buffers_;
+  std::vector<TraceConfig_DataSource> data_sources_;
+  ::protozero::CopyablePtr<TraceConfig_BuiltinDataSource> builtin_data_sources_;
+  uint32_t duration_ms_{};
+  bool prefer_suspend_clock_for_duration_{};
+  bool enable_extra_guardrails_{};
+  TraceConfig_LockdownModeOperation lockdown_mode_{};
+  std::vector<TraceConfig_ProducerConfig> producers_;
+  ::protozero::CopyablePtr<TraceConfig_StatsdMetadata> statsd_metadata_;
+  bool write_into_file_{};
+  std::string output_path_{};
+  uint32_t file_write_period_ms_{};
+  uint64_t max_file_size_bytes_{};
+  ::protozero::CopyablePtr<TraceConfig_GuardrailOverrides> guardrail_overrides_;
+  bool deferred_start_{};
+  uint32_t flush_period_ms_{};
+  uint32_t flush_timeout_ms_{};
+  uint32_t data_source_stop_timeout_ms_{};
+  bool notify_traceur_{};
+  int32_t bugreport_score_{};
+  ::protozero::CopyablePtr<TraceConfig_TriggerConfig> trigger_config_;
+  std::vector<std::string> activate_triggers_;
+  ::protozero::CopyablePtr<TraceConfig_IncrementalStateConfig> incremental_state_config_;
+  bool allow_user_build_tracing_{};
+  std::string unique_session_name_{};
+  TraceConfig_CompressionType compression_type_{};
+  bool compress_from_cli_{};
+  ::protozero::CopyablePtr<TraceConfig_IncidentReportConfig> incident_report_config_;
+  TraceConfig_StatsdLogging statsd_logging_{};
+  int64_t trace_uuid_msb_{};
+  int64_t trace_uuid_lsb_{};
+  ::protozero::CopyablePtr<TraceConfig_TraceFilter> trace_filter_;
+  ::protozero::CopyablePtr<TraceConfig_AndroidReportConfig> android_report_config_;
+  ::protozero::CopyablePtr<TraceConfig_CmdTraceStartDelay> cmd_trace_start_delay_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<38> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_CmdTraceStartDelay : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kMinDelayMsFieldNumber = 1,
+    kMaxDelayMsFieldNumber = 2,
+  };
+
+  TraceConfig_CmdTraceStartDelay();
+  ~TraceConfig_CmdTraceStartDelay() override;
+  TraceConfig_CmdTraceStartDelay(TraceConfig_CmdTraceStartDelay&&) noexcept;
+  TraceConfig_CmdTraceStartDelay& operator=(TraceConfig_CmdTraceStartDelay&&);
+  TraceConfig_CmdTraceStartDelay(const TraceConfig_CmdTraceStartDelay&);
+  TraceConfig_CmdTraceStartDelay& operator=(const TraceConfig_CmdTraceStartDelay&);
+  bool operator==(const TraceConfig_CmdTraceStartDelay&) const;
+  bool operator!=(const TraceConfig_CmdTraceStartDelay& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_min_delay_ms() const { return _has_field_[1]; }
+  uint32_t min_delay_ms() const { return min_delay_ms_; }
+  void set_min_delay_ms(uint32_t value) { min_delay_ms_ = value; _has_field_.set(1); }
+
+  bool has_max_delay_ms() const { return _has_field_[2]; }
+  uint32_t max_delay_ms() const { return max_delay_ms_; }
+  void set_max_delay_ms(uint32_t value) { max_delay_ms_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t min_delay_ms_{};
+  uint32_t max_delay_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_AndroidReportConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kReporterServicePackageFieldNumber = 1,
+    kReporterServiceClassFieldNumber = 2,
+    kSkipReportFieldNumber = 3,
+    kUsePipeInFrameworkForTestingFieldNumber = 4,
+  };
+
+  TraceConfig_AndroidReportConfig();
+  ~TraceConfig_AndroidReportConfig() override;
+  TraceConfig_AndroidReportConfig(TraceConfig_AndroidReportConfig&&) noexcept;
+  TraceConfig_AndroidReportConfig& operator=(TraceConfig_AndroidReportConfig&&);
+  TraceConfig_AndroidReportConfig(const TraceConfig_AndroidReportConfig&);
+  TraceConfig_AndroidReportConfig& operator=(const TraceConfig_AndroidReportConfig&);
+  bool operator==(const TraceConfig_AndroidReportConfig&) const;
+  bool operator!=(const TraceConfig_AndroidReportConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_reporter_service_package() const { return _has_field_[1]; }
+  const std::string& reporter_service_package() const { return reporter_service_package_; }
+  void set_reporter_service_package(const std::string& value) { reporter_service_package_ = value; _has_field_.set(1); }
+
+  bool has_reporter_service_class() const { return _has_field_[2]; }
+  const std::string& reporter_service_class() const { return reporter_service_class_; }
+  void set_reporter_service_class(const std::string& value) { reporter_service_class_ = value; _has_field_.set(2); }
+
+  bool has_skip_report() const { return _has_field_[3]; }
+  bool skip_report() const { return skip_report_; }
+  void set_skip_report(bool value) { skip_report_ = value; _has_field_.set(3); }
+
+  bool has_use_pipe_in_framework_for_testing() const { return _has_field_[4]; }
+  bool use_pipe_in_framework_for_testing() const { return use_pipe_in_framework_for_testing_; }
+  void set_use_pipe_in_framework_for_testing(bool value) { use_pipe_in_framework_for_testing_ = value; _has_field_.set(4); }
+
+ private:
+  std::string reporter_service_package_{};
+  std::string reporter_service_class_{};
+  bool skip_report_{};
+  bool use_pipe_in_framework_for_testing_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_TraceFilter : public ::protozero::CppMessageObj {
+ public:
+  using StringFilterRule = TraceConfig_TraceFilter_StringFilterRule;
+  using StringFilterChain = TraceConfig_TraceFilter_StringFilterChain;
+  using StringFilterPolicy = TraceConfig_TraceFilter_StringFilterPolicy;
+  static constexpr auto SFP_UNSPECIFIED = TraceConfig_TraceFilter_StringFilterPolicy_SFP_UNSPECIFIED;
+  static constexpr auto SFP_MATCH_REDACT_GROUPS = TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_REDACT_GROUPS;
+  static constexpr auto SFP_ATRACE_MATCH_REDACT_GROUPS = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_REDACT_GROUPS;
+  static constexpr auto SFP_MATCH_BREAK = TraceConfig_TraceFilter_StringFilterPolicy_SFP_MATCH_BREAK;
+  static constexpr auto SFP_ATRACE_MATCH_BREAK = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_MATCH_BREAK;
+  static constexpr auto SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS;
+  static constexpr auto StringFilterPolicy_MIN = TraceConfig_TraceFilter_StringFilterPolicy_SFP_UNSPECIFIED;
+  static constexpr auto StringFilterPolicy_MAX = TraceConfig_TraceFilter_StringFilterPolicy_SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS;
+  enum FieldNumbers {
+    kBytecodeFieldNumber = 1,
+    kBytecodeV2FieldNumber = 2,
+    kStringFilterChainFieldNumber = 3,
+  };
+
+  TraceConfig_TraceFilter();
+  ~TraceConfig_TraceFilter() override;
+  TraceConfig_TraceFilter(TraceConfig_TraceFilter&&) noexcept;
+  TraceConfig_TraceFilter& operator=(TraceConfig_TraceFilter&&);
+  TraceConfig_TraceFilter(const TraceConfig_TraceFilter&);
+  TraceConfig_TraceFilter& operator=(const TraceConfig_TraceFilter&);
+  bool operator==(const TraceConfig_TraceFilter&) const;
+  bool operator!=(const TraceConfig_TraceFilter& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_bytecode() const { return _has_field_[1]; }
+  const std::string& bytecode() const { return bytecode_; }
+  void set_bytecode(const std::string& value) { bytecode_ = value; _has_field_.set(1); }
+  void set_bytecode(const void* p, size_t s) { bytecode_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(1); }
+
+  bool has_bytecode_v2() const { return _has_field_[2]; }
+  const std::string& bytecode_v2() const { return bytecode_v2_; }
+  void set_bytecode_v2(const std::string& value) { bytecode_v2_ = value; _has_field_.set(2); }
+  void set_bytecode_v2(const void* p, size_t s) { bytecode_v2_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
+
+  bool has_string_filter_chain() const { return _has_field_[3]; }
+  const TraceConfig_TraceFilter_StringFilterChain& string_filter_chain() const { return *string_filter_chain_; }
+  TraceConfig_TraceFilter_StringFilterChain* mutable_string_filter_chain() { _has_field_.set(3); return string_filter_chain_.get(); }
+
+ private:
+  std::string bytecode_{};
+  std::string bytecode_v2_{};
+  ::protozero::CopyablePtr<TraceConfig_TraceFilter_StringFilterChain> string_filter_chain_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_TraceFilter_StringFilterChain : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kRulesFieldNumber = 1,
+  };
+
+  TraceConfig_TraceFilter_StringFilterChain();
+  ~TraceConfig_TraceFilter_StringFilterChain() override;
+  TraceConfig_TraceFilter_StringFilterChain(TraceConfig_TraceFilter_StringFilterChain&&) noexcept;
+  TraceConfig_TraceFilter_StringFilterChain& operator=(TraceConfig_TraceFilter_StringFilterChain&&);
+  TraceConfig_TraceFilter_StringFilterChain(const TraceConfig_TraceFilter_StringFilterChain&);
+  TraceConfig_TraceFilter_StringFilterChain& operator=(const TraceConfig_TraceFilter_StringFilterChain&);
+  bool operator==(const TraceConfig_TraceFilter_StringFilterChain&) const;
+  bool operator!=(const TraceConfig_TraceFilter_StringFilterChain& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TraceConfig_TraceFilter_StringFilterRule>& rules() const { return rules_; }
+  std::vector<TraceConfig_TraceFilter_StringFilterRule>* mutable_rules() { return &rules_; }
+  int rules_size() const;
+  void clear_rules();
+  TraceConfig_TraceFilter_StringFilterRule* add_rules();
+
+ private:
+  std::vector<TraceConfig_TraceFilter_StringFilterRule> rules_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_TraceFilter_StringFilterRule : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPolicyFieldNumber = 1,
+    kRegexPatternFieldNumber = 2,
+    kAtracePayloadStartsWithFieldNumber = 3,
+  };
+
+  TraceConfig_TraceFilter_StringFilterRule();
+  ~TraceConfig_TraceFilter_StringFilterRule() override;
+  TraceConfig_TraceFilter_StringFilterRule(TraceConfig_TraceFilter_StringFilterRule&&) noexcept;
+  TraceConfig_TraceFilter_StringFilterRule& operator=(TraceConfig_TraceFilter_StringFilterRule&&);
+  TraceConfig_TraceFilter_StringFilterRule(const TraceConfig_TraceFilter_StringFilterRule&);
+  TraceConfig_TraceFilter_StringFilterRule& operator=(const TraceConfig_TraceFilter_StringFilterRule&);
+  bool operator==(const TraceConfig_TraceFilter_StringFilterRule&) const;
+  bool operator!=(const TraceConfig_TraceFilter_StringFilterRule& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_policy() const { return _has_field_[1]; }
+  TraceConfig_TraceFilter_StringFilterPolicy policy() const { return policy_; }
+  void set_policy(TraceConfig_TraceFilter_StringFilterPolicy value) { policy_ = value; _has_field_.set(1); }
+
+  bool has_regex_pattern() const { return _has_field_[2]; }
+  const std::string& regex_pattern() const { return regex_pattern_; }
+  void set_regex_pattern(const std::string& value) { regex_pattern_ = value; _has_field_.set(2); }
+
+  bool has_atrace_payload_starts_with() const { return _has_field_[3]; }
+  const std::string& atrace_payload_starts_with() const { return atrace_payload_starts_with_; }
+  void set_atrace_payload_starts_with(const std::string& value) { atrace_payload_starts_with_ = value; _has_field_.set(3); }
+
+ private:
+  TraceConfig_TraceFilter_StringFilterPolicy policy_{};
+  std::string regex_pattern_{};
+  std::string atrace_payload_starts_with_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_IncidentReportConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDestinationPackageFieldNumber = 1,
+    kDestinationClassFieldNumber = 2,
+    kPrivacyLevelFieldNumber = 3,
+    kSkipIncidentdFieldNumber = 5,
+    kSkipDropboxFieldNumber = 4,
+  };
+
+  TraceConfig_IncidentReportConfig();
+  ~TraceConfig_IncidentReportConfig() override;
+  TraceConfig_IncidentReportConfig(TraceConfig_IncidentReportConfig&&) noexcept;
+  TraceConfig_IncidentReportConfig& operator=(TraceConfig_IncidentReportConfig&&);
+  TraceConfig_IncidentReportConfig(const TraceConfig_IncidentReportConfig&);
+  TraceConfig_IncidentReportConfig& operator=(const TraceConfig_IncidentReportConfig&);
+  bool operator==(const TraceConfig_IncidentReportConfig&) const;
+  bool operator!=(const TraceConfig_IncidentReportConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_destination_package() const { return _has_field_[1]; }
+  const std::string& destination_package() const { return destination_package_; }
+  void set_destination_package(const std::string& value) { destination_package_ = value; _has_field_.set(1); }
+
+  bool has_destination_class() const { return _has_field_[2]; }
+  const std::string& destination_class() const { return destination_class_; }
+  void set_destination_class(const std::string& value) { destination_class_ = value; _has_field_.set(2); }
+
+  bool has_privacy_level() const { return _has_field_[3]; }
+  int32_t privacy_level() const { return privacy_level_; }
+  void set_privacy_level(int32_t value) { privacy_level_ = value; _has_field_.set(3); }
+
+  bool has_skip_incidentd() const { return _has_field_[5]; }
+  bool skip_incidentd() const { return skip_incidentd_; }
+  void set_skip_incidentd(bool value) { skip_incidentd_ = value; _has_field_.set(5); }
+
+  bool has_skip_dropbox() const { return _has_field_[4]; }
+  bool skip_dropbox() const { return skip_dropbox_; }
+  void set_skip_dropbox(bool value) { skip_dropbox_ = value; _has_field_.set(4); }
+
+ private:
+  std::string destination_package_{};
+  std::string destination_class_{};
+  int32_t privacy_level_{};
+  bool skip_incidentd_{};
+  bool skip_dropbox_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_IncrementalStateConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kClearPeriodMsFieldNumber = 1,
+  };
+
+  TraceConfig_IncrementalStateConfig();
+  ~TraceConfig_IncrementalStateConfig() override;
+  TraceConfig_IncrementalStateConfig(TraceConfig_IncrementalStateConfig&&) noexcept;
+  TraceConfig_IncrementalStateConfig& operator=(TraceConfig_IncrementalStateConfig&&);
+  TraceConfig_IncrementalStateConfig(const TraceConfig_IncrementalStateConfig&);
+  TraceConfig_IncrementalStateConfig& operator=(const TraceConfig_IncrementalStateConfig&);
+  bool operator==(const TraceConfig_IncrementalStateConfig&) const;
+  bool operator!=(const TraceConfig_IncrementalStateConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_clear_period_ms() const { return _has_field_[1]; }
+  uint32_t clear_period_ms() const { return clear_period_ms_; }
+  void set_clear_period_ms(uint32_t value) { clear_period_ms_ = value; _has_field_.set(1); }
+
+ private:
+  uint32_t clear_period_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_TriggerConfig : public ::protozero::CppMessageObj {
+ public:
+  using Trigger = TraceConfig_TriggerConfig_Trigger;
+  using TriggerMode = TraceConfig_TriggerConfig_TriggerMode;
+  static constexpr auto UNSPECIFIED = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
+  static constexpr auto START_TRACING = TraceConfig_TriggerConfig_TriggerMode_START_TRACING;
+  static constexpr auto STOP_TRACING = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
+  static constexpr auto CLONE_SNAPSHOT = TraceConfig_TriggerConfig_TriggerMode_CLONE_SNAPSHOT;
+  static constexpr auto TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
+  static constexpr auto TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_CLONE_SNAPSHOT;
+  enum FieldNumbers {
+    kTriggerModeFieldNumber = 1,
+    kUseCloneSnapshotIfAvailableFieldNumber = 5,
+    kTriggersFieldNumber = 2,
+    kTriggerTimeoutMsFieldNumber = 3,
+  };
+
+  TraceConfig_TriggerConfig();
+  ~TraceConfig_TriggerConfig() override;
+  TraceConfig_TriggerConfig(TraceConfig_TriggerConfig&&) noexcept;
+  TraceConfig_TriggerConfig& operator=(TraceConfig_TriggerConfig&&);
+  TraceConfig_TriggerConfig(const TraceConfig_TriggerConfig&);
+  TraceConfig_TriggerConfig& operator=(const TraceConfig_TriggerConfig&);
+  bool operator==(const TraceConfig_TriggerConfig&) const;
+  bool operator!=(const TraceConfig_TriggerConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trigger_mode() const { return _has_field_[1]; }
+  TraceConfig_TriggerConfig_TriggerMode trigger_mode() const { return trigger_mode_; }
+  void set_trigger_mode(TraceConfig_TriggerConfig_TriggerMode value) { trigger_mode_ = value; _has_field_.set(1); }
+
+  bool has_use_clone_snapshot_if_available() const { return _has_field_[5]; }
+  bool use_clone_snapshot_if_available() const { return use_clone_snapshot_if_available_; }
+  void set_use_clone_snapshot_if_available(bool value) { use_clone_snapshot_if_available_ = value; _has_field_.set(5); }
+
+  const std::vector<TraceConfig_TriggerConfig_Trigger>& triggers() const { return triggers_; }
+  std::vector<TraceConfig_TriggerConfig_Trigger>* mutable_triggers() { return &triggers_; }
+  int triggers_size() const;
+  void clear_triggers();
+  TraceConfig_TriggerConfig_Trigger* add_triggers();
+
+  bool has_trigger_timeout_ms() const { return _has_field_[3]; }
+  uint32_t trigger_timeout_ms() const { return trigger_timeout_ms_; }
+  void set_trigger_timeout_ms(uint32_t value) { trigger_timeout_ms_ = value; _has_field_.set(3); }
+
+ private:
+  TraceConfig_TriggerConfig_TriggerMode trigger_mode_{};
+  bool use_clone_snapshot_if_available_{};
+  std::vector<TraceConfig_TriggerConfig_Trigger> triggers_;
+  uint32_t trigger_timeout_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_TriggerConfig_Trigger : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kProducerNameRegexFieldNumber = 2,
+    kStopDelayMsFieldNumber = 3,
+    kMaxPer24HFieldNumber = 4,
+    kSkipProbabilityFieldNumber = 5,
+  };
+
+  TraceConfig_TriggerConfig_Trigger();
+  ~TraceConfig_TriggerConfig_Trigger() override;
+  TraceConfig_TriggerConfig_Trigger(TraceConfig_TriggerConfig_Trigger&&) noexcept;
+  TraceConfig_TriggerConfig_Trigger& operator=(TraceConfig_TriggerConfig_Trigger&&);
+  TraceConfig_TriggerConfig_Trigger(const TraceConfig_TriggerConfig_Trigger&);
+  TraceConfig_TriggerConfig_Trigger& operator=(const TraceConfig_TriggerConfig_Trigger&);
+  bool operator==(const TraceConfig_TriggerConfig_Trigger&) const;
+  bool operator!=(const TraceConfig_TriggerConfig_Trigger& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_producer_name_regex() const { return _has_field_[2]; }
+  const std::string& producer_name_regex() const { return producer_name_regex_; }
+  void set_producer_name_regex(const std::string& value) { producer_name_regex_ = value; _has_field_.set(2); }
+
+  bool has_stop_delay_ms() const { return _has_field_[3]; }
+  uint32_t stop_delay_ms() const { return stop_delay_ms_; }
+  void set_stop_delay_ms(uint32_t value) { stop_delay_ms_ = value; _has_field_.set(3); }
+
+  bool has_max_per_24_h() const { return _has_field_[4]; }
+  uint32_t max_per_24_h() const { return max_per_24_h_; }
+  void set_max_per_24_h(uint32_t value) { max_per_24_h_ = value; _has_field_.set(4); }
+
+  bool has_skip_probability() const { return _has_field_[5]; }
+  double skip_probability() const { return skip_probability_; }
+  void set_skip_probability(double value) { skip_probability_ = value; _has_field_.set(5); }
+
+ private:
+  std::string name_{};
+  std::string producer_name_regex_{};
+  uint32_t stop_delay_ms_{};
+  uint32_t max_per_24_h_{};
+  double skip_probability_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_GuardrailOverrides : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kMaxUploadPerDayBytesFieldNumber = 1,
+    kMaxTracingBufferSizeKbFieldNumber = 2,
+  };
+
+  TraceConfig_GuardrailOverrides();
+  ~TraceConfig_GuardrailOverrides() override;
+  TraceConfig_GuardrailOverrides(TraceConfig_GuardrailOverrides&&) noexcept;
+  TraceConfig_GuardrailOverrides& operator=(TraceConfig_GuardrailOverrides&&);
+  TraceConfig_GuardrailOverrides(const TraceConfig_GuardrailOverrides&);
+  TraceConfig_GuardrailOverrides& operator=(const TraceConfig_GuardrailOverrides&);
+  bool operator==(const TraceConfig_GuardrailOverrides&) const;
+  bool operator!=(const TraceConfig_GuardrailOverrides& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_max_upload_per_day_bytes() const { return _has_field_[1]; }
+  uint64_t max_upload_per_day_bytes() const { return max_upload_per_day_bytes_; }
+  void set_max_upload_per_day_bytes(uint64_t value) { max_upload_per_day_bytes_ = value; _has_field_.set(1); }
+
+  bool has_max_tracing_buffer_size_kb() const { return _has_field_[2]; }
+  uint32_t max_tracing_buffer_size_kb() const { return max_tracing_buffer_size_kb_; }
+  void set_max_tracing_buffer_size_kb(uint32_t value) { max_tracing_buffer_size_kb_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t max_upload_per_day_bytes_{};
+  uint32_t max_tracing_buffer_size_kb_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_StatsdMetadata : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTriggeringAlertIdFieldNumber = 1,
+    kTriggeringConfigUidFieldNumber = 2,
+    kTriggeringConfigIdFieldNumber = 3,
+    kTriggeringSubscriptionIdFieldNumber = 4,
+  };
+
+  TraceConfig_StatsdMetadata();
+  ~TraceConfig_StatsdMetadata() override;
+  TraceConfig_StatsdMetadata(TraceConfig_StatsdMetadata&&) noexcept;
+  TraceConfig_StatsdMetadata& operator=(TraceConfig_StatsdMetadata&&);
+  TraceConfig_StatsdMetadata(const TraceConfig_StatsdMetadata&);
+  TraceConfig_StatsdMetadata& operator=(const TraceConfig_StatsdMetadata&);
+  bool operator==(const TraceConfig_StatsdMetadata&) const;
+  bool operator!=(const TraceConfig_StatsdMetadata& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_triggering_alert_id() const { return _has_field_[1]; }
+  int64_t triggering_alert_id() const { return triggering_alert_id_; }
+  void set_triggering_alert_id(int64_t value) { triggering_alert_id_ = value; _has_field_.set(1); }
+
+  bool has_triggering_config_uid() const { return _has_field_[2]; }
+  int32_t triggering_config_uid() const { return triggering_config_uid_; }
+  void set_triggering_config_uid(int32_t value) { triggering_config_uid_ = value; _has_field_.set(2); }
+
+  bool has_triggering_config_id() const { return _has_field_[3]; }
+  int64_t triggering_config_id() const { return triggering_config_id_; }
+  void set_triggering_config_id(int64_t value) { triggering_config_id_ = value; _has_field_.set(3); }
+
+  bool has_triggering_subscription_id() const { return _has_field_[4]; }
+  int64_t triggering_subscription_id() const { return triggering_subscription_id_; }
+  void set_triggering_subscription_id(int64_t value) { triggering_subscription_id_ = value; _has_field_.set(4); }
+
+ private:
+  int64_t triggering_alert_id_{};
+  int32_t triggering_config_uid_{};
+  int64_t triggering_config_id_{};
+  int64_t triggering_subscription_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_ProducerConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kProducerNameFieldNumber = 1,
+    kShmSizeKbFieldNumber = 2,
+    kPageSizeKbFieldNumber = 3,
+  };
+
+  TraceConfig_ProducerConfig();
+  ~TraceConfig_ProducerConfig() override;
+  TraceConfig_ProducerConfig(TraceConfig_ProducerConfig&&) noexcept;
+  TraceConfig_ProducerConfig& operator=(TraceConfig_ProducerConfig&&);
+  TraceConfig_ProducerConfig(const TraceConfig_ProducerConfig&);
+  TraceConfig_ProducerConfig& operator=(const TraceConfig_ProducerConfig&);
+  bool operator==(const TraceConfig_ProducerConfig&) const;
+  bool operator!=(const TraceConfig_ProducerConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_producer_name() const { return _has_field_[1]; }
+  const std::string& producer_name() const { return producer_name_; }
+  void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(1); }
+
+  bool has_shm_size_kb() const { return _has_field_[2]; }
+  uint32_t shm_size_kb() const { return shm_size_kb_; }
+  void set_shm_size_kb(uint32_t value) { shm_size_kb_ = value; _has_field_.set(2); }
+
+  bool has_page_size_kb() const { return _has_field_[3]; }
+  uint32_t page_size_kb() const { return page_size_kb_; }
+  void set_page_size_kb(uint32_t value) { page_size_kb_ = value; _has_field_.set(3); }
+
+ private:
+  std::string producer_name_{};
+  uint32_t shm_size_kb_{};
+  uint32_t page_size_kb_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_BuiltinDataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDisableClockSnapshottingFieldNumber = 1,
+    kDisableTraceConfigFieldNumber = 2,
+    kDisableSystemInfoFieldNumber = 3,
+    kDisableServiceEventsFieldNumber = 4,
+    kPrimaryTraceClockFieldNumber = 5,
+    kSnapshotIntervalMsFieldNumber = 6,
+    kPreferSuspendClockForSnapshotFieldNumber = 7,
+    kDisableChunkUsageHistogramsFieldNumber = 8,
+  };
+
+  TraceConfig_BuiltinDataSource();
+  ~TraceConfig_BuiltinDataSource() override;
+  TraceConfig_BuiltinDataSource(TraceConfig_BuiltinDataSource&&) noexcept;
+  TraceConfig_BuiltinDataSource& operator=(TraceConfig_BuiltinDataSource&&);
+  TraceConfig_BuiltinDataSource(const TraceConfig_BuiltinDataSource&);
+  TraceConfig_BuiltinDataSource& operator=(const TraceConfig_BuiltinDataSource&);
+  bool operator==(const TraceConfig_BuiltinDataSource&) const;
+  bool operator!=(const TraceConfig_BuiltinDataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_disable_clock_snapshotting() const { return _has_field_[1]; }
+  bool disable_clock_snapshotting() const { return disable_clock_snapshotting_; }
+  void set_disable_clock_snapshotting(bool value) { disable_clock_snapshotting_ = value; _has_field_.set(1); }
+
+  bool has_disable_trace_config() const { return _has_field_[2]; }
+  bool disable_trace_config() const { return disable_trace_config_; }
+  void set_disable_trace_config(bool value) { disable_trace_config_ = value; _has_field_.set(2); }
+
+  bool has_disable_system_info() const { return _has_field_[3]; }
+  bool disable_system_info() const { return disable_system_info_; }
+  void set_disable_system_info(bool value) { disable_system_info_ = value; _has_field_.set(3); }
+
+  bool has_disable_service_events() const { return _has_field_[4]; }
+  bool disable_service_events() const { return disable_service_events_; }
+  void set_disable_service_events(bool value) { disable_service_events_ = value; _has_field_.set(4); }
+
+  bool has_primary_trace_clock() const { return _has_field_[5]; }
+  BuiltinClock primary_trace_clock() const { return primary_trace_clock_; }
+  void set_primary_trace_clock(BuiltinClock value) { primary_trace_clock_ = value; _has_field_.set(5); }
+
+  bool has_snapshot_interval_ms() const { return _has_field_[6]; }
+  uint32_t snapshot_interval_ms() const { return snapshot_interval_ms_; }
+  void set_snapshot_interval_ms(uint32_t value) { snapshot_interval_ms_ = value; _has_field_.set(6); }
+
+  bool has_prefer_suspend_clock_for_snapshot() const { return _has_field_[7]; }
+  bool prefer_suspend_clock_for_snapshot() const { return prefer_suspend_clock_for_snapshot_; }
+  void set_prefer_suspend_clock_for_snapshot(bool value) { prefer_suspend_clock_for_snapshot_ = value; _has_field_.set(7); }
+
+  bool has_disable_chunk_usage_histograms() const { return _has_field_[8]; }
+  bool disable_chunk_usage_histograms() const { return disable_chunk_usage_histograms_; }
+  void set_disable_chunk_usage_histograms(bool value) { disable_chunk_usage_histograms_ = value; _has_field_.set(8); }
+
+ private:
+  bool disable_clock_snapshotting_{};
+  bool disable_trace_config_{};
+  bool disable_system_info_{};
+  bool disable_service_events_{};
+  BuiltinClock primary_trace_clock_{};
+  uint32_t snapshot_interval_ms_{};
+  bool prefer_suspend_clock_for_snapshot_{};
+  bool disable_chunk_usage_histograms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_DataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kConfigFieldNumber = 1,
+    kProducerNameFilterFieldNumber = 2,
+    kProducerNameRegexFilterFieldNumber = 3,
+  };
+
+  TraceConfig_DataSource();
+  ~TraceConfig_DataSource() override;
+  TraceConfig_DataSource(TraceConfig_DataSource&&) noexcept;
+  TraceConfig_DataSource& operator=(TraceConfig_DataSource&&);
+  TraceConfig_DataSource(const TraceConfig_DataSource&);
+  TraceConfig_DataSource& operator=(const TraceConfig_DataSource&);
+  bool operator==(const TraceConfig_DataSource&) const;
+  bool operator!=(const TraceConfig_DataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_config() const { return _has_field_[1]; }
+  const DataSourceConfig& config() const { return *config_; }
+  DataSourceConfig* mutable_config() { _has_field_.set(1); return config_.get(); }
+
+  const std::vector<std::string>& producer_name_filter() const { return producer_name_filter_; }
+  std::vector<std::string>* mutable_producer_name_filter() { return &producer_name_filter_; }
+  int producer_name_filter_size() const { return static_cast<int>(producer_name_filter_.size()); }
+  void clear_producer_name_filter() { producer_name_filter_.clear(); }
+  void add_producer_name_filter(std::string value) { producer_name_filter_.emplace_back(value); }
+  std::string* add_producer_name_filter() { producer_name_filter_.emplace_back(); return &producer_name_filter_.back(); }
+
+  const std::vector<std::string>& producer_name_regex_filter() const { return producer_name_regex_filter_; }
+  std::vector<std::string>* mutable_producer_name_regex_filter() { return &producer_name_regex_filter_; }
+  int producer_name_regex_filter_size() const { return static_cast<int>(producer_name_regex_filter_.size()); }
+  void clear_producer_name_regex_filter() { producer_name_regex_filter_.clear(); }
+  void add_producer_name_regex_filter(std::string value) { producer_name_regex_filter_.emplace_back(value); }
+  std::string* add_producer_name_regex_filter() { producer_name_regex_filter_.emplace_back(); return &producer_name_regex_filter_.back(); }
+
+ private:
+  ::protozero::CopyablePtr<DataSourceConfig> config_;
+  std::vector<std::string> producer_name_filter_;
+  std::vector<std::string> producer_name_regex_filter_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceConfig_BufferConfig : public ::protozero::CppMessageObj {
+ public:
+  using FillPolicy = TraceConfig_BufferConfig_FillPolicy;
+  static constexpr auto UNSPECIFIED = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
+  static constexpr auto RING_BUFFER = TraceConfig_BufferConfig_FillPolicy_RING_BUFFER;
+  static constexpr auto DISCARD = TraceConfig_BufferConfig_FillPolicy_DISCARD;
+  static constexpr auto FillPolicy_MIN = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
+  static constexpr auto FillPolicy_MAX = TraceConfig_BufferConfig_FillPolicy_DISCARD;
+  enum FieldNumbers {
+    kSizeKbFieldNumber = 1,
+    kFillPolicyFieldNumber = 4,
+    kTransferOnCloneFieldNumber = 5,
+    kClearBeforeCloneFieldNumber = 6,
+  };
+
+  TraceConfig_BufferConfig();
+  ~TraceConfig_BufferConfig() override;
+  TraceConfig_BufferConfig(TraceConfig_BufferConfig&&) noexcept;
+  TraceConfig_BufferConfig& operator=(TraceConfig_BufferConfig&&);
+  TraceConfig_BufferConfig(const TraceConfig_BufferConfig&);
+  TraceConfig_BufferConfig& operator=(const TraceConfig_BufferConfig&);
+  bool operator==(const TraceConfig_BufferConfig&) const;
+  bool operator!=(const TraceConfig_BufferConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_size_kb() const { return _has_field_[1]; }
+  uint32_t size_kb() const { return size_kb_; }
+  void set_size_kb(uint32_t value) { size_kb_ = value; _has_field_.set(1); }
+
+  bool has_fill_policy() const { return _has_field_[4]; }
+  TraceConfig_BufferConfig_FillPolicy fill_policy() const { return fill_policy_; }
+  void set_fill_policy(TraceConfig_BufferConfig_FillPolicy value) { fill_policy_ = value; _has_field_.set(4); }
+
+  bool has_transfer_on_clone() const { return _has_field_[5]; }
+  bool transfer_on_clone() const { return transfer_on_clone_; }
+  void set_transfer_on_clone(bool value) { transfer_on_clone_ = value; _has_field_.set(5); }
+
+  bool has_clear_before_clone() const { return _has_field_[6]; }
+  bool clear_before_clone() const { return clear_before_clone_; }
+  void set_clear_before_clone(bool value) { clear_before_clone_ = value; _has_field_.set(6); }
+
+ private:
+  uint32_t size_kb_{};
+  TraceConfig_BufferConfig_FillPolicy fill_policy_{};
+  bool transfer_on_clone_{};
+  bool clear_before_clone_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_CPP_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACE_CONFIG_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_TRACE_CONFIG_H_
+
+// Creates the aliases in the ::perfetto namespace, doing things like:
+// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
+// See comments in forward_decls.h for the historical reasons of this
+// indirection layer.
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
+
+namespace perfetto {
+
+inline TraceConfig::TriggerConfig::TriggerMode GetTriggerMode(
+    const TraceConfig& cfg) {
+  auto mode = cfg.trigger_config().trigger_mode();
+  if (cfg.trigger_config().use_clone_snapshot_if_available())
+    mode = TraceConfig::TriggerConfig::CLONE_SNAPSHOT;
+  return mode;
+}
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACE_CONFIG_H_
+// gen_amalgamated begin header: include/perfetto/tracing/data_source.h
+// gen_amalgamated begin header: include/perfetto/tracing/core/flush_flags.h
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_FLUSH_FLAGS_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_FLUSH_FLAGS_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace perfetto {
+
+// This class is a wrapper around the uint64_t flags that are sent across the
+// tracing protocol whenenver a flush occurs. It helps determining the reason
+// and initiator of the flush.
+// NOTE: the values here are part of the tracing protocol ABI. Do not renumber.
+class FlushFlags {
+ public:
+  enum class Initiator : uint64_t {
+    // DO NOT RENUMBER, ABI.
+    kUnknown = 0,
+    kTraced = 1,
+    kPerfettoCmd = 2,
+    kConsumerSdk = 3,
+    kMax,
+  };
+
+  enum class Reason : uint64_t {
+    // DO NOT RENUMBER, ABI.
+    kUnknown = 0,
+    kPeriodic = 1,
+    kTraceStop = 2,
+    kTraceClone = 3,
+    kExplicit = 4,
+    kMax,
+  };
+
+  enum class CloneTarget : uint64_t {
+    // DO NOT RENUMBER, ABI.
+    kUnknown = 0,
+    kBugreport = 1,
+    kMax,
+  };
+
+  explicit FlushFlags(uint64_t flags = 0) : flags_(flags) {}
+  FlushFlags(Initiator i, Reason r, CloneTarget c = CloneTarget::kUnknown)
+      : flags_((static_cast<uint64_t>(i) << kInitiatorShift) |
+               (static_cast<uint64_t>(r) << kReasonShift) |
+               (static_cast<uint64_t>(c) << kCloneTargetShift)) {}
+
+  bool operator==(const FlushFlags& o) const { return flags_ == o.flags_; }
+  bool operator!=(const FlushFlags& o) const { return !(*this == o); }
+
+  Initiator initiator() const {
+    // Due to version mismatch we might see a value from the future that we
+    // didn't know yet. If that happens, short ciruit to kUnknown.
+    static_assert(
+        uint64_t(Initiator::kMax) - 1 <= (kInitiatorMask >> kInitiatorShift),
+        "enum out of range");
+    const uint64_t value = (flags_ & kInitiatorMask) >> kInitiatorShift;
+    return value < uint64_t(Initiator::kMax) ? Initiator(value)
+                                             : Initiator::kUnknown;
+  }
+
+  Reason reason() const {
+    static_assert(uint64_t(Reason::kMax) - 1 <= (kReasonMask >> kReasonShift),
+                  "enum out of range");
+    const uint64_t value = (flags_ & kReasonMask) >> kReasonShift;
+    return value < uint64_t(Reason::kMax) ? Reason(value) : Reason::kUnknown;
+  }
+
+  CloneTarget clone_target() const {
+    static_assert(uint64_t(CloneTarget::kMax) - 1 <=
+                      (kCloneTargetMask >> kCloneTargetShift),
+                  "enum out of range");
+    const uint64_t value = (flags_ & kCloneTargetMask) >> kCloneTargetShift;
+    return value < uint64_t(CloneTarget::kMax) ? CloneTarget(value)
+                                               : CloneTarget::kUnknown;
+  }
+
+  uint64_t flags() const { return flags_; }
+
+ private:
+  // DO NOT CHANGE, ABI.
+  static constexpr uint64_t kReasonMask = 0xF;
+  static constexpr uint64_t kReasonShift = 0;
+  static constexpr uint64_t kInitiatorMask = 0xF0;
+  static constexpr uint64_t kInitiatorShift = 4;
+  static constexpr uint64_t kCloneTargetMask = 0xF00;
+  static constexpr uint64_t kCloneTargetShift = 8;
+
+  uint64_t flags_ = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_FLUSH_FLAGS_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/data_source_type.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/tracing_muxer.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/tracing_tls.h
+// gen_amalgamated begin header: include/perfetto/tracing/platform.h
+// gen_amalgamated begin header: include/perfetto/base/proc_utils.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_PROC_UTILS_H_
+#define INCLUDE_PERFETTO_BASE_PROC_UTILS_H_
+
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+extern "C" {
+// Prototype extracted from the Windows SDK to avoid including windows.h.
+__declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <zircon/process.h>
+#include <zircon/types.h>
+#else
+#include <unistd.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+using PlatformProcessId = zx_handle_t;
+inline PlatformProcessId GetProcessId() {
+  return zx_process_self();
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using PlatformProcessId = uint64_t;
+inline PlatformProcessId GetProcessId() {
+  return static_cast<uint64_t>(GetCurrentProcessId());
+}
+#else
+using PlatformProcessId = pid_t;
+inline PlatformProcessId GetProcessId() {
+  return getpid();
+}
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_PROC_UTILS_H_
+// gen_amalgamated begin header: include/perfetto/base/thread_utils.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_THREAD_UTILS_H_
+#define INCLUDE_PERFETTO_BASE_THREAD_UTILS_H_
+
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+extern "C" {
+// Prototype extracted from the Windows SDK to avoid including windows.h.
+__declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+#include <zircon/types.h>
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+#else
+#include <pthread.h>
+#endif
+
+namespace perfetto {
+namespace base {
+
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+using PlatformThreadId = pid_t;
+inline PlatformThreadId GetThreadId() {
+  return gettid();
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
+using PlatformThreadId = pid_t;
+inline PlatformThreadId GetThreadId() {
+  return static_cast<pid_t>(syscall(__NR_gettid));
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
+using PlatformThreadId = zx_koid_t;
+// Not inlined because the result is cached internally.
+PERFETTO_EXPORT_COMPONENT PlatformThreadId GetThreadId();
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+using PlatformThreadId = uint64_t;
+inline PlatformThreadId GetThreadId() {
+  uint64_t tid;
+  pthread_threadid_np(nullptr, &tid);
+  return tid;
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+using PlatformThreadId = uint64_t;
+inline PlatformThreadId GetThreadId() {
+  return static_cast<uint64_t>(GetCurrentThreadId());
+}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
+using PlatformThreadId = pid_t;
+inline PlatformThreadId GetThreadId() {
+  return reinterpret_cast<int32_t>(pthread_self());
+}
+#else  // Default to pthreads in case no OS is set.
+using PlatformThreadId = pthread_t;
+inline PlatformThreadId GetThreadId() {
+  return pthread_self();
+}
+#endif
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_THREAD_UTILS_H_
+// gen_amalgamated begin header: include/perfetto/tracing/tracing.h
+// gen_amalgamated begin header: include/perfetto/tracing/backend_type.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_BACKEND_TYPE_H_
+#define INCLUDE_PERFETTO_TRACING_BACKEND_TYPE_H_
+
+#include <stdint.h>
+
+namespace perfetto {
+
+enum BackendType : uint32_t {
+  kUnspecifiedBackend = 0,
+
+  // Connects to a previously-initialized perfetto tracing backend for
+  // in-process. If the in-process backend has not been previously initialized
+  // it will do so and create the tracing service on a dedicated thread.
+  kInProcessBackend = 1 << 0,
+
+  // Connects to the system tracing service (e.g. on Linux/Android/Mac uses a
+  // named UNIX socket).
+  kSystemBackend = 1 << 1,
+
+  // Used to provide a custom IPC transport to connect to the service.
+  // TracingInitArgs::custom_backend must be non-null and point to an
+  // indefinitely lived instance.
+  kCustomBackend = 1 << 2,
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_BACKEND_TYPE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/in_process_tracing_backend.h
+// gen_amalgamated begin header: include/perfetto/tracing/tracing_backend.h
+// gen_amalgamated begin header: include/perfetto/base/platform_handle.h
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
+#define INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
+
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+
+namespace perfetto {
+namespace base {
+
+// PlatformHandle should be used only for types that are HANDLE(s) in Windows.
+// It should NOT be used to blanket-replace "int fd" in the codebase.
+// Windows has two types of "handles", which, in UNIX-land, both map to int:
+// 1. File handles returned by the posix-compatibility API like _open().
+//    These are just int(s) and should stay such, because all the posix-like API
+//    in Windows.h take an int, not a HANDLE.
+// 2. Handles returned by old-school WINAPI like CreateFile, CreateEvent etc.
+//    These are proper HANDLE(s). PlatformHandle should be used here.
+//
+// On Windows, sockets have their own type (SOCKET) which is neither a HANDLE
+// nor an int. However Windows SOCKET(s) can have an event HANDLE attached
+// to them (which in Perfetto is a PlatformHandle), and that can be used in
+// WaitForMultipleObjects, hence in base::TaskRunner.AddFileDescriptorWatch().
+// On POSIX OSes, a SocketHandle is really just an int (a file descriptor).
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+// Windows.h typedefs HANDLE to void*, and SOCKET to uintptr_t. We use their
+// types to avoid leaking Windows.h through our headers.
+using PlatformHandle = void*;
+using SocketHandle = uintptr_t;
+
+// On Windows both nullptr and 0xffff... (INVALID_HANDLE_VALUE) are invalid.
+struct PlatformHandleChecker {
+  static inline bool IsValid(PlatformHandle h) {
+    return h && h != reinterpret_cast<PlatformHandle>(-1);
+  }
+};
+#else
+using PlatformHandle = int;
+using SocketHandle = int;
+struct PlatformHandleChecker {
+  static inline bool IsValid(PlatformHandle h) { return h >= 0; }
+};
+#endif
+
+// The definition of this lives in base/file_utils.cc (to avoid creating an
+// extra build edge for a one liner). This is really an alias for close() (UNIX)
+// CloseHandle() (Windows). THe indirection layer is just to avoid leaking
+// system headers like Windows.h through perfetto headers.
+// Thre return value is always UNIX-style: 0 on success, -1 on failure.
+int ClosePlatformHandle(PlatformHandle);
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACING_BACKEND_H_
+#define INCLUDE_PERFETTO_TRACING_TRACING_BACKEND_H_
+
+#include <functional>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
+
+// The embedder can (but doesn't have to) extend the TracingBackend class and
+// pass as an argument to Tracing::Initialize(kCustomBackend) to override the
+// way to reach the service. This is for peculiar cases where the embedder has
+// a multi-process architecture and wants to override the IPC transport. The
+// real use-case for this at the time of writing is chromium (+ Mojo IPC).
+// Extending this class requires depending on the full set of perfetto headers
+// (not just /public/). Contact the team before doing so as the non-public
+// headers are not guaranteed to be API stable.
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+// These classes are declared in headers outside of /public/.
+class Consumer;
+class ConsumerEndpoint;
+class Producer;
+class ProducerEndpoint;
+
+using CreateSocketCallback = std::function<void(base::SocketHandle)>;
+using CreateSocketAsync = void (*)(CreateSocketCallback);
+
+// Responsible for connecting to the producer.
+class PERFETTO_EXPORT_COMPONENT TracingProducerBackend {
+ public:
+  virtual ~TracingProducerBackend();
+
+  // Connects a Producer instance and obtains a ProducerEndpoint, which is
+  // essentially a 1:1 channel between one Producer and the Service.
+  // To disconnect just destroy the returned endpoint object. It is safe to
+  // destroy the Producer once Producer::OnDisconnect() has been invoked.
+  struct ConnectProducerArgs {
+    std::string producer_name;
+
+    // The Producer object that will receive calls like Start/StopDataSource().
+    // The caller has to guarantee that this object is valid as long as the
+    // returned ProducerEndpoint is alive.
+    Producer* producer = nullptr;
+
+    // The task runner where the Producer methods will be called onto.
+    // The caller has to guarantee that the passed TaskRunner is valid as long
+    // as the returned ProducerEndpoint is alive.
+    ::perfetto::base::TaskRunner* task_runner = nullptr;
+
+    // These get propagated from TracingInitArgs and are optionally provided by
+    // the client when calling Tracing::Initialize().
+    uint32_t shmem_size_hint_bytes = 0;
+    uint32_t shmem_page_size_hint_bytes = 0;
+
+    // If true, the backend should allocate a shared memory buffer and provide
+    // it to the service when connecting.
+    // It's used in startup tracing.
+    bool use_producer_provided_smb = false;
+
+    // If set, the producer will call this function to create and connect to a
+    // socket. See the corresponding field in TracingInitArgs for more info.
+    CreateSocketAsync create_socket_async = nullptr;
+  };
+
+  virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      const ConnectProducerArgs&) = 0;
+};
+
+// Responsible for connecting to the consumer.
+class PERFETTO_EXPORT_COMPONENT TracingConsumerBackend {
+ public:
+  virtual ~TracingConsumerBackend();
+
+  // As above, for the Consumer-side.
+  struct ConnectConsumerArgs {
+    // The Consumer object that will receive calls like OnTracingDisabled(),
+    // OnTraceData().
+    Consumer* consumer{};
+
+    // The task runner where the Consumer methods will be called onto.
+    ::perfetto::base::TaskRunner* task_runner{};
+  };
+  virtual std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
+      const ConnectConsumerArgs&) = 0;
+};
+
+class PERFETTO_EXPORT_COMPONENT TracingBackend : public TracingProducerBackend,
+                                                 public TracingConsumerBackend {
+ public:
+  ~TracingBackend() override;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACING_BACKEND_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+class Producer;
+class TracingService;
+
+namespace internal {
+
+// A built-in implementation of TracingBackend that creates a tracing service
+// instance in-process. Instantiated when the embedder calls
+// Tracing::Initialize(kInProcessBackend). Solves most in-app-only tracing
+// use-cases.
+class PERFETTO_EXPORT_COMPONENT InProcessTracingBackend
+    : public TracingBackend {
+ public:
+  static TracingBackend* GetInstance();
+
+  // TracingBackend implementation.
+  std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      const ConnectProducerArgs&) override;
+  std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
+      const ConnectConsumerArgs&) override;
+
+ private:
+  InProcessTracingBackend();
+  TracingService* GetOrCreateService(base::TaskRunner*);
+
+  std::unique_ptr<TracingService> service_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_IN_PROCESS_TRACING_BACKEND_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/system_tracing_backend.h
+// gen_amalgamated begin header: include/perfetto/tracing/default_socket.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_DEFAULT_SOCKET_H_
+#define INCLUDE_PERFETTO_TRACING_DEFAULT_SOCKET_H_
+
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+
+PERFETTO_EXPORT_COMPONENT const char* GetConsumerSocket();
+// This function is used for tokenize the |producer_socket_names| string into
+// multiple producer socket names.
+PERFETTO_EXPORT_COMPONENT std::vector<std::string> TokenizeProducerSockets(
+    const char* producer_socket_names);
+PERFETTO_EXPORT_COMPONENT const char* GetProducerSocket();
+
+// Optionally returns the relay socket name (nullable). The relay socket is used
+// for forwarding the IPC messages between the local producers and the remote
+// tracing service.
+PERFETTO_EXPORT_COMPONENT const char* GetRelaySocket();
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_DEFAULT_SOCKET_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/default_socket.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}
+
+class Producer;
+
+// Built-in implementations of TracingProducerBackend and TracingConsumerBackend
+// that connect to the system tracing daemon (traced) via a UNIX socket using
+// the perfetto built-in proto-based IPC mechanism. Instantiated when the
+// embedder calls Tracing::Initialize(kSystemBackend). They allow to get
+// app-traces fused together with system traces, useful to correlate on the
+// timeline system events (e.g. scheduling slices from the kernel) with in-app
+// events.
+namespace internal {
+
+// Producer backend
+class PERFETTO_EXPORT_COMPONENT SystemProducerTracingBackend
+    : public TracingProducerBackend {
+ public:
+  static TracingProducerBackend* GetInstance();
+
+  std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      const ConnectProducerArgs&) override;
+
+ private:
+  SystemProducerTracingBackend();
+};
+
+// Consumer backend
+class PERFETTO_EXPORT_COMPONENT SystemConsumerTracingBackend
+    : public TracingConsumerBackend {
+ public:
+  static TracingConsumerBackend* GetInstance();
+
+  std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
+      const ConnectConsumerArgs&) override;
+
+ private:
+  SystemConsumerTracingBackend();
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_SYSTEM_TRACING_BACKEND_H_
+// gen_amalgamated begin header: include/perfetto/tracing/tracing_policy.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACING_POLICY_H_
+#define INCLUDE_PERFETTO_TRACING_TRACING_POLICY_H_
+
+#include <functional>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/backend_type.h"
+
+namespace perfetto {
+
+// Applies policy decisions, such as allowing or denying connections, when
+// certain tracing SDK events occur. All methods are called on an internal
+// perfetto thread.
+class PERFETTO_EXPORT_COMPONENT TracingPolicy {
+ public:
+  virtual ~TracingPolicy();
+
+  // Called when the current process attempts to connect a new consumer to the
+  // backend of |backend_type| to check if the connection should be allowed. Its
+  // implementation should execute |result_callback| with the result of the
+  // check (synchronuosly or asynchronously on any thread). If the result is
+  // false, the consumer connection is aborted. Chrome uses this to restrict
+  // creating (system) tracing sessions based on an enterprise policy.
+  struct ShouldAllowConsumerSessionArgs {
+    BackendType backend_type;
+    std::function<void(bool /*allow*/)> result_callback;
+  };
+  virtual void ShouldAllowConsumerSession(
+      const ShouldAllowConsumerSessionArgs&) = 0;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACING_POLICY_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACING_H_
+#define INCLUDE_PERFETTO_TRACING_TRACING_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/backend_type.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/in_process_tracing_backend.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/system_tracing_backend.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_policy.h"
+
+namespace perfetto {
+
+namespace internal {
+class TracingMuxerImpl;
+}
+
+class TracingBackend;
+class Platform;
+class StartupTracingSession;  // Declared below.
+class TracingSession;         // Declared below.
+
+struct TracingError {
+  enum ErrorCode : uint32_t {
+    // Peer disconnection.
+    kDisconnected = 1,
+
+    // The Start() method failed. This is typically because errors in the passed
+    // TraceConfig. More details are available in |message|.
+    kTracingFailed = 2,
+  };
+
+  ErrorCode code;
+  std::string message;
+
+  TracingError(ErrorCode cd, std::string msg)
+      : code(cd), message(std::move(msg)) {
+    PERFETTO_CHECK(!message.empty());
+  }
+};
+
+using LogLev = ::perfetto::base::LogLev;
+using LogMessageCallbackArgs = ::perfetto::base::LogMessageCallbackArgs;
+using LogMessageCallback = ::perfetto::base::LogMessageCallback;
+
+struct TracingInitArgs {
+  uint32_t backends = 0;                     // One or more BackendTypes.
+  TracingBackend* custom_backend = nullptr;  // [Optional].
+
+  // [Optional] Platform implementation. It allows the embedder to take control
+  // of platform-specific bits like thread creation and TLS slot handling. If
+  // not set it will use Platform::GetDefaultPlatform().
+  Platform* platform = nullptr;
+
+  // [Optional] Tune the size of the shared memory buffer between the current
+  // process and the service backend(s). This is a trade-off between memory
+  // footprint and the ability to sustain bursts of trace writes (see comments
+  // in shared_memory_abi.h).
+  // If set, the value must be a multiple of 4KB. The value can be ignored if
+  // larger than kMaxShmSize (32MB) or not a multiple of 4KB.
+  uint32_t shmem_size_hint_kb = 0;
+
+  // [Optional] Specifies the preferred size of each page in the shmem buffer.
+  // This is a trade-off between IPC overhead and fragmentation/efficiency of
+  // the shmem buffer in presence of multiple writer threads.
+  // Must be one of [4, 8, 16, 32].
+  uint32_t shmem_page_size_hint_kb = 0;
+
+  // [Optional] The length of the period during which shared-memory-buffer
+  // chunks that have been filled with data are accumulated (batched) on the
+  // producer side, before the service is notified of them over an out-of-band
+  // IPC call. If, while this period lasts, the shared memory buffer gets too
+  // full, the IPC call will be sent immediately. The value of this parameter is
+  // a trade-off between IPC traffic overhead and the ability to sustain bursts
+  // of trace writes. The higher the value, the more chunks will be batched and
+  // the less buffer space will be available to hide the latency of the service,
+  // and vice versa. For more details, see the SetBatchCommitsDuration method in
+  // shared_memory_arbiter.h.
+  //
+  // Note: With the default value of 0ms, batching still happens but with a zero
+  // delay, i.e. commits will be sent to the service at the next opportunity.
+  uint32_t shmem_batch_commits_duration_ms = 0;
+
+  // [Optional] Enables direct producer-side patching of chunks that have not
+  // yet been committed to the service. This flag will only have an effect
+  // if the service supports direct patching, otherwise it will be ignored.
+  bool shmem_direct_patching_enabled = false;
+
+  // [Optional] If set, the policy object is notified when certain SDK events
+  // occur and may apply policy decisions, such as denying connections. The
+  // embedder is responsible for ensuring the object remains alive for the
+  // lifetime of the process.
+  TracingPolicy* tracing_policy = nullptr;
+
+  // [Optional] If set, log messages generated by perfetto are passed to this
+  // callback instead of being logged directly.
+  LogMessageCallback log_message_callback = nullptr;
+
+  // When this flag is set to false, it overrides
+  // `DataSource::kSupportsMultipleInstances` for all the data sources.
+  // As a result when a tracing session is already running and if we attempt to
+  // start another session, it will fail to start the data source which were
+  // already active.
+  bool supports_multiple_data_source_instances = true;
+
+  // If this flag is set the default clock for taking timestamps is overridden
+  // with CLOCK_MONOTONIC (for use in Chrome).
+  bool use_monotonic_clock = false;
+
+  // If this flag is set the default clock for taking timestamps is overridden
+  // with CLOCK_MONOTONIC_RAW on platforms that support it.
+  bool use_monotonic_raw_clock = false;
+
+  // This flag can be set to false in order to avoid enabling the system
+  // consumer in Tracing::Initialize(), so that the linker can remove the unused
+  // consumer IPC implementation to reduce binary size. This setting only has an
+  // effect if kSystemBackend is specified in |backends|. When this option is
+  // false, Tracing::NewTrace() will instatiate the system backend only if
+  // explicitly specified as kSystemBackend: kUndefinedBackend will consider
+  // only already instantiated backends.
+  bool enable_system_consumer = true;
+
+  // When true, sets disallow_merging_with_system_tracks in TrackDescriptor,
+  // making sure that Trace Processor doesn't merge track event and system
+  // event tracks for the same thread.
+  bool disallow_merging_with_system_tracks = false;
+
+  // If set, this function will be called by the producer client to create a
+  // socket for connection to the system service. The function takes two
+  // arguments: a name of the socket, and a callback that takes an open file
+  // descriptor. It should create a socket with the given name, connect to it,
+  // and return the corresponding descriptor via the callback.
+  // This is intended for the use-case where a process being traced is run
+  // inside a sandbox and can't create sockets directly.
+  // Not yet supported for consumer connections currently.
+  CreateSocketAsync create_socket_async = nullptr;
+
+ protected:
+  friend class Tracing;
+  friend class internal::TracingMuxerImpl;
+
+  using BackendFactoryFunction = TracingBackend* (*)();
+  using ProducerBackendFactoryFunction = TracingProducerBackend* (*)();
+  using ConsumerBackendFactoryFunction = TracingConsumerBackend* (*)();
+
+  BackendFactoryFunction in_process_backend_factory_ = nullptr;
+  ProducerBackendFactoryFunction system_producer_backend_factory_ = nullptr;
+  ConsumerBackendFactoryFunction system_consumer_backend_factory_ = nullptr;
+  bool dcheck_is_on_ = PERFETTO_DCHECK_IS_ON();
+};
+
+// The entry-point for using perfetto.
+class PERFETTO_EXPORT_COMPONENT Tracing {
+ public:
+  // Initializes Perfetto with the given backends in the calling process and/or
+  // with a user-provided backend. It's possible to call this function more than
+  // once to initialize different backends. If a backend was already initialized
+  // the call will have no effect on it. All the members of `args` will be
+  // ignored in subsequent calls, except those require to initialize new
+  // backends (`backends`, `enable_system_consumer`, `shmem_size_hint_kb`,
+  // `shmem_page_size_hint_kb` and `shmem_batch_commits_duration_ms`).
+  static inline void Initialize(const TracingInitArgs& args)
+      PERFETTO_ALWAYS_INLINE {
+    TracingInitArgs args_copy(args);
+    // This code is inlined to allow dead-code elimination for unused backends.
+    // This saves ~200 KB when not using the in-process backend (b/148198993).
+    // The logic behind it is the following:
+    // Nothing other than the code below references the two GetInstance()
+    // methods. From a linker-graph viewpoint, those GetInstance() pull in many
+    // other pieces of the codebase (e.g. InProcessTracingBackend pulls the
+    // whole TracingServiceImpl, SystemTracingBackend pulls the whole //ipc
+    // layer). Due to the inline, the compiler can see through the code and
+    // realize that some branches are always not taken. When that happens, no
+    // reference to the backends' GetInstance() is emitted and that allows the
+    // linker GC to get rid of the entire set of dependencies.
+    if (args.backends & kInProcessBackend) {
+      args_copy.in_process_backend_factory_ =
+          &internal::InProcessTracingBackend::GetInstance;
+    }
+    if (args.backends & kSystemBackend) {
+      args_copy.system_producer_backend_factory_ =
+          &internal::SystemProducerTracingBackend::GetInstance;
+      if (args.enable_system_consumer) {
+        args_copy.system_consumer_backend_factory_ =
+            &internal::SystemConsumerTracingBackend::GetInstance;
+      }
+    }
+    InitializeInternal(args_copy);
+  }
+
+  // Checks if tracing has been initialized by calling |Initialize|.
+  static bool IsInitialized();
+
+  // Start a new tracing session using the given tracing backend. Use
+  // |kUnspecifiedBackend| to select an available backend automatically.
+  static PERFETTO_ALWAYS_INLINE inline std::unique_ptr<TracingSession> NewTrace(
+      BackendType backend = kUnspecifiedBackend);
+
+  // Shut down Perfetto, releasing any allocated OS resources (threads, files,
+  // sockets, etc.). Note that Perfetto cannot be reinitialized again in the
+  // same process[1]. Instead, this function is meant for shutting down all
+  // Perfetto-related code so that it can be safely unloaded, e.g., with
+  // dlclose().
+  //
+  // It is only safe to call this function when all threads recording trace
+  // events have been terminated or otherwise guaranteed to not make any further
+  // calls into Perfetto.
+  //
+  // [1] Unless static data is also cleared through other means.
+  static void Shutdown();
+
+  // Uninitialize Perfetto. Only exposed for testing scenarios where it can be
+  // guaranteed that no tracing sessions or other operations are happening when
+  // this call is made.
+  static void ResetForTesting();
+
+  // Start a new startup tracing session in the current process. Startup tracing
+  // can be used in anticipation of a session that will be started by the
+  // specified backend in the near future. The data source configs in the
+  // supplied TraceConfig have to (mostly) match those in the config that will
+  // later be provided by the backend.
+  // Learn more about config matching at ComputeStartupConfigHash.
+  //
+  // Note that startup tracing requires that either:
+  //  (a) the service backend already has an SMB set up, or
+  //  (b) the service backend to support producer-provided SMBs if the backend
+  //      is not yet connected or no SMB has been set up yet
+  //      (See `use_producer_provided_smb`). If necessary, the
+  //      client library will briefly disconnect and reconnect the backend to
+  //      supply an SMB to the backend. If the service does not accept the SMB,
+  //      startup tracing will be aborted, but the service may still start the
+  //      corresponding tracing session later.
+  //
+  // Startup tracing is NOT supported with the in-process backend. For this
+  // backend, you can just start a regular tracing session and block until it is
+  // set up instead.
+  //
+  // The client library will start the data sources instances specified in the
+  // config with a placeholder target buffer. Once the backend starts a matching
+  // tracing session, the session will resume as normal. If no matching session
+  // is started after a timeout (or the backend doesn't accept the
+  // producer-provided SMB), the startup tracing session will be aborted
+  // and the data source instances stopped.
+  struct OnStartupTracingSetupCallbackArgs {
+    int num_data_sources_started;
+  };
+  struct SetupStartupTracingOpts {
+    BackendType backend = kUnspecifiedBackend;
+    uint32_t timeout_ms = 10000;
+
+    // If set, this callback is executed (on an internal Perfetto thread) when
+    // startup tracing was set up.
+    std::function<void(OnStartupTracingSetupCallbackArgs)> on_setup;
+
+    // If set, this callback is executed (on an internal Perfetto thread) if any
+    // data sources were aborted, e.g. due to exceeding the timeout or as a
+    // response to Abort().
+    std::function<void()> on_aborted;
+
+    // If set, this callback is executed (on an internal Perfetto thread) after
+    // all data sources were adopted by a tracing session initiated by the
+    // backend.
+    std::function<void()> on_adopted;
+  };
+
+  static std::unique_ptr<StartupTracingSession> SetupStartupTracing(
+      const TraceConfig& config,
+      SetupStartupTracingOpts);
+
+  // Blocking version of above method, so callers can ensure that tracing is
+  // active before proceeding with app startup. Calls into
+  // DataSource::Trace() or trace macros right after this method are written
+  // into the startup session.
+  static std::unique_ptr<StartupTracingSession> SetupStartupTracingBlocking(
+      const TraceConfig& config,
+      SetupStartupTracingOpts);
+
+  // Informs the tracing services to activate any of these triggers if any
+  // tracing session was waiting for them.
+  //
+  // Sends the trigger signal to all the initialized backends that are currently
+  // connected and that connect in the next `ttl_ms` milliseconds (but
+  // returns immediately anyway).
+  static void ActivateTriggers(const std::vector<std::string>& triggers,
+                               uint32_t ttl_ms);
+
+ private:
+  static void InitializeInternal(const TracingInitArgs&);
+  static std::unique_ptr<TracingSession> NewTraceInternal(
+      BackendType,
+      TracingConsumerBackend* (*system_backend_factory)());
+
+  Tracing() = delete;
+};
+
+class PERFETTO_EXPORT_COMPONENT TracingSession {
+ public:
+  virtual ~TracingSession();
+
+  // Configure the session passing the trace config.
+  // If a writable file handle is given through |fd|, the trace will
+  // automatically written to that file. Otherwise you should call ReadTrace()
+  // to retrieve the trace data. This call does not take ownership of |fd|.
+  // TODO(primiano): add an error callback.
+  virtual void Setup(const TraceConfig&, int fd = -1) = 0;
+
+  // Enable tracing asynchronously. Use SetOnStartCallback() to get a
+  // notification when the session has fully started.
+  virtual void Start() = 0;
+
+  // Enable tracing and block until tracing has started. Note that if data
+  // sources are registered after this call was initiated, the call may return
+  // before the additional data sources have started. Also, if other producers
+  // (e.g., with system-wide tracing) have registered data sources without start
+  // notification support, this call may return before those data sources have
+  // started.
+  virtual void StartBlocking() = 0;
+
+  // This callback will be invoked when all data sources have acknowledged that
+  // tracing has started. This callback will be invoked on an internal perfetto
+  // thread.
+  virtual void SetOnStartCallback(std::function<void()>) = 0;
+
+  // This callback can be used to get a notification when some error occured
+  // (e.g., peer disconnection). Error type will be passed as an argument. This
+  // callback will be invoked on an internal perfetto thread.
+  virtual void SetOnErrorCallback(std::function<void(TracingError)>) = 0;
+
+  // Issues a flush request, asking all data sources to ack the request, within
+  // the specified timeout. A "flush" is a fence to ensure visibility of data in
+  // the async tracing pipeline. It guarantees that all data written before the
+  // Flush() call will be visible in the trace buffer and hence by the
+  // ReadTrace() / ReadTraceBlocking() methods.
+  // Args:
+  //  callback: will be invoked on an internal perfetto thread when all data
+  //    sources have acked, or the timeout is reached. The bool argument
+  //    will be true if all data sources acked within the timeout, false if
+  //    the timeout was hit or some other error occurred (e.g. the tracing
+  //    session wasn't started or ended).
+  //  timeout_ms: how much time the service will wait for data source acks. If
+  //    0, the global timeout specified in the TraceConfig (flush_timeout_ms)
+  //    will be used. If flush_timeout_ms is also unspecified, a default value
+  //    of 5s will be used.
+  // Known issues:
+  //    Because flushing is still based on service-side scraping, the very last
+  //    trace packet for each data source thread will not be visible. Fixing
+  //    this requires either propagating the Flush() to the data sources or
+  //    changing the order of atomic operations in the service (b/162206162).
+  //    Until then, a workaround is to make sure to call
+  //    DataSource::Trace([](TraceContext ctx) { ctx.Flush(); }) just before
+  //    stopping, on each thread where DataSource::Trace has been previously
+  //    called.
+  virtual void Flush(std::function<void(bool)>, uint32_t timeout_ms = 0) = 0;
+
+  // Blocking version of Flush(). Waits until all data sources have acked and
+  // returns the success/failure status.
+  bool FlushBlocking(uint32_t timeout_ms = 0);
+
+  // Disable tracing asynchronously.
+  // Use SetOnStopCallback() to get a notification when the tracing session is
+  // fully stopped and all data sources have acked.
+  virtual void Stop() = 0;
+
+  // Disable tracing and block until tracing has stopped.
+  virtual void StopBlocking() = 0;
+
+  // This callback will be invoked when tracing is disabled.
+  // This can happen either when explicitly calling TracingSession.Stop() or
+  // when the trace reaches its |duration_ms| time limit.
+  // This callback will be invoked on an internal perfetto thread.
+  virtual void SetOnStopCallback(std::function<void()>) = 0;
+
+  // Changes the TraceConfig for an active tracing session. The session must
+  // have been configured and started before. Note that the tracing service
+  // only supports changing a subset of TraceConfig fields,
+  // see ConsumerEndpoint::ChangeTraceConfig().
+  virtual void ChangeTraceConfig(const TraceConfig&) = 0;
+
+  // Struct passed as argument to the callback passed to ReadTrace().
+  // [data, size] is guaranteed to contain 1 or more full trace packets, which
+  // can be decoded using trace.proto. No partial or truncated packets are
+  // exposed. If the trace is empty this returns a zero-sized nullptr with
+  // |has_more| == true to signal EOF.
+  // This callback will be invoked on an internal perfetto thread.
+  struct ReadTraceCallbackArgs {
+    const char* data = nullptr;
+    size_t size = 0;
+
+    // When false, this will be the last invocation of the callback for this
+    // read cycle.
+    bool has_more = false;
+  };
+
+  // Reads back the trace data (raw protobuf-encoded bytes) asynchronously.
+  // Can be called at any point during the trace, typically but not necessarily,
+  // after stopping. If this is called before the end of the trace (i.e. before
+  // Stop() / StopBlocking()), in almost all cases you need to call
+  // Flush() / FlushBlocking() before Read(). This is to guarantee that tracing
+  // data in-flight in the data sources is committed into the tracing buffers
+  // before reading them.
+  // Reading the trace data is a destructive operation w.r.t. contents of the
+  // trace buffer and is not idempotent.
+  // A single ReadTrace() call can yield >1 callback invocations, until
+  // |has_more| is false.
+  using ReadTraceCallback = std::function<void(ReadTraceCallbackArgs)>;
+  virtual void ReadTrace(ReadTraceCallback) = 0;
+
+  // Synchronous version of ReadTrace(). It blocks the calling thread until all
+  // the trace contents are read. This is slow and inefficient (involves more
+  // copies) and is mainly intended for testing.
+  std::vector<char> ReadTraceBlocking();
+
+  // Struct passed as an argument to the callback for GetTraceStats(). Contains
+  // statistics about the tracing session.
+  struct GetTraceStatsCallbackArgs {
+    // Whether or not querying statistics succeeded.
+    bool success = false;
+    // Serialized TraceStats protobuf message. To decode:
+    //
+    //   perfetto::protos::gen::TraceStats trace_stats;
+    //   trace_stats.ParseFromArray(args.trace_stats_data.data(),
+    //                              args.trace_stats_data.size());
+    //
+    std::vector<uint8_t> trace_stats_data;
+  };
+
+  // Requests a snapshot of statistical data for this tracing session. Only one
+  // query may be active at a time. This callback will be invoked on an internal
+  // perfetto thread.
+  using GetTraceStatsCallback = std::function<void(GetTraceStatsCallbackArgs)>;
+  virtual void GetTraceStats(GetTraceStatsCallback) = 0;
+
+  // Synchronous version of GetTraceStats() for convenience.
+  GetTraceStatsCallbackArgs GetTraceStatsBlocking();
+
+  // Struct passed as an argument to the callback for QueryServiceState().
+  // Contains information about registered data sources.
+  struct QueryServiceStateCallbackArgs {
+    // Whether or not getting the service state succeeded.
+    bool success = false;
+    // Serialized TracingServiceState protobuf message. To decode:
+    //
+    //   perfetto::protos::gen::TracingServiceState state;
+    //   state.ParseFromArray(args.service_state_data.data(),
+    //                        args.service_state_data.size());
+    //
+    std::vector<uint8_t> service_state_data;
+  };
+
+  // Requests a snapshot of the tracing service state for this session. Only one
+  // request per session may be active at a time. This callback will be invoked
+  // on an internal perfetto thread.
+  using QueryServiceStateCallback =
+      std::function<void(QueryServiceStateCallbackArgs)>;
+  virtual void QueryServiceState(QueryServiceStateCallback) = 0;
+
+  // Synchronous version of QueryServiceState() for convenience.
+  QueryServiceStateCallbackArgs QueryServiceStateBlocking();
+};
+
+class PERFETTO_EXPORT_COMPONENT StartupTracingSession {
+ public:
+  // Note that destroying the StartupTracingSession object will not abort the
+  // startup session automatically. Call Abort() explicitly to do so.
+  virtual ~StartupTracingSession();
+
+  // Abort any active but still unbound data source instances that belong to
+  // this startup tracing session. Does not affect data source instances that
+  // were already bound to a service-controlled session.
+  virtual void Abort() = 0;
+
+  // Same as above, but blocks the current thread until aborted.
+  // Note some of the internal (non observable from public APIs) cleanup might
+  // be done even after this method returns.
+  virtual void AbortBlocking() = 0;
+};
+
+PERFETTO_ALWAYS_INLINE inline std::unique_ptr<TracingSession>
+Tracing::NewTrace(BackendType backend) {
+  // This code is inlined to allow dead-code elimination for unused consumer
+  // implementation. The logic behind it is the following:
+  // Nothing other than the code below references the GetInstance() method
+  // below. From a linker-graph viewpoint, those GetInstance() pull in many
+  // other pieces of the codebase (ConsumerOnlySystemTracingBackend pulls
+  // ConsumerIPCClient). Due to the inline, the compiler can see through the
+  // code and realize that some branches are always not taken. When that
+  // happens, no reference to the backends' GetInstance() is emitted and that
+  // allows the linker GC to get rid of the entire set of dependencies.
+  TracingConsumerBackend* (*system_backend_factory)();
+  system_backend_factory = nullptr;
+  // In case PERFETTO_IPC is disabled, a fake system backend is used, which
+  // always panics. NewTrace(kSystemBackend) should fail if PERFETTO_IPC is
+  // diabled, not panic.
+#if PERFETTO_BUILDFLAG(PERFETTO_IPC)
+  if (backend & kSystemBackend) {
+    system_backend_factory =
+        &internal::SystemConsumerTracingBackend::GetInstance;
+  }
+#endif
+  return NewTraceInternal(backend, system_backend_factory);
+}
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACING_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_PLATFORM_H_
+#define INCLUDE_PERFETTO_TRACING_PLATFORM_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <functional>
+#include <memory>
+#include <string>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+
+namespace perfetto {
+
+namespace base {
+class TaskRunner;
+}  // namespace base
+
+// This abstract class is used to abstract dependencies on platform-specific
+// primitives that cannot be implemented by the perfetto codebase and must be
+// provided or overridden by the embedder.
+// This is, for instance, for cases where we want to use some particular
+// base:: class in Chrome and provide instead POSIX fallbacks for other
+// embedders.
+
+// Base class for thread-local objects. This is to get a basic object vtable and
+// delegate destruction to the embedder. See Platform::CreateThreadLocalObject.
+class PERFETTO_EXPORT_COMPONENT PlatformThreadLocalObject {
+ public:
+  // Implemented by perfetto internal code. The embedder must call this when
+  // implementing GetOrCreateThreadLocalObject() to create an instance for the
+  // first time on each thread.
+  static std::unique_ptr<PlatformThreadLocalObject> CreateInstance();
+  virtual ~PlatformThreadLocalObject();
+};
+
+class PERFETTO_EXPORT_COMPONENT Platform {
+ public:
+  // Embedders can use this unless they have custom needs (e.g. Chrome wanting
+  // to use its own base class for TLS).
+  static Platform* GetDefaultPlatform();
+
+  // Embedders can call this to set process ID in those cases where getpid()
+  // returns incorrect values (e.g. for sandboxed processes in Chromium).
+  // Should only be called once, before tracing has been initialized.
+  static void SetCurrentProcessId(base::PlatformProcessId process_id) {
+    PERFETTO_CHECK(!process_id_);
+    PERFETTO_DCHECK(!Tracing::IsInitialized());
+    process_id_ = process_id;
+  }
+
+  // Returns process ID previously set by SetCurrentProcessId, or the process
+  // ID provided by the OS if no custom ID was provided.
+  static base::PlatformProcessId GetCurrentProcessId() {
+    if (process_id_)
+      return process_id_;
+    return base::GetProcessId();
+  }
+
+  virtual ~Platform();
+
+  // Creates a thread-local object. The embedder must:
+  // - Create an instance per-thread calling ThreadLocalObject::CreateInstance.
+  // - Own the lifetime of the returned object as long as the thread is alive.
+  // - Destroy it when the thread exits.
+  // Perfetto requires only one thread-local object overall (obviously, one
+  // instance per-thread) from the embedder.
+  using ThreadLocalObject = ::perfetto::PlatformThreadLocalObject;
+  virtual ThreadLocalObject* GetOrCreateThreadLocalObject() = 0;
+
+  // Creates a sequenced task runner. The easiest implementation is to create
+  // a new thread (e.g. use base::ThreadTaskRunner) but this can also be
+  // implemented in some more clever way (e.g. using chromiums's scheduler).
+  struct CreateTaskRunnerArgs {
+    // Optional. Sets the name to the newly created task runner. In the default
+    // PosixPlatform implementation this causes a pthread_setname_np(). This is
+    // only for ease of debugging, it does not affect the tracing behavior.
+    std::string name_for_debugging;
+  };
+  virtual std::unique_ptr<base::TaskRunner> CreateTaskRunner(
+      const CreateTaskRunnerArgs&) = 0;
+
+  // Used to derive the producer name. Mostly relevant when using the
+  // kSystemBackend mode. It can be an arbitrary string when using the
+  // in-process mode.
+  virtual std::string GetCurrentProcessName() = 0;
+
+  // Tear down any persistent platform state (e.g., TLS variables). The platform
+  // interface must not be used after calling this function.
+  virtual void Shutdown();
+
+  // Returns the thread ID provided by the OS by default. Chromium uses
+  // different thread IDs on some platforms, so it needs the ability to
+  // override this method.
+  virtual base::PlatformThreadId GetCurrentThreadId();
+
+ private:
+  static base::PlatformProcessId process_id_;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_PLATFORM_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_TLS_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_TLS_H_
+
+#include <array>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+
+namespace perfetto {
+
+class TraceWriterBase;
+
+namespace internal {
+
+// Organization of the thread-local storage
+// ----------------------------------------
+// First of all, remember the cardinality of the problem: at any point in time
+// there are M data sources registered (i.e. number of subclasses of DataSource)
+// and up to N concurrent instances for each data source, so up to M * N total
+// data source instances around.
+// Each data source instance can be accessed by T threads (no upper bound).
+// We can safely put hard limits both to M and N (i.e. say that we support at
+// most 32 data source types per process and up to 8 concurrent instances).
+//
+// We want to make it so from the Platform viewpoint, we use only one global
+// TLS object, so T instances in total, one per thread, regardless of M and N.
+// This allows to deal with at-thread-exit destruction only in one place, rather
+// than N, M or M * N.
+//
+// Visually:
+//                     [    Thread 1   ] [    Thread 2   ] [    Thread T   ]
+//                     +---------------+ +---------------+ +---------------+
+// Data source Foo     |               | |               | |               |
+//  Instance 1         |     TLS       | |     TLS       | |     TLS       |
+//  Instance 2         |    Object     | |    Object     | |    Object     |
+//  Instance 3         |               | |               | |               |
+//                     |               | |               | |               |
+// Data source Bar     |               | |               | |               |
+//  Instance 1         |               | |               | |               |
+//  Instance 2         |               | |               | |               |
+//                     +---------------+ +---------------+ +---------------+
+//
+// Each TLS Object is organized as an array of M DataSourceThreadLocalState.
+// Each DSTLS itself is an array of up to N per-instance objects.
+// The only per-instance object for now is the TraceWriter.
+// So for each data source, for each instance, for each thread we keep one
+// TraceWriter.
+// The lookup is O(1): Given the TLS object, the TraceWriter is just tls[M][N].
+class TracingTLS : public Platform::ThreadLocalObject {
+ public:
+  ~TracingTLS() override;
+
+  // This is checked against TraceMuxerImpl's global generation counter to
+  // handle destruction of TraceWriter(s) that belong to data sources that
+  // have been stopped. When the two numbers diverge, a scan of all the
+  // thread-local TraceWriter(s) is issued.
+  uint32_t generation = 0;
+
+  // This flag is true while this thread is inside a trace point for any data
+  // source or in other delicate parts of the tracing machinery during which we
+  // should not try to trace. Used to prevent unexpected re-entrancy.
+  // This flag is also load-bearing when handling re-entrancy during thread-exit
+  // handlers. See comment in TracingTLS::~TracingTLS().
+  bool is_in_trace_point = false;
+
+  // Used inside a trace point (only one trace point per thread can be active at
+  // any time) to cache the instances bitmap.
+  uint32_t cached_instances = 0;
+
+  // By default all data source instances have independent thread-local state
+  // (see above).
+  std::array<DataSourceThreadLocalState, kMaxDataSources> data_sources_tls{};
+
+  // Track event data sources, however, share the same thread-local state in
+  // order to be able to share trace writers and interning state across all
+  // track event categories.
+  DataSourceThreadLocalState track_event_tls{};
+};
+
+struct ScopedReentrancyAnnotator {
+  ScopedReentrancyAnnotator(TracingTLS& root_tls) : root_tls_(root_tls) {
+    PERFETTO_DCHECK(!root_tls_.is_in_trace_point);
+    root_tls_.is_in_trace_point = true;
+  }
+  ~ScopedReentrancyAnnotator() { root_tls_.is_in_trace_point = false; }
+
+ private:
+  TracingTLS& root_tls_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_TLS_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_MUXER_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_MUXER_H_
+
+#include <atomic>
+#include <memory>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+namespace perfetto {
+
+class DataSourceBase;
+class TraceWriterBase;
+struct TracingInitArgs;
+class TracingSession;
+
+namespace internal {
+
+struct DataSourceParams {
+  bool supports_multiple_instances;
+  bool requires_callbacks_under_lock;
+};
+
+struct DataSourceStaticState;
+
+// This class acts as a bridge between the public API methods and the
+// TracingBackend(s). It exposes a simplified view of the world to the API
+// methods, so that they don't have to care about the multiplicity of backends.
+// It handles all the bookkeeping to map data source instances and trace writers
+// to the various backends.
+// See tracing_muxer_impl.h for the full picture. This class contains only the
+// fewer fields and methods that need to be exposed to public/ headers. Fields
+// and methods that are required to implement them should go into
+// src/tracing/internal/tracing_muxer_impl.h instead: that one can pull in
+// perfetto headers outside of public, this one cannot.
+class PERFETTO_EXPORT_COMPONENT TracingMuxer {
+ public:
+  static TracingMuxer* Get() { return instance_; }
+
+  virtual ~TracingMuxer();
+
+  TracingTLS* GetOrCreateTracingTLS() {
+    return static_cast<TracingTLS*>(platform_->GetOrCreateThreadLocalObject());
+  }
+
+  // This method can fail and return false if trying to register more than
+  // kMaxDataSources types.
+  using DataSourceFactory = std::function<std::unique_ptr<DataSourceBase>()>;
+  virtual bool RegisterDataSource(const DataSourceDescriptor&,
+                                  DataSourceFactory,
+                                  DataSourceParams,
+                                  DataSourceStaticState*) = 0;
+
+  // Updates the DataSourceDescriptor for the DataSource.
+  virtual void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
+                                          const DataSourceStaticState*) = 0;
+
+  // It identifies the right backend and forwards the call to it.
+  // The returned TraceWriter must be used within the same sequence (for most
+  // projects this means "same thread"). Alternatively the client needs to take
+  // care of using synchronization primitives to prevent concurrent accesses.
+  virtual std::unique_ptr<TraceWriterBase> CreateTraceWriter(
+      DataSourceStaticState*,
+      uint32_t data_source_instance_index,
+      DataSourceState*,
+      BufferExhaustedPolicy buffer_exhausted_policy) = 0;
+
+  virtual void DestroyStoppedTraceWritersForCurrentThread() = 0;
+
+  uint32_t generation(std::memory_order ord) { return generation_.load(ord); }
+
+  using InterceptorFactory = std::function<std::unique_ptr<InterceptorBase>()>;
+  virtual void RegisterInterceptor(const InterceptorDescriptor&,
+                                   InterceptorFactory,
+                                   InterceptorBase::TLSFactory,
+                                   InterceptorBase::TracePacketCallback) = 0;
+
+  // Informs the tracing services to activate any of these triggers if any
+  // tracing session was waiting for them.
+  //
+  // Sends the trigger signal to all the initialized backends that are currently
+  // connected and that connect in the next `ttl_ms` milliseconds (but returns
+  // immediately anyway).
+  virtual void ActivateTriggers(const std::vector<std::string>&,
+                                uint32_t ttl_ms) = 0;
+
+  base::PlatformThreadId GetCurrentThreadId() {
+    return platform_->GetCurrentThreadId();
+  }
+
+ protected:
+  explicit TracingMuxer(Platform* platform) : platform_(platform) {}
+
+  static TracingMuxer* instance_;
+  Platform* const platform_ = nullptr;
+
+  // Incremented every time a data source is destroyed. See tracing_tls.h.
+  std::atomic<uint32_t> generation_{};
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_MUXER_H_
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_TYPE_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_TYPE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+
+namespace perfetto {
+namespace internal {
+
+// Represents a data source type (not an instance).
+//
+// All the static state of a DataSource<T> lives here (including
+// DataSourceStaticState).
+//
+// The C shared library API wrapper cannot use DataSource<T>, because it needs
+// to create new data source types at runtime, so it uses this directly.
+//
+// The main reason why this intermediate class exist is to decouple the
+// DataSourceStaticState from the specific DataSource<T>. The C API cannot
+// dynamically create template instances and it needs a way to decouple those at
+// runtime.
+class PERFETTO_EXPORT_COMPONENT DataSourceType {
+ public:
+  // Function pointer type used to create custom per instance thread local
+  // state.
+  using CreateCustomTlsFn =
+      DataSourceInstanceThreadLocalState::ObjectWithDeleter (*)(
+          DataSourceInstanceThreadLocalState* tls_inst,
+          uint32_t instance_index,
+          void* user_arg);
+  // Function pointer type used to create custom per instance thread local
+  // incremental state (which might be cleared periodically by the tracing
+  // service).
+  using CreateIncrementalStateFn =
+      DataSourceInstanceThreadLocalState::ObjectWithDeleter (*)(
+          DataSourceInstanceThreadLocalState* tls_inst,
+          uint32_t instance_index,
+          void* user_arg);
+
+  // Registers the data source type with the central tracing muxer.
+  // * `descriptor` is the data source protobuf descriptor.
+  // * `factory` is a std::function used to create instances of the data source
+  //   type.
+  // * `buffer_exhausted_policy` specifies what to do when the shared memory
+  //   buffer runs out of chunks.
+  // * `create_custom_tls_fn` and `create_incremental_state_fn` are function
+  //   pointers called to create custom state. They will receive `user_arg` as
+  //   an extra param.
+  bool Register(const DataSourceDescriptor& descriptor,
+                TracingMuxer::DataSourceFactory factory,
+                internal::DataSourceParams params,
+                BufferExhaustedPolicy buffer_exhausted_policy,
+                CreateCustomTlsFn create_custom_tls_fn,
+                CreateIncrementalStateFn create_incremental_state_fn,
+                void* user_arg) {
+    buffer_exhausted_policy_ = buffer_exhausted_policy;
+    create_custom_tls_fn_ = create_custom_tls_fn;
+    create_incremental_state_fn_ = create_incremental_state_fn;
+    user_arg_ = user_arg;
+    auto* tracing_impl = TracingMuxer::Get();
+    return tracing_impl->RegisterDataSource(descriptor, factory, params,
+                                            &state_);
+  }
+
+  // Updates the data source type descriptor.
+  void UpdateDescriptor(const DataSourceDescriptor& descriptor) {
+    auto* tracing_impl = TracingMuxer::Get();
+    tracing_impl->UpdateDataSourceDescriptor(descriptor, &state_);
+  }
+
+  // The beginning of a trace point.
+  //
+  // `tls_state` must point to a thread local variable that caches a pointer to
+  // an internal per data source type thread local state.
+  //
+  // `instances` must point to a copy of the current active instances for the
+  // data source type.
+  //
+  // `DataSourceTraits` can be used to customize the thread local storage used
+  // for the data source type.
+  //
+  // `TracePointTraits` and `trace_point_data` are customization point for
+  // getting the active instances bitmap.
+  //
+  // If this returns false, the trace point must be skipped.
+  template <typename DataSourceTraits, typename TracePointTraits>
+  bool TracePrologue(
+      DataSourceThreadLocalState** tls_state,
+      uint32_t* instances,
+      typename TracePointTraits::TracePointData trace_point_data) {
+    // See tracing_muxer.h for the structure of the TLS.
+    if (PERFETTO_UNLIKELY(!*tls_state)) {
+      *tls_state = GetOrCreateDataSourceTLS<DataSourceTraits>();
+      // If the TLS hasn't been obtained yet, it's possible that this thread
+      // hasn't observed the initialization of global state like the muxer yet.
+      // To ensure that the thread "sees" the effects of such initialization,
+      // we have to reload |instances| with an acquire fence, ensuring that any
+      // initialization performed before instances was updated is visible
+      // in this thread.
+      *instances &= TracePointTraits::GetActiveInstances(trace_point_data)
+                        ->load(std::memory_order_acquire);
+      if (!*instances)
+        return false;
+    }
+    auto* tracing_impl = TracingMuxer::Get();
+
+    // Avoid re-entering the trace point recursively.
+    if (PERFETTO_UNLIKELY((*tls_state)->root_tls->is_in_trace_point))
+      return false;
+
+    (*tls_state)->root_tls->is_in_trace_point = true;
+
+    // TracingTLS::generation is a global monotonic counter that is incremented
+    // every time a tracing session is stopped. We use that as a signal to force
+    // a slow-path garbage collection of all the trace writers for the current
+    // thread and to destroy the ones that belong to tracing sessions that have
+    // ended. This is to avoid having too many TraceWriter instances alive, each
+    // holding onto one chunk of the shared memory buffer.
+    // Rationale why memory_order_relaxed should be fine:
+    // - The TraceWriter object that we use is always constructed and destructed
+    //   on the current thread. There is no risk of accessing a half-initialized
+    //   TraceWriter (which would be really bad).
+    // - In the worst case, in the case of a race on the generation check, we
+    //   might end up using a TraceWriter for the same data source that belongs
+    //   to a stopped session. This is not really wrong, as we don't give any
+    //   guarantee on the global atomicity of the stop. In the worst case the
+    //   service will reject the data commit if this arrives too late.
+
+    if (PERFETTO_UNLIKELY(
+            (*tls_state)->root_tls->generation !=
+            tracing_impl->generation(std::memory_order_relaxed))) {
+      // Will update root_tls->generation.
+      tracing_impl->DestroyStoppedTraceWritersForCurrentThread();
+    }
+
+    return true;
+  }
+
+  // Must be called at the ending of a trace point that was not skipped.
+  void TraceEpilogue(DataSourceThreadLocalState* tls_state) {
+    tls_state->root_tls->is_in_trace_point = false;
+  }
+
+  struct InstancesIterator {
+    // A bitmap of the currenly active instances.
+    uint32_t cached_instances;
+    // The current instance index.
+    uint32_t i;
+    // The current instance. If this is `nullptr`, the iteration is over.
+    DataSourceInstanceThreadLocalState* instance;
+  };
+
+  // Returns an iterator to the active instances of this data source type.
+  //
+  // `cached_instances` is a copy of the bitmap of the active instances for this
+  // data source type (usually just a copy of ValidInstances(), but can be
+  // customized).
+  //
+  // `tls_state` is the thread local pointer obtained from TracePrologue.
+  //
+  // `TracePointTraits` and `trace_point_data` are customization point for
+  // getting the active instances bitmap.
+  template <typename TracePointTraits>
+  InstancesIterator BeginIteration(
+      uint32_t cached_instances,
+      DataSourceThreadLocalState* tls_state,
+      typename TracePointTraits::TracePointData trace_point_data) {
+    InstancesIterator it{};
+    it.cached_instances = cached_instances;
+    FirstActiveInstance<TracePointTraits>(&it, tls_state, trace_point_data);
+    return it;
+  }
+
+  // Advances `*iterator` to point to the next active instance of this data
+  // source type.
+  //
+  // `tls_state` is the thread local pointer obtained from TracePrologue.
+  //
+  // `TracePointTraits` and `trace_point_data` are customization point for
+  // getting the active instances bitmap.
+  template <typename TracePointTraits>
+  void NextIteration(
+      InstancesIterator* iterator,
+      DataSourceThreadLocalState* tls_state,
+      typename TracePointTraits::TracePointData trace_point_data) {
+    iterator->i++;
+    FirstActiveInstance<TracePointTraits>(iterator, tls_state,
+                                          trace_point_data);
+  }
+
+  void* GetIncrementalState(
+      internal::DataSourceInstanceThreadLocalState* tls_inst,
+      uint32_t instance_index) {
+    // Recreate incremental state data if it has been reset by the service.
+    if (tls_inst->incremental_state_generation !=
+        static_state()->incremental_state_generation.load(
+            std::memory_order_relaxed)) {
+      tls_inst->incremental_state.reset();
+      CreateIncrementalState(tls_inst, instance_index);
+    }
+    return tls_inst->incremental_state.get();
+  }
+
+  std::atomic<uint32_t>* valid_instances() { return &state_.valid_instances; }
+
+  DataSourceStaticState* static_state() { return &state_; }
+
+ private:
+  void CreateIncrementalState(
+      internal::DataSourceInstanceThreadLocalState* tls_inst,
+      uint32_t instance_index) {
+    PERFETTO_DCHECK(create_incremental_state_fn_ != nullptr);
+    tls_inst->incremental_state =
+        create_incremental_state_fn_(tls_inst, instance_index, user_arg_);
+    tls_inst->incremental_state_generation =
+        static_state()->incremental_state_generation.load(
+            std::memory_order_relaxed);
+  }
+
+  void PopulateTlsInst(DataSourceInstanceThreadLocalState* tls_inst,
+                       DataSourceState* instance_state,
+                       uint32_t instance_index);
+
+  // Advances `*iterator` to the first active instance whose index is greater or
+  // equal than `iterator->i`.
+  template <typename TracePointTraits>
+  void FirstActiveInstance(
+      InstancesIterator* iterator,
+      DataSourceThreadLocalState* tls_state,
+      typename TracePointTraits::TracePointData trace_point_data) {
+    iterator->instance = nullptr;
+    for (; iterator->i < kMaxDataSourceInstances; iterator->i++) {
+      DataSourceState* instance_state =
+          state_.TryGetCached(iterator->cached_instances, iterator->i);
+      if (!instance_state)
+        continue;
+      // Even if we passed the check above, the DataSourceInstance might be
+      // still destroyed concurrently while this code runs. The code below is
+      // designed to deal with such race, as follows:
+      // - We don't access the user-defined data source instance state. The only
+      //   bits of state we use are |backend_id| and |buffer_id|.
+      // - Beyond those two integers, we access only the TraceWriter here. The
+      //   TraceWriter is always safe because it lives on the TLS.
+      // - |instance_state| is backed by static storage, so the pointer is
+      //   always valid, even after the data source instance is destroyed.
+      // - In the case of a race-on-destruction, we'll still see the latest
+      //   backend_id and buffer_id and in the worst case keep trying writing
+      //   into the tracing shared memory buffer after stopped. But this isn't
+      //   really any worse than the case of the stop IPC being delayed by the
+      //   kernel scheduler. The tracing service is robust against data commit
+      //   attemps made after tracing is stopped.
+      // There is a theoretical race that would case the wrong behavior w.r.t
+      // writing data in the wrong buffer, but it's so rare that we ignore it:
+      // if the data source is stopped and started kMaxDataSourceInstances
+      // times (so that the same id is recycled) while we are in this function,
+      // we might end up reusing the old data source's backend_id and buffer_id
+      // for the new one, because we don't see the generation change past this
+      // point. But stopping and starting tracing (even once) takes so much
+      // handshaking to make this extremely unrealistic.
+
+      auto& tls_inst = tls_state->per_instance[iterator->i];
+      if (PERFETTO_UNLIKELY(!tls_inst.trace_writer)) {
+        // Here we need an acquire barrier, which matches the release-store made
+        // by TracingMuxerImpl::SetupDataSource(), to ensure that the backend_id
+        // and buffer_id are consistent.
+        iterator->cached_instances &=
+            TracePointTraits::GetActiveInstances(trace_point_data)
+                ->load(std::memory_order_acquire);
+        instance_state =
+            state_.TryGetCached(iterator->cached_instances, iterator->i);
+        if (!instance_state || !instance_state->trace_lambda_enabled.load(
+                                   std::memory_order_relaxed))
+          continue;
+        PopulateTlsInst(&tls_inst, instance_state, iterator->i);
+      }
+      iterator->instance = &tls_inst;
+      break;
+    }
+  }
+
+  // Note that the returned object is one per-thread per-data-source-type, NOT
+  // per data-source *instance*.
+  template <typename DataSourceTraits>
+  DataSourceThreadLocalState* GetOrCreateDataSourceTLS() {
+    auto* tracing_impl = TracingMuxer::Get();
+    TracingTLS* root_tls = tracing_impl->GetOrCreateTracingTLS();
+    DataSourceThreadLocalState* ds_tls =
+        DataSourceTraits::GetDataSourceTLS(&state_, root_tls);
+    // We keep re-initializing as the initialization is idempotent and not worth
+    // the code for extra checks. Also, ds_tls->static_state might point to
+    // another data source if ResetForTesting() has been used.
+    ds_tls->static_state = &state_;
+    assert(!ds_tls->root_tls || ds_tls->root_tls == root_tls);
+    ds_tls->root_tls = root_tls;
+    return ds_tls;
+  }
+
+  DataSourceStaticState state_;
+  BufferExhaustedPolicy buffer_exhausted_policy_{};
+  CreateCustomTlsFn create_custom_tls_fn_ = nullptr;
+  CreateIncrementalStateFn create_incremental_state_fn_ = nullptr;
+  // User defined pointer that carries extra content for the fn_ callbacks
+  // above. Only used in the C shared library.
+  void* user_arg_ = nullptr;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_DATA_SOURCE_TYPE_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/trace_packet.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidCameraFrameEvent;
+class AndroidCameraSessionStats;
+class AndroidEnergyEstimationBreakdown;
+class AndroidGameInterventionList;
+class AndroidLogPacket;
+class AndroidSystemProperty;
+class BatteryCounters;
+class ChromeBenchmarkMetadata;
+class ChromeEventBundle;
+class ChromeMetadataPacket;
+class ClockSnapshot;
+class CpuInfo;
+class DeobfuscationMapping;
+class EntityStateResidency;
+class EtwTraceEventBundle;
+class ExtensionDescriptor;
+class FrameTimelineEvent;
+class FtraceEventBundle;
+class FtraceStats;
+class GpuCounterEvent;
+class GpuLog;
+class GpuMemTotalEvent;
+class GpuRenderStageEvent;
+class GraphicsFrameEvent;
+class HeapGraph;
+class InitialDisplayState;
+class InodeFileMap;
+class InternedData;
+class LayersSnapshotProto;
+class MemoryTrackerSnapshot;
+class ModuleSymbols;
+class NetworkPacketBundle;
+class NetworkPacketEvent;
+class PackagesList;
+class PerfSample;
+class PerfettoMetatrace;
+class PowerRails;
+class ProcessDescriptor;
+class ProcessStats;
+class ProcessTree;
+class ProfilePacket;
+class ProfiledFrameSymbols;
+class ShellHandlerMappings;
+class ShellTransition;
+class SmapsPacket;
+class StatsdAtom;
+class StreamingAllocation;
+class StreamingFree;
+class StreamingProfilePacket;
+class SysStats;
+class SystemInfo;
+class TestEvent;
+class ThreadDescriptor;
+class TraceConfig;
+class TracePacketDefaults;
+class TraceStats;
+class TraceUuid;
+class TracingServiceEvent;
+class TrackDescriptor;
+class TrackEvent;
+class TrackEventRangeOfInterest;
+class TransactionTraceEntry;
+class TranslationTable;
+class Trigger;
+class UiState;
+class VulkanApiEvent;
+class VulkanMemoryEvent;
+
+namespace perfetto_pbzero_enum_TracePacket {
+enum SequenceFlags : int32_t {
+  SEQ_UNSPECIFIED = 0,
+  SEQ_INCREMENTAL_STATE_CLEARED = 1,
+  SEQ_NEEDS_INCREMENTAL_STATE = 2,
+};
+} // namespace perfetto_pbzero_enum_TracePacket
+using TracePacket_SequenceFlags = perfetto_pbzero_enum_TracePacket::SequenceFlags;
+
+
+constexpr TracePacket_SequenceFlags TracePacket_SequenceFlags_MIN = TracePacket_SequenceFlags::SEQ_UNSPECIFIED;
+constexpr TracePacket_SequenceFlags TracePacket_SequenceFlags_MAX = TracePacket_SequenceFlags::SEQ_NEEDS_INCREMENTAL_STATE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TracePacket_SequenceFlags_Name(::perfetto::protos::pbzero::TracePacket_SequenceFlags value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TracePacket_SequenceFlags::SEQ_UNSPECIFIED:
+    return "SEQ_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TracePacket_SequenceFlags::SEQ_INCREMENTAL_STATE_CLEARED:
+    return "SEQ_INCREMENTAL_STATE_CLEARED";
+
+  case ::perfetto::protos::pbzero::TracePacket_SequenceFlags::SEQ_NEEDS_INCREMENTAL_STATE:
+    return "SEQ_NEEDS_INCREMENTAL_STATE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class TracePacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/900, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracePacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracePacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracePacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timestamp() const { return at<8>().valid(); }
+  uint64_t timestamp() const { return at<8>().as_uint64(); }
+  bool has_timestamp_clock_id() const { return at<58>().valid(); }
+  uint32_t timestamp_clock_id() const { return at<58>().as_uint32(); }
+  bool has_process_tree() const { return at<2>().valid(); }
+  ::protozero::ConstBytes process_tree() const { return at<2>().as_bytes(); }
+  bool has_process_stats() const { return at<9>().valid(); }
+  ::protozero::ConstBytes process_stats() const { return at<9>().as_bytes(); }
+  bool has_inode_file_map() const { return at<4>().valid(); }
+  ::protozero::ConstBytes inode_file_map() const { return at<4>().as_bytes(); }
+  bool has_chrome_events() const { return at<5>().valid(); }
+  ::protozero::ConstBytes chrome_events() const { return at<5>().as_bytes(); }
+  bool has_clock_snapshot() const { return at<6>().valid(); }
+  ::protozero::ConstBytes clock_snapshot() const { return at<6>().as_bytes(); }
+  bool has_sys_stats() const { return at<7>().valid(); }
+  ::protozero::ConstBytes sys_stats() const { return at<7>().as_bytes(); }
+  bool has_track_event() const { return at<11>().valid(); }
+  ::protozero::ConstBytes track_event() const { return at<11>().as_bytes(); }
+  bool has_trace_uuid() const { return at<89>().valid(); }
+  ::protozero::ConstBytes trace_uuid() const { return at<89>().as_bytes(); }
+  bool has_trace_config() const { return at<33>().valid(); }
+  ::protozero::ConstBytes trace_config() const { return at<33>().as_bytes(); }
+  bool has_ftrace_stats() const { return at<34>().valid(); }
+  ::protozero::ConstBytes ftrace_stats() const { return at<34>().as_bytes(); }
+  bool has_trace_stats() const { return at<35>().valid(); }
+  ::protozero::ConstBytes trace_stats() const { return at<35>().as_bytes(); }
+  bool has_profile_packet() const { return at<37>().valid(); }
+  ::protozero::ConstBytes profile_packet() const { return at<37>().as_bytes(); }
+  bool has_streaming_allocation() const { return at<74>().valid(); }
+  ::protozero::ConstBytes streaming_allocation() const { return at<74>().as_bytes(); }
+  bool has_streaming_free() const { return at<75>().valid(); }
+  ::protozero::ConstBytes streaming_free() const { return at<75>().as_bytes(); }
+  bool has_battery() const { return at<38>().valid(); }
+  ::protozero::ConstBytes battery() const { return at<38>().as_bytes(); }
+  bool has_power_rails() const { return at<40>().valid(); }
+  ::protozero::ConstBytes power_rails() const { return at<40>().as_bytes(); }
+  bool has_android_log() const { return at<39>().valid(); }
+  ::protozero::ConstBytes android_log() const { return at<39>().as_bytes(); }
+  bool has_system_info() const { return at<45>().valid(); }
+  ::protozero::ConstBytes system_info() const { return at<45>().as_bytes(); }
+  bool has_trigger() const { return at<46>().valid(); }
+  ::protozero::ConstBytes trigger() const { return at<46>().as_bytes(); }
+  bool has_packages_list() const { return at<47>().valid(); }
+  ::protozero::ConstBytes packages_list() const { return at<47>().as_bytes(); }
+  bool has_chrome_benchmark_metadata() const { return at<48>().valid(); }
+  ::protozero::ConstBytes chrome_benchmark_metadata() const { return at<48>().as_bytes(); }
+  bool has_perfetto_metatrace() const { return at<49>().valid(); }
+  ::protozero::ConstBytes perfetto_metatrace() const { return at<49>().as_bytes(); }
+  bool has_chrome_metadata() const { return at<51>().valid(); }
+  ::protozero::ConstBytes chrome_metadata() const { return at<51>().as_bytes(); }
+  bool has_gpu_counter_event() const { return at<52>().valid(); }
+  ::protozero::ConstBytes gpu_counter_event() const { return at<52>().as_bytes(); }
+  bool has_gpu_render_stage_event() const { return at<53>().valid(); }
+  ::protozero::ConstBytes gpu_render_stage_event() const { return at<53>().as_bytes(); }
+  bool has_streaming_profile_packet() const { return at<54>().valid(); }
+  ::protozero::ConstBytes streaming_profile_packet() const { return at<54>().as_bytes(); }
+  bool has_heap_graph() const { return at<56>().valid(); }
+  ::protozero::ConstBytes heap_graph() const { return at<56>().as_bytes(); }
+  bool has_graphics_frame_event() const { return at<57>().valid(); }
+  ::protozero::ConstBytes graphics_frame_event() const { return at<57>().as_bytes(); }
+  bool has_vulkan_memory_event() const { return at<62>().valid(); }
+  ::protozero::ConstBytes vulkan_memory_event() const { return at<62>().as_bytes(); }
+  bool has_gpu_log() const { return at<63>().valid(); }
+  ::protozero::ConstBytes gpu_log() const { return at<63>().as_bytes(); }
+  bool has_vulkan_api_event() const { return at<65>().valid(); }
+  ::protozero::ConstBytes vulkan_api_event() const { return at<65>().as_bytes(); }
+  bool has_perf_sample() const { return at<66>().valid(); }
+  ::protozero::ConstBytes perf_sample() const { return at<66>().as_bytes(); }
+  bool has_cpu_info() const { return at<67>().valid(); }
+  ::protozero::ConstBytes cpu_info() const { return at<67>().as_bytes(); }
+  bool has_smaps_packet() const { return at<68>().valid(); }
+  ::protozero::ConstBytes smaps_packet() const { return at<68>().as_bytes(); }
+  bool has_service_event() const { return at<69>().valid(); }
+  ::protozero::ConstBytes service_event() const { return at<69>().as_bytes(); }
+  bool has_initial_display_state() const { return at<70>().valid(); }
+  ::protozero::ConstBytes initial_display_state() const { return at<70>().as_bytes(); }
+  bool has_gpu_mem_total_event() const { return at<71>().valid(); }
+  ::protozero::ConstBytes gpu_mem_total_event() const { return at<71>().as_bytes(); }
+  bool has_memory_tracker_snapshot() const { return at<73>().valid(); }
+  ::protozero::ConstBytes memory_tracker_snapshot() const { return at<73>().as_bytes(); }
+  bool has_frame_timeline_event() const { return at<76>().valid(); }
+  ::protozero::ConstBytes frame_timeline_event() const { return at<76>().as_bytes(); }
+  bool has_android_energy_estimation_breakdown() const { return at<77>().valid(); }
+  ::protozero::ConstBytes android_energy_estimation_breakdown() const { return at<77>().as_bytes(); }
+  bool has_ui_state() const { return at<78>().valid(); }
+  ::protozero::ConstBytes ui_state() const { return at<78>().as_bytes(); }
+  bool has_android_camera_frame_event() const { return at<80>().valid(); }
+  ::protozero::ConstBytes android_camera_frame_event() const { return at<80>().as_bytes(); }
+  bool has_android_camera_session_stats() const { return at<81>().valid(); }
+  ::protozero::ConstBytes android_camera_session_stats() const { return at<81>().as_bytes(); }
+  bool has_translation_table() const { return at<82>().valid(); }
+  ::protozero::ConstBytes translation_table() const { return at<82>().as_bytes(); }
+  bool has_android_game_intervention_list() const { return at<83>().valid(); }
+  ::protozero::ConstBytes android_game_intervention_list() const { return at<83>().as_bytes(); }
+  bool has_statsd_atom() const { return at<84>().valid(); }
+  ::protozero::ConstBytes statsd_atom() const { return at<84>().as_bytes(); }
+  bool has_android_system_property() const { return at<86>().valid(); }
+  ::protozero::ConstBytes android_system_property() const { return at<86>().as_bytes(); }
+  bool has_entity_state_residency() const { return at<91>().valid(); }
+  ::protozero::ConstBytes entity_state_residency() const { return at<91>().as_bytes(); }
+  bool has_profiled_frame_symbols() const { return at<55>().valid(); }
+  ::protozero::ConstBytes profiled_frame_symbols() const { return at<55>().as_bytes(); }
+  bool has_module_symbols() const { return at<61>().valid(); }
+  ::protozero::ConstBytes module_symbols() const { return at<61>().as_bytes(); }
+  bool has_deobfuscation_mapping() const { return at<64>().valid(); }
+  ::protozero::ConstBytes deobfuscation_mapping() const { return at<64>().as_bytes(); }
+  bool has_track_descriptor() const { return at<60>().valid(); }
+  ::protozero::ConstBytes track_descriptor() const { return at<60>().as_bytes(); }
+  bool has_process_descriptor() const { return at<43>().valid(); }
+  ::protozero::ConstBytes process_descriptor() const { return at<43>().as_bytes(); }
+  bool has_thread_descriptor() const { return at<44>().valid(); }
+  ::protozero::ConstBytes thread_descriptor() const { return at<44>().as_bytes(); }
+  bool has_ftrace_events() const { return at<1>().valid(); }
+  ::protozero::ConstBytes ftrace_events() const { return at<1>().as_bytes(); }
+  bool has_synchronization_marker() const { return at<36>().valid(); }
+  ::protozero::ConstBytes synchronization_marker() const { return at<36>().as_bytes(); }
+  bool has_compressed_packets() const { return at<50>().valid(); }
+  ::protozero::ConstBytes compressed_packets() const { return at<50>().as_bytes(); }
+  bool has_extension_descriptor() const { return at<72>().valid(); }
+  ::protozero::ConstBytes extension_descriptor() const { return at<72>().as_bytes(); }
+  bool has_network_packet() const { return at<88>().valid(); }
+  ::protozero::ConstBytes network_packet() const { return at<88>().as_bytes(); }
+  bool has_network_packet_bundle() const { return at<92>().valid(); }
+  ::protozero::ConstBytes network_packet_bundle() const { return at<92>().as_bytes(); }
+  bool has_track_event_range_of_interest() const { return at<90>().valid(); }
+  ::protozero::ConstBytes track_event_range_of_interest() const { return at<90>().as_bytes(); }
+  bool has_surfaceflinger_layers_snapshot() const { return at<93>().valid(); }
+  ::protozero::ConstBytes surfaceflinger_layers_snapshot() const { return at<93>().as_bytes(); }
+  bool has_surfaceflinger_transactions() const { return at<94>().valid(); }
+  ::protozero::ConstBytes surfaceflinger_transactions() const { return at<94>().as_bytes(); }
+  bool has_shell_transition() const { return at<96>().valid(); }
+  ::protozero::ConstBytes shell_transition() const { return at<96>().as_bytes(); }
+  bool has_shell_handler_mappings() const { return at<97>().valid(); }
+  ::protozero::ConstBytes shell_handler_mappings() const { return at<97>().as_bytes(); }
+  bool has_etw_events() const { return at<95>().valid(); }
+  ::protozero::ConstBytes etw_events() const { return at<95>().as_bytes(); }
+  bool has_for_testing() const { return at<900>().valid(); }
+  ::protozero::ConstBytes for_testing() const { return at<900>().as_bytes(); }
+  bool has_trusted_uid() const { return at<3>().valid(); }
+  int32_t trusted_uid() const { return at<3>().as_int32(); }
+  bool has_trusted_packet_sequence_id() const { return at<10>().valid(); }
+  uint32_t trusted_packet_sequence_id() const { return at<10>().as_uint32(); }
+  bool has_trusted_pid() const { return at<79>().valid(); }
+  int32_t trusted_pid() const { return at<79>().as_int32(); }
+  bool has_interned_data() const { return at<12>().valid(); }
+  ::protozero::ConstBytes interned_data() const { return at<12>().as_bytes(); }
+  bool has_sequence_flags() const { return at<13>().valid(); }
+  uint32_t sequence_flags() const { return at<13>().as_uint32(); }
+  bool has_incremental_state_cleared() const { return at<41>().valid(); }
+  bool incremental_state_cleared() const { return at<41>().as_bool(); }
+  bool has_trace_packet_defaults() const { return at<59>().valid(); }
+  ::protozero::ConstBytes trace_packet_defaults() const { return at<59>().as_bytes(); }
+  bool has_previous_packet_dropped() const { return at<42>().valid(); }
+  bool previous_packet_dropped() const { return at<42>().as_bool(); }
+  bool has_first_packet_on_sequence() const { return at<87>().valid(); }
+  bool first_packet_on_sequence() const { return at<87>().as_bool(); }
+  bool has_machine_id() const { return at<98>().valid(); }
+  uint32_t machine_id() const { return at<98>().as_uint32(); }
+};
+
+class TracePacket : public ::protozero::Message {
+ public:
+  using Decoder = TracePacket_Decoder;
+  enum : int32_t {
+    kTimestampFieldNumber = 8,
+    kTimestampClockIdFieldNumber = 58,
+    kProcessTreeFieldNumber = 2,
+    kProcessStatsFieldNumber = 9,
+    kInodeFileMapFieldNumber = 4,
+    kChromeEventsFieldNumber = 5,
+    kClockSnapshotFieldNumber = 6,
+    kSysStatsFieldNumber = 7,
+    kTrackEventFieldNumber = 11,
+    kTraceUuidFieldNumber = 89,
+    kTraceConfigFieldNumber = 33,
+    kFtraceStatsFieldNumber = 34,
+    kTraceStatsFieldNumber = 35,
+    kProfilePacketFieldNumber = 37,
+    kStreamingAllocationFieldNumber = 74,
+    kStreamingFreeFieldNumber = 75,
+    kBatteryFieldNumber = 38,
+    kPowerRailsFieldNumber = 40,
+    kAndroidLogFieldNumber = 39,
+    kSystemInfoFieldNumber = 45,
+    kTriggerFieldNumber = 46,
+    kPackagesListFieldNumber = 47,
+    kChromeBenchmarkMetadataFieldNumber = 48,
+    kPerfettoMetatraceFieldNumber = 49,
+    kChromeMetadataFieldNumber = 51,
+    kGpuCounterEventFieldNumber = 52,
+    kGpuRenderStageEventFieldNumber = 53,
+    kStreamingProfilePacketFieldNumber = 54,
+    kHeapGraphFieldNumber = 56,
+    kGraphicsFrameEventFieldNumber = 57,
+    kVulkanMemoryEventFieldNumber = 62,
+    kGpuLogFieldNumber = 63,
+    kVulkanApiEventFieldNumber = 65,
+    kPerfSampleFieldNumber = 66,
+    kCpuInfoFieldNumber = 67,
+    kSmapsPacketFieldNumber = 68,
+    kServiceEventFieldNumber = 69,
+    kInitialDisplayStateFieldNumber = 70,
+    kGpuMemTotalEventFieldNumber = 71,
+    kMemoryTrackerSnapshotFieldNumber = 73,
+    kFrameTimelineEventFieldNumber = 76,
+    kAndroidEnergyEstimationBreakdownFieldNumber = 77,
+    kUiStateFieldNumber = 78,
+    kAndroidCameraFrameEventFieldNumber = 80,
+    kAndroidCameraSessionStatsFieldNumber = 81,
+    kTranslationTableFieldNumber = 82,
+    kAndroidGameInterventionListFieldNumber = 83,
+    kStatsdAtomFieldNumber = 84,
+    kAndroidSystemPropertyFieldNumber = 86,
+    kEntityStateResidencyFieldNumber = 91,
+    kProfiledFrameSymbolsFieldNumber = 55,
+    kModuleSymbolsFieldNumber = 61,
+    kDeobfuscationMappingFieldNumber = 64,
+    kTrackDescriptorFieldNumber = 60,
+    kProcessDescriptorFieldNumber = 43,
+    kThreadDescriptorFieldNumber = 44,
+    kFtraceEventsFieldNumber = 1,
+    kSynchronizationMarkerFieldNumber = 36,
+    kCompressedPacketsFieldNumber = 50,
+    kExtensionDescriptorFieldNumber = 72,
+    kNetworkPacketFieldNumber = 88,
+    kNetworkPacketBundleFieldNumber = 92,
+    kTrackEventRangeOfInterestFieldNumber = 90,
+    kSurfaceflingerLayersSnapshotFieldNumber = 93,
+    kSurfaceflingerTransactionsFieldNumber = 94,
+    kShellTransitionFieldNumber = 96,
+    kShellHandlerMappingsFieldNumber = 97,
+    kEtwEventsFieldNumber = 95,
+    kForTestingFieldNumber = 900,
+    kTrustedUidFieldNumber = 3,
+    kTrustedPacketSequenceIdFieldNumber = 10,
+    kTrustedPidFieldNumber = 79,
+    kInternedDataFieldNumber = 12,
+    kSequenceFlagsFieldNumber = 13,
+    kIncrementalStateClearedFieldNumber = 41,
+    kTracePacketDefaultsFieldNumber = 59,
+    kPreviousPacketDroppedFieldNumber = 42,
+    kFirstPacketOnSequenceFieldNumber = 87,
+    kMachineIdFieldNumber = 98,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracePacket"; }
+
+
+  using SequenceFlags = ::perfetto::protos::pbzero::TracePacket_SequenceFlags;
+  static inline const char* SequenceFlags_Name(SequenceFlags value) {
+    return ::perfetto::protos::pbzero::TracePacket_SequenceFlags_Name(value);
+  }
+  static inline const SequenceFlags SEQ_UNSPECIFIED = SequenceFlags::SEQ_UNSPECIFIED;
+  static inline const SequenceFlags SEQ_INCREMENTAL_STATE_CLEARED = SequenceFlags::SEQ_INCREMENTAL_STATE_CLEARED;
+  static inline const SequenceFlags SEQ_NEEDS_INCREMENTAL_STATE = SequenceFlags::SEQ_NEEDS_INCREMENTAL_STATE;
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimestampClockId =
+    ::protozero::proto_utils::FieldMetadata<
+      58,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TimestampClockId kTimestampClockId{};
+  void set_timestamp_clock_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampClockId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessTree =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessTree,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProcessTree kProcessTree{};
+  template <typename T = ProcessTree> T* set_process_tree() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ProcessStats =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessStats,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProcessStats kProcessStats{};
+  template <typename T = ProcessStats> T* set_process_stats() {
+    return BeginNestedMessage<T>(9);
+  }
+
+
+  using FieldMetadata_InodeFileMap =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InodeFileMap,
+      TracePacket>;
+
+  static constexpr FieldMetadata_InodeFileMap kInodeFileMap{};
+  template <typename T = InodeFileMap> T* set_inode_file_map() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_ChromeEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeEventBundle,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ChromeEvents kChromeEvents{};
+  template <typename T = ChromeEventBundle> T* set_chrome_events() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_ClockSnapshot =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockSnapshot,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ClockSnapshot kClockSnapshot{};
+  template <typename T = ClockSnapshot> T* set_clock_snapshot() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_SysStats =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SysStats kSysStats{};
+  template <typename T = SysStats> T* set_sys_stats() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_TrackEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrackEvent kTrackEvent{};
+  template <typename T = TrackEvent> T* set_track_event() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_TraceUuid =
+    ::protozero::proto_utils::FieldMetadata<
+      89,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceUuid,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TraceUuid kTraceUuid{};
+  template <typename T = TraceUuid> T* set_trace_uuid() {
+    return BeginNestedMessage<T>(89);
+  }
+
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TraceConfig kTraceConfig{};
+  template <typename T = TraceConfig> T* set_trace_config() {
+    return BeginNestedMessage<T>(33);
+  }
+
+
+  using FieldMetadata_FtraceStats =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceStats,
+      TracePacket>;
+
+  static constexpr FieldMetadata_FtraceStats kFtraceStats{};
+  template <typename T = FtraceStats> T* set_ftrace_stats() {
+    return BeginNestedMessage<T>(34);
+  }
+
+
+  using FieldMetadata_TraceStats =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceStats,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TraceStats kTraceStats{};
+  template <typename T = TraceStats> T* set_trace_stats() {
+    return BeginNestedMessage<T>(35);
+  }
+
+
+  using FieldMetadata_ProfilePacket =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProfilePacket kProfilePacket{};
+  template <typename T = ProfilePacket> T* set_profile_packet() {
+    return BeginNestedMessage<T>(37);
+  }
+
+
+  using FieldMetadata_StreamingAllocation =
+    ::protozero::proto_utils::FieldMetadata<
+      74,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StreamingAllocation,
+      TracePacket>;
+
+  static constexpr FieldMetadata_StreamingAllocation kStreamingAllocation{};
+  template <typename T = StreamingAllocation> T* set_streaming_allocation() {
+    return BeginNestedMessage<T>(74);
+  }
+
+
+  using FieldMetadata_StreamingFree =
+    ::protozero::proto_utils::FieldMetadata<
+      75,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StreamingFree,
+      TracePacket>;
+
+  static constexpr FieldMetadata_StreamingFree kStreamingFree{};
+  template <typename T = StreamingFree> T* set_streaming_free() {
+    return BeginNestedMessage<T>(75);
+  }
+
+
+  using FieldMetadata_Battery =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BatteryCounters,
+      TracePacket>;
+
+  static constexpr FieldMetadata_Battery kBattery{};
+  template <typename T = BatteryCounters> T* set_battery() {
+    return BeginNestedMessage<T>(38);
+  }
+
+
+  using FieldMetadata_PowerRails =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PowerRails,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PowerRails kPowerRails{};
+  template <typename T = PowerRails> T* set_power_rails() {
+    return BeginNestedMessage<T>(40);
+  }
+
+
+  using FieldMetadata_AndroidLog =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidLogPacket,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidLog kAndroidLog{};
+  template <typename T = AndroidLogPacket> T* set_android_log() {
+    return BeginNestedMessage<T>(39);
+  }
+
+
+  using FieldMetadata_SystemInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SystemInfo,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SystemInfo kSystemInfo{};
+  template <typename T = SystemInfo> T* set_system_info() {
+    return BeginNestedMessage<T>(45);
+  }
+
+
+  using FieldMetadata_Trigger =
+    ::protozero::proto_utils::FieldMetadata<
+      46,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Trigger,
+      TracePacket>;
+
+  static constexpr FieldMetadata_Trigger kTrigger{};
+  template <typename T = Trigger> T* set_trigger() {
+    return BeginNestedMessage<T>(46);
+  }
+
+
+  using FieldMetadata_PackagesList =
+    ::protozero::proto_utils::FieldMetadata<
+      47,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PackagesList,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PackagesList kPackagesList{};
+  template <typename T = PackagesList> T* set_packages_list() {
+    return BeginNestedMessage<T>(47);
+  }
+
+
+  using FieldMetadata_ChromeBenchmarkMetadata =
+    ::protozero::proto_utils::FieldMetadata<
+      48,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeBenchmarkMetadata,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ChromeBenchmarkMetadata kChromeBenchmarkMetadata{};
+  template <typename T = ChromeBenchmarkMetadata> T* set_chrome_benchmark_metadata() {
+    return BeginNestedMessage<T>(48);
+  }
+
+
+  using FieldMetadata_PerfettoMetatrace =
+    ::protozero::proto_utils::FieldMetadata<
+      49,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfettoMetatrace,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PerfettoMetatrace kPerfettoMetatrace{};
+  template <typename T = PerfettoMetatrace> T* set_perfetto_metatrace() {
+    return BeginNestedMessage<T>(49);
+  }
+
+
+  using FieldMetadata_ChromeMetadata =
+    ::protozero::proto_utils::FieldMetadata<
+      51,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeMetadataPacket,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ChromeMetadata kChromeMetadata{};
+  template <typename T = ChromeMetadataPacket> T* set_chrome_metadata() {
+    return BeginNestedMessage<T>(51);
+  }
+
+
+  using FieldMetadata_GpuCounterEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      52,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_GpuCounterEvent kGpuCounterEvent{};
+  template <typename T = GpuCounterEvent> T* set_gpu_counter_event() {
+    return BeginNestedMessage<T>(52);
+  }
+
+
+  using FieldMetadata_GpuRenderStageEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      53,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_GpuRenderStageEvent kGpuRenderStageEvent{};
+  template <typename T = GpuRenderStageEvent> T* set_gpu_render_stage_event() {
+    return BeginNestedMessage<T>(53);
+  }
+
+
+  using FieldMetadata_StreamingProfilePacket =
+    ::protozero::proto_utils::FieldMetadata<
+      54,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StreamingProfilePacket,
+      TracePacket>;
+
+  static constexpr FieldMetadata_StreamingProfilePacket kStreamingProfilePacket{};
+  template <typename T = StreamingProfilePacket> T* set_streaming_profile_packet() {
+    return BeginNestedMessage<T>(54);
+  }
+
+
+  using FieldMetadata_HeapGraph =
+    ::protozero::proto_utils::FieldMetadata<
+      56,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapGraph,
+      TracePacket>;
+
+  static constexpr FieldMetadata_HeapGraph kHeapGraph{};
+  template <typename T = HeapGraph> T* set_heap_graph() {
+    return BeginNestedMessage<T>(56);
+  }
+
+
+  using FieldMetadata_GraphicsFrameEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      57,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GraphicsFrameEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_GraphicsFrameEvent kGraphicsFrameEvent{};
+  template <typename T = GraphicsFrameEvent> T* set_graphics_frame_event() {
+    return BeginNestedMessage<T>(57);
+  }
+
+
+  using FieldMetadata_VulkanMemoryEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      62,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanMemoryEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_VulkanMemoryEvent kVulkanMemoryEvent{};
+  template <typename T = VulkanMemoryEvent> T* set_vulkan_memory_event() {
+    return BeginNestedMessage<T>(62);
+  }
+
+
+  using FieldMetadata_GpuLog =
+    ::protozero::proto_utils::FieldMetadata<
+      63,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuLog,
+      TracePacket>;
+
+  static constexpr FieldMetadata_GpuLog kGpuLog{};
+  template <typename T = GpuLog> T* set_gpu_log() {
+    return BeginNestedMessage<T>(63);
+  }
+
+
+  using FieldMetadata_VulkanApiEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      65,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanApiEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_VulkanApiEvent kVulkanApiEvent{};
+  template <typename T = VulkanApiEvent> T* set_vulkan_api_event() {
+    return BeginNestedMessage<T>(65);
+  }
+
+
+  using FieldMetadata_PerfSample =
+    ::protozero::proto_utils::FieldMetadata<
+      66,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfSample,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PerfSample kPerfSample{};
+  template <typename T = PerfSample> T* set_perf_sample() {
+    return BeginNestedMessage<T>(66);
+  }
+
+
+  using FieldMetadata_CpuInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      67,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuInfo,
+      TracePacket>;
+
+  static constexpr FieldMetadata_CpuInfo kCpuInfo{};
+  template <typename T = CpuInfo> T* set_cpu_info() {
+    return BeginNestedMessage<T>(67);
+  }
+
+
+  using FieldMetadata_SmapsPacket =
+    ::protozero::proto_utils::FieldMetadata<
+      68,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmapsPacket,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SmapsPacket kSmapsPacket{};
+  template <typename T = SmapsPacket> T* set_smaps_packet() {
+    return BeginNestedMessage<T>(68);
+  }
+
+
+  using FieldMetadata_ServiceEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      69,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingServiceEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ServiceEvent kServiceEvent{};
+  template <typename T = TracingServiceEvent> T* set_service_event() {
+    return BeginNestedMessage<T>(69);
+  }
+
+
+  using FieldMetadata_InitialDisplayState =
+    ::protozero::proto_utils::FieldMetadata<
+      70,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InitialDisplayState,
+      TracePacket>;
+
+  static constexpr FieldMetadata_InitialDisplayState kInitialDisplayState{};
+  template <typename T = InitialDisplayState> T* set_initial_display_state() {
+    return BeginNestedMessage<T>(70);
+  }
+
+
+  using FieldMetadata_GpuMemTotalEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      71,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuMemTotalEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_GpuMemTotalEvent kGpuMemTotalEvent{};
+  template <typename T = GpuMemTotalEvent> T* set_gpu_mem_total_event() {
+    return BeginNestedMessage<T>(71);
+  }
+
+
+  using FieldMetadata_MemoryTrackerSnapshot =
+    ::protozero::proto_utils::FieldMetadata<
+      73,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MemoryTrackerSnapshot,
+      TracePacket>;
+
+  static constexpr FieldMetadata_MemoryTrackerSnapshot kMemoryTrackerSnapshot{};
+  template <typename T = MemoryTrackerSnapshot> T* set_memory_tracker_snapshot() {
+    return BeginNestedMessage<T>(73);
+  }
+
+
+  using FieldMetadata_FrameTimelineEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      76,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_FrameTimelineEvent kFrameTimelineEvent{};
+  template <typename T = FrameTimelineEvent> T* set_frame_timeline_event() {
+    return BeginNestedMessage<T>(76);
+  }
+
+
+  using FieldMetadata_AndroidEnergyEstimationBreakdown =
+    ::protozero::proto_utils::FieldMetadata<
+      77,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidEnergyEstimationBreakdown,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidEnergyEstimationBreakdown kAndroidEnergyEstimationBreakdown{};
+  template <typename T = AndroidEnergyEstimationBreakdown> T* set_android_energy_estimation_breakdown() {
+    return BeginNestedMessage<T>(77);
+  }
+
+
+  using FieldMetadata_UiState =
+    ::protozero::proto_utils::FieldMetadata<
+      78,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UiState,
+      TracePacket>;
+
+  static constexpr FieldMetadata_UiState kUiState{};
+  template <typename T = UiState> T* set_ui_state() {
+    return BeginNestedMessage<T>(78);
+  }
+
+
+  using FieldMetadata_AndroidCameraFrameEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      80,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraFrameEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidCameraFrameEvent kAndroidCameraFrameEvent{};
+  template <typename T = AndroidCameraFrameEvent> T* set_android_camera_frame_event() {
+    return BeginNestedMessage<T>(80);
+  }
+
+
+  using FieldMetadata_AndroidCameraSessionStats =
+    ::protozero::proto_utils::FieldMetadata<
+      81,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraSessionStats,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidCameraSessionStats kAndroidCameraSessionStats{};
+  template <typename T = AndroidCameraSessionStats> T* set_android_camera_session_stats() {
+    return BeginNestedMessage<T>(81);
+  }
+
+
+  using FieldMetadata_TranslationTable =
+    ::protozero::proto_utils::FieldMetadata<
+      82,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TranslationTable,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TranslationTable kTranslationTable{};
+  template <typename T = TranslationTable> T* set_translation_table() {
+    return BeginNestedMessage<T>(82);
+  }
+
+
+  using FieldMetadata_AndroidGameInterventionList =
+    ::protozero::proto_utils::FieldMetadata<
+      83,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidGameInterventionList,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidGameInterventionList kAndroidGameInterventionList{};
+  template <typename T = AndroidGameInterventionList> T* set_android_game_intervention_list() {
+    return BeginNestedMessage<T>(83);
+  }
+
+
+  using FieldMetadata_StatsdAtom =
+    ::protozero::proto_utils::FieldMetadata<
+      84,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StatsdAtom,
+      TracePacket>;
+
+  static constexpr FieldMetadata_StatsdAtom kStatsdAtom{};
+  template <typename T = StatsdAtom> T* set_statsd_atom() {
+    return BeginNestedMessage<T>(84);
+  }
+
+
+  using FieldMetadata_AndroidSystemProperty =
+    ::protozero::proto_utils::FieldMetadata<
+      86,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidSystemProperty,
+      TracePacket>;
+
+  static constexpr FieldMetadata_AndroidSystemProperty kAndroidSystemProperty{};
+  template <typename T = AndroidSystemProperty> T* set_android_system_property() {
+    return BeginNestedMessage<T>(86);
+  }
+
+
+  using FieldMetadata_EntityStateResidency =
+    ::protozero::proto_utils::FieldMetadata<
+      91,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EntityStateResidency,
+      TracePacket>;
+
+  static constexpr FieldMetadata_EntityStateResidency kEntityStateResidency{};
+  template <typename T = EntityStateResidency> T* set_entity_state_residency() {
+    return BeginNestedMessage<T>(91);
+  }
+
+
+  using FieldMetadata_ProfiledFrameSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      55,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfiledFrameSymbols,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProfiledFrameSymbols kProfiledFrameSymbols{};
+  template <typename T = ProfiledFrameSymbols> T* set_profiled_frame_symbols() {
+    return BeginNestedMessage<T>(55);
+  }
+
+
+  using FieldMetadata_ModuleSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      61,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ModuleSymbols,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ModuleSymbols kModuleSymbols{};
+  template <typename T = ModuleSymbols> T* set_module_symbols() {
+    return BeginNestedMessage<T>(61);
+  }
+
+
+  using FieldMetadata_DeobfuscationMapping =
+    ::protozero::proto_utils::FieldMetadata<
+      64,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DeobfuscationMapping,
+      TracePacket>;
+
+  static constexpr FieldMetadata_DeobfuscationMapping kDeobfuscationMapping{};
+  template <typename T = DeobfuscationMapping> T* set_deobfuscation_mapping() {
+    return BeginNestedMessage<T>(64);
+  }
+
+
+  using FieldMetadata_TrackDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      60,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackDescriptor,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrackDescriptor kTrackDescriptor{};
+  template <typename T = TrackDescriptor> T* set_track_descriptor() {
+    return BeginNestedMessage<T>(60);
+  }
+
+
+  using FieldMetadata_ProcessDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      43,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessDescriptor,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ProcessDescriptor kProcessDescriptor{};
+  template <typename T = ProcessDescriptor> T* set_process_descriptor() {
+    return BeginNestedMessage<T>(43);
+  }
+
+
+  using FieldMetadata_ThreadDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      44,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ThreadDescriptor,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ThreadDescriptor kThreadDescriptor{};
+  template <typename T = ThreadDescriptor> T* set_thread_descriptor() {
+    return BeginNestedMessage<T>(44);
+  }
+
+
+  using FieldMetadata_FtraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceEventBundle,
+      TracePacket>;
+
+  static constexpr FieldMetadata_FtraceEvents kFtraceEvents{};
+  template <typename T = FtraceEventBundle> T* set_ftrace_events() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_SynchronizationMarker =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SynchronizationMarker kSynchronizationMarker{};
+  void set_synchronization_marker(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_SynchronizationMarker::kFieldId, data, size);
+  }
+  void set_synchronization_marker(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_SynchronizationMarker::kFieldId, bytes.data, bytes.size);
+  }
+  void set_synchronization_marker(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SynchronizationMarker::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CompressedPackets =
+    ::protozero::proto_utils::FieldMetadata<
+      50,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TracePacket>;
+
+  static constexpr FieldMetadata_CompressedPackets kCompressedPackets{};
+  void set_compressed_packets(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_CompressedPackets::kFieldId, data, size);
+  }
+  void set_compressed_packets(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_CompressedPackets::kFieldId, bytes.data, bytes.size);
+  }
+  void set_compressed_packets(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_CompressedPackets::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExtensionDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      72,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ExtensionDescriptor,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ExtensionDescriptor kExtensionDescriptor{};
+  template <typename T = ExtensionDescriptor> T* set_extension_descriptor() {
+    return BeginNestedMessage<T>(72);
+  }
+
+
+  using FieldMetadata_NetworkPacket =
+    ::protozero::proto_utils::FieldMetadata<
+      88,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_NetworkPacket kNetworkPacket{};
+  template <typename T = NetworkPacketEvent> T* set_network_packet() {
+    return BeginNestedMessage<T>(88);
+  }
+
+
+  using FieldMetadata_NetworkPacketBundle =
+    ::protozero::proto_utils::FieldMetadata<
+      92,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketBundle,
+      TracePacket>;
+
+  static constexpr FieldMetadata_NetworkPacketBundle kNetworkPacketBundle{};
+  template <typename T = NetworkPacketBundle> T* set_network_packet_bundle() {
+    return BeginNestedMessage<T>(92);
+  }
+
+
+  using FieldMetadata_TrackEventRangeOfInterest =
+    ::protozero::proto_utils::FieldMetadata<
+      90,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventRangeOfInterest,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrackEventRangeOfInterest kTrackEventRangeOfInterest{};
+  template <typename T = TrackEventRangeOfInterest> T* set_track_event_range_of_interest() {
+    return BeginNestedMessage<T>(90);
+  }
+
+
+  using FieldMetadata_SurfaceflingerLayersSnapshot =
+    ::protozero::proto_utils::FieldMetadata<
+      93,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayersSnapshotProto,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SurfaceflingerLayersSnapshot kSurfaceflingerLayersSnapshot{};
+  template <typename T = LayersSnapshotProto> T* set_surfaceflinger_layers_snapshot() {
+    return BeginNestedMessage<T>(93);
+  }
+
+
+  using FieldMetadata_SurfaceflingerTransactions =
+    ::protozero::proto_utils::FieldMetadata<
+      94,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransactionTraceEntry,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SurfaceflingerTransactions kSurfaceflingerTransactions{};
+  template <typename T = TransactionTraceEntry> T* set_surfaceflinger_transactions() {
+    return BeginNestedMessage<T>(94);
+  }
+
+
+  using FieldMetadata_ShellTransition =
+    ::protozero::proto_utils::FieldMetadata<
+      96,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ShellTransition,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ShellTransition kShellTransition{};
+  template <typename T = ShellTransition> T* set_shell_transition() {
+    return BeginNestedMessage<T>(96);
+  }
+
+
+  using FieldMetadata_ShellHandlerMappings =
+    ::protozero::proto_utils::FieldMetadata<
+      97,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ShellHandlerMappings,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ShellHandlerMappings kShellHandlerMappings{};
+  template <typename T = ShellHandlerMappings> T* set_shell_handler_mappings() {
+    return BeginNestedMessage<T>(97);
+  }
+
+
+  using FieldMetadata_EtwEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      95,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EtwTraceEventBundle,
+      TracePacket>;
+
+  static constexpr FieldMetadata_EtwEvents kEtwEvents{};
+  template <typename T = EtwTraceEventBundle> T* set_etw_events() {
+    return BeginNestedMessage<T>(95);
+  }
+
+
+  using FieldMetadata_ForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      900,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestEvent,
+      TracePacket>;
+
+  static constexpr FieldMetadata_ForTesting kForTesting{};
+  template <typename T = TestEvent> T* set_for_testing() {
+    return BeginNestedMessage<T>(900);
+  }
+
+
+  using FieldMetadata_TrustedUid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrustedUid kTrustedUid{};
+  void set_trusted_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrustedUid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TrustedPacketSequenceId =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrustedPacketSequenceId kTrustedPacketSequenceId{};
+  void set_trusted_packet_sequence_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrustedPacketSequenceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TrustedPid =
+    ::protozero::proto_utils::FieldMetadata<
+      79,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TrustedPid kTrustedPid{};
+  void set_trusted_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrustedPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InternedData =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedData,
+      TracePacket>;
+
+  static constexpr FieldMetadata_InternedData kInternedData{};
+  template <typename T = InternedData> T* set_interned_data() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_SequenceFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_SequenceFlags kSequenceFlags{};
+  void set_sequence_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SequenceFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IncrementalStateCleared =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracePacket>;
+
+  static constexpr FieldMetadata_IncrementalStateCleared kIncrementalStateCleared{};
+  void set_incremental_state_cleared(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IncrementalStateCleared::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TracePacketDefaults =
+    ::protozero::proto_utils::FieldMetadata<
+      59,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracePacketDefaults,
+      TracePacket>;
+
+  static constexpr FieldMetadata_TracePacketDefaults kTracePacketDefaults{};
+  template <typename T = TracePacketDefaults> T* set_trace_packet_defaults() {
+    return BeginNestedMessage<T>(59);
+  }
+
+
+  using FieldMetadata_PreviousPacketDropped =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracePacket>;
+
+  static constexpr FieldMetadata_PreviousPacketDropped kPreviousPacketDropped{};
+  void set_previous_packet_dropped(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreviousPacketDropped::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FirstPacketOnSequence =
+    ::protozero::proto_utils::FieldMetadata<
+      87,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracePacket>;
+
+  static constexpr FieldMetadata_FirstPacketOnSequence kFirstPacketOnSequence{};
+  void set_first_packet_on_sequence(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_FirstPacketOnSequence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MachineId =
+    ::protozero::proto_utils::FieldMetadata<
+      98,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacket>;
+
+  static constexpr FieldMetadata_MachineId kMachineId{};
+  void set_machine_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MachineId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_DATA_SOURCE_H_
+#define INCLUDE_PERFETTO_TRACING_DATA_SOURCE_H_
+
+// This header contains the key class (DataSource) that a producer app should
+// override in order to create a custom data source that gets tracing Start/Stop
+// notifications and emits tracing data.
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <array>
+#include <atomic>
+#include <functional>
+#include <memory>
+#include <mutex>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/flush_flags.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_type.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/locked_handle.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+// DEPRECATED: Instead of using this macro, prefer specifying symbol linkage
+// attributes explicitly using the `_WITH_ATTRS` macro variants (e.g.,
+// PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS). This avoids
+// potential macro definition collisions between two libraries using Perfetto.
+//
+// PERFETTO_COMPONENT_EXPORT is used to mark symbols in Perfetto's headers
+// (typically templates) that are defined by the user outside of Perfetto and
+// should be made visible outside the current module. (e.g., in Chrome's
+// component build).
+#if !defined(PERFETTO_COMPONENT_EXPORT)
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
+// Workaround for C4003: not enough arguments for function-like macro invocation
+// 'PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE'
+#define PERFETTO_COMPONENT_EXPORT __declspec()
+#else
+#define PERFETTO_COMPONENT_EXPORT
+#endif
+#endif
+
+namespace perfetto {
+namespace internal {
+class TracingMuxerImpl;
+class TrackEventCategoryRegistry;
+template <typename, const internal::TrackEventCategoryRegistry*>
+class TrackEventDataSource;
+}  // namespace internal
+
+namespace shlib {
+class TrackEvent;
+}  // namespace shlib
+
+namespace test {
+class DataSourceInternalForTest;
+}  // namespace test
+
+// Base class with the virtual methods to get start/stop notifications.
+// Embedders are supposed to derive the templated version below, not this one.
+class PERFETTO_EXPORT_COMPONENT DataSourceBase {
+ public:
+  virtual ~DataSourceBase();
+
+  // TODO(primiano): change the const& args below to be pointers instead. It
+  // makes it more awkward to handle output arguments and require mutable(s).
+  // This requires synchronizing a breaking API change for existing embedders.
+
+  // OnSetup() is invoked when tracing is configured. In most cases this happens
+  // just before starting the trace. In the case of deferred start (see
+  // deferred_start in trace_config.proto) start might happen later.
+  class SetupArgs {
+   public:
+    // This is valid only within the scope of the OnSetup() call and must not
+    // be retained.
+    const DataSourceConfig* config = nullptr;
+
+    // Backend type.
+    BackendType backend_type = kUnspecifiedBackend;
+
+    // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+    uint32_t internal_instance_index = 0;
+  };
+  virtual void OnSetup(const SetupArgs&);
+
+  class StartArgs {
+   public:
+    // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+    uint32_t internal_instance_index = 0;
+  };
+  virtual void OnStart(const StartArgs&);
+
+  class PERFETTO_EXPORT_COMPONENT StopArgs {
+   public:
+    virtual ~StopArgs();
+
+    // HandleAsynchronously() can optionally be called to defer the tracing
+    // session stop and write tracing data just before stopping.
+    // This function returns a closure that must be invoked after the last
+    // trace events have been emitted. The returned closure can be called from
+    // any thread. The caller also needs to explicitly call TraceContext.Flush()
+    // from the last Trace() lambda invocation because no other implicit flushes
+    // will happen after the stop signal.
+    // When this function is called, the tracing service will defer the stop of
+    // the tracing session until the returned closure is invoked.
+    // However, the caller cannot hang onto this closure for too long. The
+    // tracing service will forcefully stop the tracing session without waiting
+    // for pending producers after TraceConfig.data_source_stop_timeout_ms
+    // (default: 5s, can be overridden by Consumers when starting a trace).
+    // If the closure is called after this timeout an error will be logged and
+    // the trace data emitted will not be present in the trace. No other
+    // functional side effects (e.g. crashes or corruptions) will happen. In
+    // other words, it is fine to accidentally hold onto this closure for too
+    // long but, if that happens, some tracing data will be lost.
+    virtual std::function<void()> HandleStopAsynchronously() const = 0;
+
+    // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+    uint32_t internal_instance_index = 0;
+  };
+  virtual void OnStop(const StopArgs&);
+
+  class ClearIncrementalStateArgs {
+   public:
+    // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+    uint32_t internal_instance_index = 0;
+  };
+  virtual void WillClearIncrementalState(const ClearIncrementalStateArgs&);
+
+  class FlushArgs {
+   public:
+    virtual ~FlushArgs();
+
+    // HandleFlushAsynchronously() can be called to postpone acknowledging the
+    // flush request. This function returns a closure that must be invoked after
+    // the flush request has been processed. The returned closure can be called
+    // from any thread.
+    virtual std::function<void()> HandleFlushAsynchronously() const = 0;
+
+    // The index of this data source instance (0..kMaxDataSourceInstances - 1).
+    uint32_t internal_instance_index = 0;
+
+    // The reason and initiator of the flush. See flush_flags.h .
+    FlushFlags flush_flags;
+  };
+  // Called when the tracing service requests a Flush. Users can override this
+  // to tell other threads to flush their TraceContext for this data source
+  // (the library cannot execute code on all the threads on its own).
+  virtual void OnFlush(const FlushArgs&);
+
+  // Determines whether a startup session can be adopted by a service-initiated
+  // tracing session (i.e. whether their configs are compatible).
+  virtual bool CanAdoptStartupSession(const DataSourceConfig& startup_config,
+                                      const DataSourceConfig& service_config);
+};
+
+struct DefaultDataSourceTraits {
+  // |IncrementalStateType| can optionally be used store custom per-sequence
+  // incremental data (e.g., interning tables).
+  using IncrementalStateType = void;
+  // |TlsStateType| can optionally be used to store custom per-sequence
+  // session data, which is not reset when incremental state is cleared
+  // (e.g. configuration options).
+  using TlsStateType = void;
+
+  // Allows overriding what type of thread-local state configuration the data
+  // source uses. By default every data source gets independent thread-local
+  // state, which means every instance uses separate trace writers and
+  // incremental state even on the same thread. Some data sources (most notably
+  // the track event data source) want to share trace writers and incremental
+  // state on the same thread.
+  static internal::DataSourceThreadLocalState* GetDataSourceTLS(
+      internal::DataSourceStaticState* static_state,
+      internal::TracingTLS* root_tls) {
+    auto* ds_tls = &root_tls->data_sources_tls[static_state->index];
+    // ds_tls->static_state can be:
+    // * nullptr
+    // * equal to static_state
+    // * equal to the static state of a different data source, in tests (when
+    //   ResetForTesting() has been used)
+    // In any case, there's no need to do anything, the caller will reinitialize
+    // static_state.
+    return ds_tls;
+  }
+};
+
+// Holds the type for a DataSource. Accessed by the static Trace() method
+// fastpaths. This allows redefinitions under a component where a component
+// specific export macro is used.
+// Due to C2086 (redefinition) error on MSVC/clang-cl, internal::DataSourceType
+// can't be a static data member. To avoid explicit specialization after
+// instantiation error, type() needs to be in a template helper class that's
+// instantiated independently from DataSource. See b/280777748.
+template <typename DerivedDataSource,
+          typename DataSourceTraits = DefaultDataSourceTraits>
+struct DataSourceHelper {
+  static internal::DataSourceType& type() {
+    static perfetto::internal::DataSourceType type_;
+    return type_;
+  }
+};
+
+// Templated base class meant to be derived by embedders to create a custom data
+// source. DerivedDataSource must be the type of the derived class itself, e.g.:
+// class MyDataSource : public DataSource<MyDataSource> {...}.
+//
+// |DataSourceTraits| allows customizing the behavior of the data source. See
+// |DefaultDataSourceTraits|.
+template <typename DerivedDataSource,
+          typename DataSourceTraits = DefaultDataSourceTraits>
+class DataSource : public DataSourceBase {
+  struct DefaultTracePointTraits;
+  using Helper = DataSourceHelper<DerivedDataSource, DataSourceTraits>;
+
+ public:
+  // The BufferExhaustedPolicy to use for TraceWriters of this DataSource.
+  // Override this in your DataSource class to change the default, which is to
+  // drop data on shared memory overruns.
+  constexpr static BufferExhaustedPolicy kBufferExhaustedPolicy =
+      BufferExhaustedPolicy::kDrop;
+
+  // When this flag is false, we cannot have multiple instances of this data
+  // source. When a data source is already active and if we attempt
+  // to start another instance of that data source (via another tracing
+  // session), it will fail to start the second instance of data source.
+  static constexpr bool kSupportsMultipleInstances = true;
+
+  // When this flag is true, DataSource callbacks (OnSetup, OnStart, etc.) are
+  // called under the lock (the same that is used in GetDataSourceLocked
+  // function). This is not recommended because it can lead to deadlocks, but
+  // it was the default behavior for a long time and some embedders rely on it
+  // to protect concurrent access to the DataSource members. So we keep the
+  // "true" value as the default.
+  static constexpr bool kRequiresCallbacksUnderLock = true;
+
+  // Argument passed to the lambda function passed to Trace() (below).
+  class TraceContext {
+   public:
+    using TracePacketHandle =
+        ::protozero::MessageHandle<::perfetto::protos::pbzero::TracePacket>;
+
+    TraceContext(TraceContext&&) noexcept = default;
+    ~TraceContext() {
+      // If the data source is being intercepted, flush the trace writer after
+      // each trace point to make sure the interceptor sees the data right away.
+      if (PERFETTO_UNLIKELY(tls_inst_->is_intercepted))
+        Flush();
+    }
+
+    // Adds an empty trace packet to the trace to ensure that the service can
+    // safely read the last event from the trace buffer.
+    // See PERFETTO_INTERNAL_ADD_EMPTY_EVENT macros for context.
+    void AddEmptyTracePacket() {
+      // If nothing was written since the last empty packet, there's nothing to
+      // scrape, so adding more empty packets serves no purpose.
+      if (tls_inst_->trace_writer->written() ==
+          tls_inst_->last_empty_packet_position) {
+        return;
+      }
+      tls_inst_->trace_writer->NewTracePacket();
+      tls_inst_->last_empty_packet_position =
+          tls_inst_->trace_writer->written();
+    }
+
+    TracePacketHandle NewTracePacket() {
+      return tls_inst_->trace_writer->NewTracePacket();
+    }
+
+    // Forces a commit of the thread-local tracing data written so far to the
+    // service. This is almost never required (tracing data is periodically
+    // committed as trace pages are filled up) and has a non-negligible
+    // performance hit (requires an IPC + refresh of the current thread-local
+    // chunk). The only case when this should be used is when handling OnStop()
+    // asynchronously, to ensure sure that the data is committed before the
+    // Stop timeout expires.
+    // The TracePacketHandle obtained by the last NewTracePacket() call must be
+    // finalized before calling Flush() (either implicitly by going out of scope
+    // or by explicitly calling Finalize()).
+    // |cb| is an optional callback. When non-null it will request the
+    // service to ACK the flush and will be invoked on an internal thread after
+    // the service has  acknowledged it. The callback might be NEVER INVOKED if
+    // the service crashes or the IPC connection is dropped.
+    void Flush(std::function<void()> cb = {}) {
+      tls_inst_->trace_writer->Flush(cb);
+    }
+
+    // Returns the number of bytes written on the current thread by the current
+    // data-source since its creation.
+    // This can be useful for splitting protos that might grow very large.
+    uint64_t written() { return tls_inst_->trace_writer->written(); }
+
+    // Returns a RAII handle to access the data source instance, guaranteeing
+    // that it won't be deleted on another thread (because of trace stopping)
+    // while accessing it from within the Trace() lambda.
+    // The returned handle can be invalid (nullptr) if tracing is stopped
+    // immediately before calling this. The caller is supposed to check for its
+    // validity before using it. After checking, the handle is guaranteed to
+    // remain valid until the handle goes out of scope.
+    LockedHandle<DerivedDataSource> GetDataSourceLocked() const {
+      auto* internal_state =
+          Helper::type().static_state()->TryGet(instance_index_);
+      if (!internal_state)
+        return LockedHandle<DerivedDataSource>();
+      std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
+      return LockedHandle<DerivedDataSource>(
+          std::move(lock),
+          static_cast<DerivedDataSource*>(internal_state->data_source.get()));
+    }
+
+    // Post-condition: returned ptr will be non-null.
+    typename DataSourceTraits::TlsStateType* GetCustomTlsState() {
+      PERFETTO_DCHECK(tls_inst_->data_source_custom_tls);
+      return reinterpret_cast<typename DataSourceTraits::TlsStateType*>(
+          tls_inst_->data_source_custom_tls.get());
+    }
+
+    typename DataSourceTraits::IncrementalStateType* GetIncrementalState() {
+      return static_cast<typename DataSourceTraits::IncrementalStateType*>(
+          Helper::type().GetIncrementalState(tls_inst_, instance_index_));
+    }
+
+   private:
+    friend class DataSource;
+    template <typename, const internal::TrackEventCategoryRegistry*>
+    friend class internal::TrackEventDataSource;
+    TraceContext(internal::DataSourceInstanceThreadLocalState* tls_inst,
+                 uint32_t instance_index)
+        : tls_inst_(tls_inst), instance_index_(instance_index) {}
+    TraceContext(const TraceContext&) = delete;
+    TraceContext& operator=(const TraceContext&) = delete;
+
+    internal::DataSourceInstanceThreadLocalState* const tls_inst_;
+    uint32_t const instance_index_;
+  };
+
+  // The main tracing method. Tracing code should call this passing a lambda as
+  // argument, with the following signature: void(TraceContext).
+  // The lambda will be called synchronously (i.e., always before Trace()
+  // returns) only if tracing is enabled and the data source has been enabled in
+  // the tracing config.
+  // The lambda can be called more than once per Trace() call, in the case of
+  // concurrent tracing sessions (or even if the data source is instantiated
+  // twice within the same trace config).
+  template <typename Lambda>
+  static void Trace(Lambda tracing_fn) {
+    CallIfEnabled<DefaultTracePointTraits>([&tracing_fn](uint32_t instances) {
+      TraceWithInstances<DefaultTracePointTraits>(instances,
+                                                  std::move(tracing_fn));
+    });
+  }
+
+  // An efficient trace point guard for checking if this data source is active.
+  // |callback| is a function which will only be called if there are active
+  // instances. It is given an instance state parameter, which should be passed
+  // to TraceWithInstances() to actually record trace data.
+  template <typename Traits = DefaultTracePointTraits, typename Callback>
+  static void CallIfEnabled(Callback callback,
+                            typename Traits::TracePointData trace_point_data =
+                                {}) PERFETTO_ALWAYS_INLINE {
+    // |instances| is a per-class bitmap that tells:
+    // 1. If the data source is enabled at all.
+    // 2. The index of the slot within
+    //    internal::DataSourceStaticState::instances that holds the instance
+    //    state. In turn this allows to map the data source to the tracing
+    //    session and buffers.
+    // memory_order_relaxed is okay because:
+    // - |instances| is re-read with an acquire barrier below if this succeeds.
+    // - The code between this point and the acquire-load is based on static
+    //    storage which has indefinite lifetime.
+    uint32_t instances = Traits::GetActiveInstances(trace_point_data)
+                             ->load(std::memory_order_relaxed);
+
+    // This is the tracing fast-path. Bail out immediately if tracing is not
+    // enabled (or tracing is enabled but not for this data source).
+    if (PERFETTO_LIKELY(!instances))
+      return;
+    callback(instances);
+  }
+
+  // The "lower half" of a trace point which actually performs tracing after
+  // this data source has been determined to be active.
+  // |instances| must be the instance state value retrieved through
+  // CallIfEnabled().
+  // |tracing_fn| will be called to record trace data as in Trace().
+  //
+  // |trace_point_data| is an optional parameter given to |Traits::
+  // GetActiveInstances| to make it possible to use custom storage for
+  // the data source enabled state. This is, for example, used by TrackEvent to
+  // implement per-tracing category enabled states.
+  template <typename Traits = DefaultTracePointTraits, typename Lambda>
+  static void TraceWithInstances(
+      uint32_t cached_instances,
+      Lambda tracing_fn,
+      typename Traits::TracePointData trace_point_data = {}) {
+    PERFETTO_DCHECK(cached_instances);
+
+    if (!Helper::type().template TracePrologue<DataSourceTraits, Traits>(
+            &tls_state_, &cached_instances, trace_point_data)) {
+      return;
+    }
+
+    for (internal::DataSourceType::InstancesIterator it =
+             Helper::type().template BeginIteration<Traits>(
+                 cached_instances, tls_state_, trace_point_data);
+         it.instance; Helper::type().template NextIteration<Traits>(
+             &it, tls_state_, trace_point_data)) {
+      tracing_fn(TraceContext(it.instance, it.i));
+    }
+
+    Helper::type().TraceEpilogue(tls_state_);
+  }
+
+  // Registers the data source on all tracing backends, including ones that
+  // connect after the registration. Doing so enables the data source to receive
+  // Setup/Start/Stop notifications and makes the Trace() method work when
+  // tracing is enabled and the data source is selected.
+  // This must be called after Tracing::Initialize().
+  // Can return false to signal failure if attemping to register more than
+  // kMaxDataSources (32) data sources types or if tracing hasn't been
+  // initialized.
+  // The optional |constructor_args| will be passed to the data source when it
+  // is constructed.
+  template <class... Args>
+  static bool Register(const DataSourceDescriptor& descriptor,
+                       const Args&... constructor_args) {
+    // Silences -Wunused-variable warning in case the trace method is not used
+    // by the translation unit that declares the data source.
+    (void)tls_state_;
+
+    auto factory = [constructor_args...]() {
+      return std::unique_ptr<DataSourceBase>(
+          new DerivedDataSource(constructor_args...));
+    };
+    internal::DataSourceParams params{
+        DerivedDataSource::kSupportsMultipleInstances,
+        DerivedDataSource::kRequiresCallbacksUnderLock};
+    return Helper::type().Register(
+        descriptor, factory, params, DerivedDataSource::kBufferExhaustedPolicy,
+        GetCreateTlsFn(
+            static_cast<typename DataSourceTraits::TlsStateType*>(nullptr)),
+        GetCreateIncrementalStateFn(
+            static_cast<typename DataSourceTraits::IncrementalStateType*>(
+                nullptr)),
+        nullptr);
+  }
+
+  // Updates the data source descriptor.
+  static void UpdateDescriptor(const DataSourceDescriptor& descriptor) {
+    Helper::type().UpdateDescriptor(descriptor);
+  }
+
+ private:
+  friend ::perfetto::test::DataSourceInternalForTest;
+  friend ::perfetto::shlib::TrackEvent;
+  // Traits for customizing the behavior of a specific trace point.
+  struct DefaultTracePointTraits {
+    // By default, every call to DataSource::Trace() will record trace events
+    // for every active instance of that data source. A single trace point can,
+    // however, use a custom set of enable flags for more fine grained control
+    // of when that trace point is active.
+    //
+    // DANGER: when doing this, the data source must use the appropriate memory
+    // fences when changing the state of the bitmap.
+    //
+    // |TraceWithInstances| may be optionally given an additional parameter for
+    // looking up the enable flags. That parameter is passed as |TracePointData|
+    // to |GetActiveInstances|. This is, for example, used by TrackEvent to
+    // implement per-category enabled states.
+    struct TracePointData {};
+    static constexpr std::atomic<uint32_t>* GetActiveInstances(TracePointData) {
+      return Helper::type().valid_instances();
+    }
+  };
+
+  template <typename T>
+  static internal::DataSourceInstanceThreadLocalState::ObjectWithDeleter
+  CreateIncrementalState(internal::DataSourceInstanceThreadLocalState*,
+                         uint32_t,
+                         void*) {
+    return internal::DataSourceInstanceThreadLocalState::ObjectWithDeleter(
+        reinterpret_cast<void*>(new T()),
+        [](void* p) { delete reinterpret_cast<T*>(p); });
+  }
+
+  // The second parameter here is used to specialize the case where there is no
+  // incremental state type.
+  template <typename T>
+  static internal::DataSourceType::CreateIncrementalStateFn
+  GetCreateIncrementalStateFn(const T*) {
+    return &CreateIncrementalState<T>;
+  }
+
+  static internal::DataSourceType::CreateIncrementalStateFn
+  GetCreateIncrementalStateFn(const void*) {
+    return nullptr;
+  }
+
+  template <typename T>
+  static internal::DataSourceInstanceThreadLocalState::ObjectWithDeleter
+  CreateDataSourceCustomTls(
+      internal::DataSourceInstanceThreadLocalState* tls_inst,
+      uint32_t instance_index,
+      void*) {
+    return internal::DataSourceInstanceThreadLocalState::ObjectWithDeleter(
+        reinterpret_cast<void*>(new T(TraceContext(tls_inst, instance_index))),
+        [](void* p) { delete reinterpret_cast<T*>(p); });
+  }
+
+  // The second parameter here is used to specialize the case where there is no
+  // tls state type.
+  template <typename T>
+  static internal::DataSourceType::CreateCustomTlsFn GetCreateTlsFn(const T*) {
+    return &CreateDataSourceCustomTls<T>;
+  }
+
+  static internal::DataSourceType::CreateCustomTlsFn GetCreateTlsFn(
+      const void*) {
+    return nullptr;
+  }
+
+  // This TLS object is a cached raw pointer and has deliberately no destructor.
+  // The Platform implementation is supposed to create and manage the lifetime
+  // of the Platform::ThreadLocalObject and take care of destroying it.
+  // This is because non-POD thread_local variables have subtleties (global
+  // destructors) that we need to defer to the embedder. In chromium's platform
+  // implementation, for instance, the tls slot is implemented using
+  // chromium's base::ThreadLocalStorage.
+  static thread_local internal::DataSourceThreadLocalState* tls_state_;
+};
+
+// static
+template <typename T, typename D>
+thread_local internal::DataSourceThreadLocalState* DataSource<T, D>::tls_state_;
+
+}  // namespace perfetto
+
+// If placed at the end of a macro declaration, eats the semicolon at the end of
+// the macro invocation (e.g., "MACRO(...);") to avoid warnings about extra
+// semicolons.
+#define PERFETTO_INTERNAL_SWALLOW_SEMICOLON() \
+  extern int perfetto_internal_unused
+
+// This macro must be used once for each data source next to the data source's
+// declaration.
+#define PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS(...)  \
+  PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS( \
+      PERFETTO_COMPONENT_EXPORT, __VA_ARGS__)
+
+// Similar to `PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS` but it also takes
+// custom attributes, which are useful when DataSource is defined in a component
+// where a component specific export macro is used.
+#define PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(attrs, ...) \
+  template <>                                                              \
+  attrs perfetto::internal::DataSourceType&                                \
+  perfetto::DataSourceHelper<__VA_ARGS__>::type()
+
+// This macro must be used once for each data source in one source file to
+// allocate static storage for the data source's static state.
+#define PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(...)  \
+  PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS( \
+      PERFETTO_COMPONENT_EXPORT, __VA_ARGS__)
+
+// Similar to `PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS` but it also takes
+// custom attributes, which are useful when DataSource is defined in a component
+// where a component specific export macro is used.
+#define PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(attrs, ...) \
+  template <>                                                             \
+  perfetto::internal::DataSourceType&                                     \
+  perfetto::DataSourceHelper<__VA_ARGS__>::type() {                       \
+    static perfetto::internal::DataSourceType type_;                      \
+    return type_;                                                         \
+  }                                                                       \
+  PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
+
+#endif  // INCLUDE_PERFETTO_TRACING_DATA_SOURCE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_data_source.h
+// gen_amalgamated begin header: include/perfetto/base/template_util.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_TEMPLATE_UTIL_H_
+#define INCLUDE_PERFETTO_BASE_TEMPLATE_UTIL_H_
+
+#include <cstddef>
+#include <type_traits>
+
+namespace perfetto {
+namespace base {
+
+// Helper to express preferences in an overload set. If more than one overload
+// is available for a given set of parameters the overload with the higher
+// priority will be chosen.
+template <size_t I>
+struct priority_tag : priority_tag<I - 1> {};
+
+template <>
+struct priority_tag<0> {};
+
+// enable_if_t is an implementation of std::enable_if_t from C++14.
+//
+// Specification:
+// https://en.cppreference.com/w/cpp/types/enable_if
+template <bool B, class T = void>
+using enable_if_t = typename std::enable_if<B, T>::type;
+
+// decay_t is an implementation of std::decay_t from C++14.
+//
+// Specification:
+// https://en.cppreference.com/w/cpp/types/decay
+template <class T>
+using decay_t = typename std::decay<T>::type;
+
+// remove_cvref is an implementation of std::remove_cvref from
+// C++20.
+//
+// Specification:
+// https://en.cppreference.com/w/cpp/types/remove_cvref
+
+template <class T>
+struct remove_cvref {
+  using type = typename std::remove_cv<typename std::remove_cv<
+      typename std::remove_reference<T>::type>::type>::type;
+};
+template <class T>
+using remove_cvref_t = typename remove_cvref<T>::type;
+
+// Check if a given type is a specialization of a given template:
+// is_specialization<T, std::vector>::value.
+
+template <typename Type, template <typename...> class Template>
+struct is_specialization : std::false_type {};
+
+template <template <typename...> class Ref, typename... Args>
+struct is_specialization<Ref<Args...>, Ref> : std::true_type {};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_TEMPLATE_UTIL_H_
+// gen_amalgamated begin header: include/perfetto/tracing/event_context.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_internal.h
+// gen_amalgamated begin header: include/perfetto/base/flat_set.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_BASE_FLAT_SET_H_
+#define INCLUDE_PERFETTO_BASE_FLAT_SET_H_
+
+#include <algorithm>
+#include <vector>
+
+// A vector-based set::set-like container.
+// It's more cache friendly than std::*set and performs for cases where:
+// 1. A high number of dupes is expected (e.g. pid tracking in ftrace).
+// 2. The working set is small (hundreds of elements).
+
+// Performance characteristics (for uniformly random insertion order):
+// - For smaller insertions (up to ~500), it outperforms both std::set<int> and
+//   std::unordered_set<int> by ~3x.
+// - Up until 4k insertions, it is always faster than std::set<int>.
+// - unordered_set<int> is faster with more than 2k insertions.
+// - unordered_set, however, it's less memory efficient and has more caveats
+//   (see chromium's base/containers/README.md).
+//
+// See flat_set_benchmark.cc and the charts in go/perfetto-int-set-benchmark.
+
+namespace perfetto {
+namespace base {
+
+template <typename T>
+class FlatSet {
+ public:
+  using value_type = T;
+  using const_pointer = const T*;
+  using iterator = typename std::vector<T>::iterator;
+  using const_iterator = typename std::vector<T>::const_iterator;
+
+  FlatSet() = default;
+
+  // Mainly for tests. Deliberately not marked as "explicit".
+  FlatSet(std::initializer_list<T> initial) : entries_(initial) {
+    std::sort(entries_.begin(), entries_.end());
+    entries_.erase(std::unique(entries_.begin(), entries_.end()),
+                   entries_.end());
+  }
+
+  const_iterator find(T value) const {
+    auto entries_end = entries_.end();
+    auto it = std::lower_bound(entries_.begin(), entries_end, value);
+    return (it != entries_end && *it == value) ? it : entries_end;
+  }
+
+  size_t count(T value) const { return find(value) == entries_.end() ? 0 : 1; }
+
+  std::pair<iterator, bool> insert(T value) {
+    auto entries_end = entries_.end();
+    auto it = std::lower_bound(entries_.begin(), entries_end, value);
+    if (it != entries_end && *it == value)
+      return std::make_pair(it, false);
+    // If the value is not found |it| is either end() or the next item strictly
+    // greater than |value|. In both cases we want to insert just before that.
+    it = entries_.insert(it, std::move(value));
+    return std::make_pair(it, true);
+  }
+
+  size_t erase(T value) {
+    auto it = find(value);
+    if (it == entries_.end())
+      return 0;
+    entries_.erase(it);
+    return 1;
+  }
+
+  void clear() { entries_.clear(); }
+
+  bool empty() const { return entries_.empty(); }
+  void reserve(size_t n) { entries_.reserve(n); }
+  size_t size() const { return entries_.size(); }
+  const_iterator begin() const { return entries_.begin(); }
+  const_iterator end() const { return entries_.end(); }
+
+ private:
+  std::vector<T> entries_;
+};
+
+}  // namespace base
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_BASE_FLAT_SET_H_
+// gen_amalgamated begin header: include/perfetto/protozero/scattered_heap_buffer.h
+// gen_amalgamated begin header: include/perfetto/protozero/root_message.h
+// gen_amalgamated begin header: include/perfetto/protozero/message_arena.h
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_MESSAGE_ARENA_H_
+#define INCLUDE_PERFETTO_PROTOZERO_MESSAGE_ARENA_H_
+
+#include <stdint.h>
+
+#include <forward_list>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+
+namespace protozero {
+
+class Message;
+
+// Object allocator for fixed-sized protozero::Message objects.
+// It's a simple bump-pointer allocator which leverages the stack-alike
+// usage pattern of protozero nested messages. It avoids hitting the system
+// allocator in most cases, by reusing the same block, and falls back on
+// allocating new blocks only when using deeply nested messages (which are
+// extremely rare).
+// This is used by RootMessage<T> to handle the storage for root-level messages.
+class PERFETTO_EXPORT_COMPONENT MessageArena {
+ public:
+  MessageArena();
+  ~MessageArena();
+
+  // Strictly no copies or moves as this is used to hand out pointers.
+  MessageArena(const MessageArena&) = delete;
+  MessageArena& operator=(const MessageArena&) = delete;
+  MessageArena(MessageArena&&) = delete;
+  MessageArena& operator=(MessageArena&&) = delete;
+
+  // Allocates a new Message object.
+  Message* NewMessage();
+
+  // Deletes the last message allocated. The |msg| argument is used only for
+  // DCHECKs, it MUST be the pointer obtained by the last NewMessage() call.
+  void DeleteLastMessage(Message* msg) {
+    PERFETTO_DCHECK(!blocks_.empty() && blocks_.front().entries > 0);
+    PERFETTO_DCHECK(&blocks_.front().storage[blocks_.front().entries - 1] ==
+                    static_cast<void*>(msg));
+    DeleteLastMessageInternal();
+  }
+
+  // Resets the state of the arena, clearing up all but one block. This is used
+  // to avoid leaking outstanding unfinished sub-messages while recycling the
+  // RootMessage object (this is extremely rare due to the RAII scoped handles
+  // but could happen if some client does some overly clever std::move() trick).
+  void Reset() {
+    PERFETTO_DCHECK(!blocks_.empty());
+    blocks_.resize(1);
+    auto& block = blocks_.front();
+    block.entries = 0;
+    PERFETTO_ASAN_POISON(block.storage, sizeof(block.storage));
+  }
+
+ private:
+  void DeleteLastMessageInternal();
+
+  struct Block {
+    static constexpr size_t kCapacity = 16;
+
+    Block() { PERFETTO_ASAN_POISON(storage, sizeof(storage)); }
+
+    std::aligned_storage<sizeof(Message), alignof(Message)>::type
+        storage[kCapacity];
+    uint32_t entries = 0;  // # Message entries used (<= kCapacity).
+  };
+
+  // blocks are used to hand out pointers and must not be moved. Hence why
+  // std::list rather than std::vector.
+  std::forward_list<Block> blocks_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_MESSAGE_ARENA_H_
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_ROOT_MESSAGE_H_
+#define INCLUDE_PERFETTO_PROTOZERO_ROOT_MESSAGE_H_
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
+
+namespace protozero {
+
+// Helper class to hand out messages using the default MessageArena.
+// Usage:
+// RootMessage<perfetto::protos::zero::MyMessage> msg;
+// msg.Reset(stream_writer);
+// msg.set_foo(...);
+// auto* nested = msg.set_nested();
+template <typename T = Message>
+class RootMessage : public T {
+ public:
+  RootMessage() { T::Reset(nullptr, &root_arena_); }
+
+  // Disallow copy and move.
+  RootMessage(const RootMessage&) = delete;
+  RootMessage& operator=(const RootMessage&) = delete;
+  RootMessage(RootMessage&&) = delete;
+  RootMessage& operator=(RootMessage&&) = delete;
+
+  void Reset(ScatteredStreamWriter* writer) {
+    root_arena_.Reset();
+    Message::Reset(writer, &root_arena_);
+  }
+
+ private:
+  MessageArena root_arena_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_ROOT_MESSAGE_H_
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_HEAP_BUFFER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_HEAP_BUFFER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace protozero {
+
+class Message;
+
+class PERFETTO_EXPORT_COMPONENT ScatteredHeapBuffer
+    : public protozero::ScatteredStreamWriter::Delegate {
+ public:
+  class PERFETTO_EXPORT_COMPONENT Slice {
+   public:
+    Slice();
+    explicit Slice(size_t size);
+    Slice(Slice&& slice) noexcept;
+    ~Slice();
+    Slice& operator=(Slice&&);
+
+    inline protozero::ContiguousMemoryRange GetTotalRange() const {
+      return {buffer_.get(), buffer_.get() + size_};
+    }
+
+    inline protozero::ContiguousMemoryRange GetUsedRange() const {
+      return {buffer_.get(), buffer_.get() + size_ - unused_bytes_};
+    }
+
+    uint8_t* start() const { return buffer_.get(); }
+    size_t size() const { return size_; }
+    size_t unused_bytes() const { return unused_bytes_; }
+    void set_unused_bytes(size_t unused_bytes) {
+      PERFETTO_DCHECK(unused_bytes_ <= size_);
+      unused_bytes_ = unused_bytes;
+    }
+
+    void Clear();
+
+   private:
+    std::unique_ptr<uint8_t[]> buffer_;
+    size_t size_;
+    size_t unused_bytes_;
+  };
+
+  ScatteredHeapBuffer(size_t initial_slice_size_bytes = 128,
+                      size_t maximum_slice_size_bytes = 128 * 1024);
+  ~ScatteredHeapBuffer() override;
+
+  // protozero::ScatteredStreamWriter::Delegate implementation.
+  protozero::ContiguousMemoryRange GetNewBuffer() override;
+
+  // Return the slices backing this buffer, adjusted for the number of bytes the
+  // writer has written.
+  const std::vector<Slice>& GetSlices();
+
+  // Stitch all the slices into a single contiguous buffer.
+  std::vector<uint8_t> StitchSlices();
+
+  // Note that the returned ranges point back to this buffer and thus cannot
+  // outlive it.
+  std::vector<protozero::ContiguousMemoryRange> GetRanges();
+
+  // Note that size of the last slice isn't updated to reflect the number of
+  // bytes written by the trace writer.
+  const std::vector<Slice>& slices() const { return slices_; }
+
+  void set_writer(protozero::ScatteredStreamWriter* writer) {
+    writer_ = writer;
+  }
+
+  // Update unused_bytes() of the current |Slice| based on the writer's state.
+  void AdjustUsedSizeOfCurrentSlice();
+
+  // Returns the total size the slices occupy in heap memory (including unused).
+  size_t GetTotalSize();
+
+  // Reset the contents of this buffer but retain one slice allocation (if it
+  // exists) to be reused for future writes.
+  void Reset();
+
+ private:
+  size_t next_slice_size_;
+  const size_t maximum_slice_size_;
+  protozero::ScatteredStreamWriter* writer_ = nullptr;
+  std::vector<Slice> slices_;
+
+  // Used to keep an allocated slice around after this buffer is reset.
+  Slice cached_slice_;
+};
+
+// Helper function to create heap-based protozero messages in one line.
+// Useful when manually serializing a protozero message (primarily in
+// tests/utilities). So instead of the following:
+//   protozero::MyMessage msg;
+//   protozero::ScatteredHeapBuffer shb;
+//   protozero::ScatteredStreamWriter writer(&shb);
+//   shb.set_writer(&writer);
+//   msg.Reset(&writer);
+//   ...
+// You can write:
+//   protozero::HeapBuffered<protozero::MyMessage> msg;
+//   msg->set_stuff(...);
+//   msg.SerializeAsString();
+template <typename T = ::protozero::Message>
+class HeapBuffered {
+ public:
+  HeapBuffered() : HeapBuffered(4096, 4096) {}
+  HeapBuffered(size_t initial_slice_size_bytes, size_t maximum_slice_size_bytes)
+      : shb_(initial_slice_size_bytes, maximum_slice_size_bytes),
+        writer_(&shb_) {
+    shb_.set_writer(&writer_);
+    msg_.Reset(&writer_);
+  }
+
+  // This can't be neither copied nor moved because Message hands out pointers
+  // to itself when creating submessages.
+  HeapBuffered(const HeapBuffered&) = delete;
+  HeapBuffered& operator=(const HeapBuffered&) = delete;
+  HeapBuffered(HeapBuffered&&) = delete;
+  HeapBuffered& operator=(HeapBuffered&&) = delete;
+
+  T* get() { return &msg_; }
+  T* operator->() { return &msg_; }
+
+  bool empty() const { return shb_.slices().empty(); }
+
+  std::vector<uint8_t> SerializeAsArray() {
+    msg_.Finalize();
+    return shb_.StitchSlices();
+  }
+
+  std::string SerializeAsString() {
+    auto vec = SerializeAsArray();
+    return std::string(reinterpret_cast<const char*>(vec.data()), vec.size());
+  }
+
+  std::vector<protozero::ContiguousMemoryRange> GetRanges() {
+    msg_.Finalize();
+    return shb_.GetRanges();
+  }
+
+  const std::vector<ScatteredHeapBuffer::Slice>& GetSlices() {
+    msg_.Finalize();
+    return shb_.GetSlices();
+  }
+
+  void Reset() {
+    shb_.Reset();
+    writer_.Reset(protozero::ContiguousMemoryRange{});
+    msg_.Reset(&writer_);
+    PERFETTO_DCHECK(empty());
+  }
+
+ private:
+  ScatteredHeapBuffer shb_;
+  ScatteredStreamWriter writer_;
+  RootMessage<T> msg_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_HEAP_BUFFER_H_
+// gen_amalgamated begin header: include/perfetto/tracing/debug_annotation.h
+// gen_amalgamated begin header: include/perfetto/tracing/traced_value_forward.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACED_VALUE_FORWARD_H_
+#define INCLUDE_PERFETTO_TRACING_TRACED_VALUE_FORWARD_H_
+
+namespace perfetto {
+
+class TracedValue;
+class TracedArray;
+class TracedDictionary;
+template <typename MessageType>
+class TracedProto;
+
+template <typename T>
+void WriteIntoTracedValue(TracedValue context, T&& value);
+template <typename MessageType, typename T>
+void WriteIntoTracedProto(TracedProto<MessageType> context, T&& value);
+
+template <typename T, class = void>
+struct TraceFormatTraits;
+
+// Helpers to check whether a given type T can be written into a TracedValue /
+// TracedProto<MessageType>.
+//
+// Intended to be used for types like smart pointers, who should support
+// WriteIntoTrace only iff their inner type supports being written into
+// a TracedValue.
+//
+// template <typename T>
+// class SmartPtr {
+//   ...
+//
+//   // Note: |Check| is needed to ensure that using
+//   SmartPtr<ClassWhichDoesNotSupportTracedValue> does not generate a
+//   compilation error.
+//
+//   template <typename Check=void>
+//   typename check_traced_value_support<T, Check>::value
+//   WriteIntoTrace(perfetto::TracedValue context) const {
+//      WriteIntoTracedValue(std::move(context), *ptr_);
+//   }
+//
+//   template <typename MessageType>
+//   typename check_traced_value_support<T, MessageType>::value
+//   WriteIntoTrace(perfetto::TracedProto<MessageType> message) const {
+//      WriteIntoTracedProto(std::move(message), *ptr_);
+//   }
+// };
+template <typename T, typename ResultType = void, typename = void>
+struct check_traced_value_support;
+
+template <typename MessageType,
+          typename T,
+          typename ResultType = void,
+          typename = void>
+struct check_traced_proto_support;
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACED_VALUE_FORWARD_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/debug_annotation.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DebugAnnotation;
+class DebugAnnotation_NestedValue;
+namespace perfetto_pbzero_enum_DebugAnnotation_NestedValue {
+enum NestedType : int32_t;
+}  // namespace perfetto_pbzero_enum_DebugAnnotation_NestedValue
+using DebugAnnotation_NestedValue_NestedType = perfetto_pbzero_enum_DebugAnnotation_NestedValue::NestedType;
+
+namespace perfetto_pbzero_enum_DebugAnnotation_NestedValue {
+enum NestedType : int32_t {
+  UNSPECIFIED = 0,
+  DICT = 1,
+  ARRAY = 2,
+};
+} // namespace perfetto_pbzero_enum_DebugAnnotation_NestedValue
+using DebugAnnotation_NestedValue_NestedType = perfetto_pbzero_enum_DebugAnnotation_NestedValue::NestedType;
+
+
+constexpr DebugAnnotation_NestedValue_NestedType DebugAnnotation_NestedValue_NestedType_MIN = DebugAnnotation_NestedValue_NestedType::UNSPECIFIED;
+constexpr DebugAnnotation_NestedValue_NestedType DebugAnnotation_NestedValue_NestedType_MAX = DebugAnnotation_NestedValue_NestedType::ARRAY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* DebugAnnotation_NestedValue_NestedType_Name(::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType::DICT:
+    return "DICT";
+
+  case ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType::ARRAY:
+    return "ARRAY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class DebugAnnotationValueTypeName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DebugAnnotationValueTypeName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DebugAnnotationValueTypeName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DebugAnnotationValueTypeName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class DebugAnnotationValueTypeName : public ::protozero::Message {
+ public:
+  using Decoder = DebugAnnotationValueTypeName_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DebugAnnotationValueTypeName"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotationValueTypeName>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotationValueTypeName>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DebugAnnotationName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DebugAnnotationName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DebugAnnotationName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DebugAnnotationName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class DebugAnnotationName : public ::protozero::Message {
+ public:
+  using Decoder = DebugAnnotationName_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DebugAnnotationName"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotationName>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotationName>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DebugAnnotation_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/17, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  DebugAnnotation_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DebugAnnotation_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DebugAnnotation_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name_iid() const { return at<1>().valid(); }
+  uint64_t name_iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<10>().valid(); }
+  ::protozero::ConstChars name() const { return at<10>().as_string(); }
+  bool has_bool_value() const { return at<2>().valid(); }
+  bool bool_value() const { return at<2>().as_bool(); }
+  bool has_uint_value() const { return at<3>().valid(); }
+  uint64_t uint_value() const { return at<3>().as_uint64(); }
+  bool has_int_value() const { return at<4>().valid(); }
+  int64_t int_value() const { return at<4>().as_int64(); }
+  bool has_double_value() const { return at<5>().valid(); }
+  double double_value() const { return at<5>().as_double(); }
+  bool has_pointer_value() const { return at<7>().valid(); }
+  uint64_t pointer_value() const { return at<7>().as_uint64(); }
+  bool has_nested_value() const { return at<8>().valid(); }
+  ::protozero::ConstBytes nested_value() const { return at<8>().as_bytes(); }
+  bool has_legacy_json_value() const { return at<9>().valid(); }
+  ::protozero::ConstChars legacy_json_value() const { return at<9>().as_string(); }
+  bool has_string_value() const { return at<6>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<6>().as_string(); }
+  bool has_string_value_iid() const { return at<17>().valid(); }
+  uint64_t string_value_iid() const { return at<17>().as_uint64(); }
+  bool has_proto_type_name() const { return at<16>().valid(); }
+  ::protozero::ConstChars proto_type_name() const { return at<16>().as_string(); }
+  bool has_proto_type_name_iid() const { return at<13>().valid(); }
+  uint64_t proto_type_name_iid() const { return at<13>().as_uint64(); }
+  bool has_proto_value() const { return at<14>().valid(); }
+  ::protozero::ConstBytes proto_value() const { return at<14>().as_bytes(); }
+  bool has_dict_entries() const { return at<11>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> dict_entries() const { return GetRepeated<::protozero::ConstBytes>(11); }
+  bool has_array_values() const { return at<12>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> array_values() const { return GetRepeated<::protozero::ConstBytes>(12); }
+};
+
+class DebugAnnotation : public ::protozero::Message {
+ public:
+  using Decoder = DebugAnnotation_Decoder;
+  enum : int32_t {
+    kNameIidFieldNumber = 1,
+    kNameFieldNumber = 10,
+    kBoolValueFieldNumber = 2,
+    kUintValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kDoubleValueFieldNumber = 5,
+    kPointerValueFieldNumber = 7,
+    kNestedValueFieldNumber = 8,
+    kLegacyJsonValueFieldNumber = 9,
+    kStringValueFieldNumber = 6,
+    kStringValueIidFieldNumber = 17,
+    kProtoTypeNameFieldNumber = 16,
+    kProtoTypeNameIidFieldNumber = 13,
+    kProtoValueFieldNumber = 14,
+    kDictEntriesFieldNumber = 11,
+    kArrayValuesFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DebugAnnotation"; }
+
+  using NestedValue = ::perfetto::protos::pbzero::DebugAnnotation_NestedValue;
+
+  using FieldMetadata_NameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_NameIid kNameIid{};
+  void set_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BoolValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_BoolValue kBoolValue{};
+  void set_bool_value(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BoolValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UintValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_UintValue kUintValue{};
+  void set_uint_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UintValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PointerValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_PointerValue kPointerValue{};
+  void set_pointer_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PointerValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NestedValue =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation_NestedValue,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_NestedValue kNestedValue{};
+  template <typename T = DebugAnnotation_NestedValue> T* set_nested_value() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_LegacyJsonValue =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_LegacyJsonValue kLegacyJsonValue{};
+  void set_legacy_json_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LegacyJsonValue::kFieldId, data, size);
+  }
+  void set_legacy_json_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LegacyJsonValue::kFieldId, chars.data, chars.size);
+  }
+  void set_legacy_json_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacyJsonValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringValueIid =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_StringValueIid kStringValueIid{};
+  void set_string_value_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValueIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProtoTypeName =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_ProtoTypeName kProtoTypeName{};
+  void set_proto_type_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProtoTypeName::kFieldId, data, size);
+  }
+  void set_proto_type_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProtoTypeName::kFieldId, chars.data, chars.size);
+  }
+  void set_proto_type_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProtoTypeName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProtoTypeNameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_ProtoTypeNameIid kProtoTypeNameIid{};
+  void set_proto_type_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProtoTypeNameIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProtoValue =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_ProtoValue kProtoValue{};
+  void set_proto_value(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_ProtoValue::kFieldId, data, size);
+  }
+  void set_proto_value(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_ProtoValue::kFieldId, bytes.data, bytes.size);
+  }
+  void set_proto_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProtoValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DictEntries =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_DictEntries kDictEntries{};
+  template <typename T = DebugAnnotation> T* add_dict_entries() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_ArrayValues =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      DebugAnnotation>;
+
+  static constexpr FieldMetadata_ArrayValues kArrayValues{};
+  template <typename T = DebugAnnotation> T* add_array_values() {
+    return BeginNestedMessage<T>(12);
+  }
+
+};
+
+class DebugAnnotation_NestedValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  DebugAnnotation_NestedValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DebugAnnotation_NestedValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DebugAnnotation_NestedValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nested_type() const { return at<1>().valid(); }
+  int32_t nested_type() const { return at<1>().as_int32(); }
+  bool has_dict_keys() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> dict_keys() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_dict_values() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> dict_values() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_array_values() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> array_values() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_int_value() const { return at<5>().valid(); }
+  int64_t int_value() const { return at<5>().as_int64(); }
+  bool has_double_value() const { return at<6>().valid(); }
+  double double_value() const { return at<6>().as_double(); }
+  bool has_bool_value() const { return at<7>().valid(); }
+  bool bool_value() const { return at<7>().as_bool(); }
+  bool has_string_value() const { return at<8>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<8>().as_string(); }
+};
+
+class DebugAnnotation_NestedValue : public ::protozero::Message {
+ public:
+  using Decoder = DebugAnnotation_NestedValue_Decoder;
+  enum : int32_t {
+    kNestedTypeFieldNumber = 1,
+    kDictKeysFieldNumber = 2,
+    kDictValuesFieldNumber = 3,
+    kArrayValuesFieldNumber = 4,
+    kIntValueFieldNumber = 5,
+    kDoubleValueFieldNumber = 6,
+    kBoolValueFieldNumber = 7,
+    kStringValueFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DebugAnnotation.NestedValue"; }
+
+
+  using NestedType = ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType;
+  static inline const char* NestedType_Name(NestedType value) {
+    return ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType_Name(value);
+  }
+  static inline const NestedType UNSPECIFIED = NestedType::UNSPECIFIED;
+  static inline const NestedType DICT = NestedType::DICT;
+  static inline const NestedType ARRAY = NestedType::ARRAY;
+
+  using FieldMetadata_NestedType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_NestedType kNestedType{};
+  void set_nested_type(::perfetto::protos::pbzero::DebugAnnotation_NestedValue_NestedType value) {
+    static constexpr uint32_t field_id = FieldMetadata_NestedType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DictKeys =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_DictKeys kDictKeys{};
+  void add_dict_keys(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, data, size);
+  }
+  void add_dict_keys(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, chars.data, chars.size);
+  }
+  void add_dict_keys(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DictKeys::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DictValues =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation_NestedValue,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_DictValues kDictValues{};
+  template <typename T = DebugAnnotation_NestedValue> T* add_dict_values() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ArrayValues =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation_NestedValue,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_ArrayValues kArrayValues{};
+  template <typename T = DebugAnnotation_NestedValue> T* add_array_values() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BoolValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_BoolValue kBoolValue{};
+  void set_bool_value(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BoolValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DebugAnnotation_NestedValue>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_DEBUG_ANNOTATION_H_
+#define INCLUDE_PERFETTO_TRACING_DEBUG_ANNOTATION_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value_forward.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+
+namespace {
+// std::underlying_type can't be used with non-enum types, so we need this
+// indirection.
+template <typename T, bool = std::is_enum<T>::value>
+struct safe_underlying_type {
+  using type = typename std::underlying_type<T>::type;
+};
+
+template <typename T>
+struct safe_underlying_type<T, false> {
+  using type = T;
+};
+}  // namespace
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+}  // namespace pbzero
+}  // namespace protos
+
+// A base class for custom track event debug annotations.
+class PERFETTO_EXPORT_COMPONENT DebugAnnotation {
+ public:
+  DebugAnnotation() = default;
+  virtual ~DebugAnnotation();
+
+  // Called to write the contents of the debug annotation into the trace.
+  virtual void Add(protos::pbzero::DebugAnnotation*) const = 0;
+
+  void WriteIntoTracedValue(TracedValue context) const;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_DEBUG_ANNOTATION_H_
+// gen_amalgamated begin header: include/perfetto/tracing/traced_value.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/checked_scope.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_CHECKED_SCOPE_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_CHECKED_SCOPE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+namespace perfetto {
+namespace internal {
+
+#if PERFETTO_DCHECK_IS_ON()
+
+// Checker to ensure that despite multiple scopes being present, only the active
+// one is being accessed. Rules:
+// - Only an active scope can create inner scopes. When this happens, it stops
+// being active and the inner scope becomes active instead.
+// - Only an active scope can be destroyed. When this happens, its parent scope
+// becomes active.
+class PERFETTO_EXPORT_COMPONENT CheckedScope {
+ public:
+  explicit CheckedScope(CheckedScope* parent_scope);
+  ~CheckedScope();
+  CheckedScope(CheckedScope&&);
+  CheckedScope& operator=(CheckedScope&&);
+  CheckedScope(const CheckedScope&) = delete;
+  CheckedScope& operator=(const CheckedScope&) = delete;
+
+  void Reset();
+
+  CheckedScope* parent_scope() const { return parent_scope_; }
+  bool is_active() const { return is_active_; }
+
+ private:
+  void set_is_active(bool is_active) { is_active_ = is_active; }
+
+  bool is_active_ = true;
+  CheckedScope* parent_scope_;
+
+  bool deleted_ = false;
+};
+
+#else
+
+// Dummy for cases when DCHECK is not enabled. Methods are marked constexpr to
+// ensure that the compiler can inline and optimise them away.
+class CheckedScope {
+ public:
+  inline explicit CheckedScope(CheckedScope*) {}
+  inline ~CheckedScope() {}
+
+  CheckedScope(const CheckedScope&) = delete;
+  CheckedScope& operator=(const CheckedScope&) = delete;
+
+  CheckedScope(CheckedScope&&) = default;
+  CheckedScope& operator=(CheckedScope&&) = default;
+
+  inline void Reset() {}
+
+  inline CheckedScope* parent_scope() const { return nullptr; }
+  inline bool is_active() const { return true; }
+};
+
+#endif  // PERFETTO_DCHECK_IS_ON()
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_CHECKED_SCOPE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/string_helpers.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_STRING_HELPERS_H_
+#define INCLUDE_PERFETTO_TRACING_STRING_HELPERS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+
+#include <cstddef>
+#include <string>
+
+namespace perfetto {
+
+// A wrapper for marking strings that can't be determined to be static at build
+// time, but are in fact static.
+class PERFETTO_EXPORT_COMPONENT StaticString {
+ public:
+  // Implicit constructor for string literals.
+  template <size_t N>
+  constexpr StaticString(const char (&str)[N]) : value(str) {}
+
+  // Implicit constructor for null strings.
+  constexpr StaticString(std::nullptr_t) : value(nullptr) {}
+
+  constexpr explicit StaticString(const char* str) : value(str) {}
+
+  const char* value;
+};
+
+// A explicit wrapper for marking strings as dynamic to ensure that perfetto
+// doesn't try to cache the pointer value.
+class PERFETTO_EXPORT_COMPONENT DynamicString {
+ public:
+  explicit DynamicString(const std::string& str)
+      : value(str.data()), length(str.length()) {}
+  explicit DynamicString(const char* str) : value(str) {
+    PERFETTO_DCHECK(str);
+    length = strlen(str);
+  }
+  DynamicString(const char* str, size_t len) : value(str), length(len) {}
+
+  const char* value;
+  size_t length;
+};
+
+namespace internal {
+
+template <size_t N>
+constexpr const char* GetStaticString(const char (&string)[N]) {
+  return string;
+}
+
+constexpr std::nullptr_t GetStaticString(std::nullptr_t) {
+  return nullptr;
+}
+
+constexpr const char* GetStaticString(perfetto::StaticString string) {
+  return string.value;
+}
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_STRING_HELPERS_H_
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACED_VALUE_H_
+#define INCLUDE_PERFETTO_TRACING_TRACED_VALUE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/template_util.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/checked_scope.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/string_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value_forward.h"
+
+#include <memory>
+#include <string>
+#include <string_view>
+#include <type_traits>
+#include <utility>
+
+namespace perfetto {
+
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+}
+}  // namespace protos
+
+class DebugAnnotation;
+class EventContext;
+
+// These classes provide a JSON-inspired way to write structed data into traces.
+//
+// Each TracedValue can be consumed exactly once to write a value into a trace
+// using one of the Write* methods.
+//
+// Write* methods fall into two categories:
+// - Primitive types (int, string, bool, double, etc): they just write the
+//   provided value, consuming the TracedValue in the process.
+// - Complex types (arrays and dicts): they consume the TracedValue and
+//   return a corresponding scoped object (TracedArray or TracedDictionary).
+//   This scope then can be used to write multiple items into the container:
+//   TracedArray::AppendItem and TracedDictionary::AddItem return a new
+//   TracedValue which then can be used to write an element of the
+//   dictionary or array.
+//
+// To define how a custom class should be written into the trace, users should
+// define one of the two following functions:
+// - Foo::WriteIntoTrace(TracedValue) const
+//   (preferred for code which depends on perfetto directly)
+// - perfetto::TraceFormatTraits<T>::WriteIntoTrace(
+//       TracedValue, const T&);
+//   (should be used if T is defined in a library which doesn't know anything
+//   about tracing).
+//
+//
+// After defining a conversion method, the object can be used directly as a
+// TRACE_EVENT argument:
+//
+// Foo foo;
+// TRACE_EVENT("cat", "Event", "arg", foo);
+//
+// Examples:
+//
+// TRACE_EVENT("cat", "event", "params", [&](perfetto::TracedValue context)
+// {
+//   auto dict = std::move(context).WriteDictionary();
+//   dict->Add("param1", param1);
+//   dict->Add("param2", param2);
+//   ...
+//   dict->Add("paramN", paramN);
+//
+//   {
+//     auto inner_array = dict->AddArray("inner");
+//     inner_array->Append(value1);
+//     inner_array->Append(value2);
+//   }
+// });
+//
+// template <typename T>
+// TraceFormatTraits<std::optional<T>>::WriteIntoTrace(
+//    TracedValue context, const std::optional<T>& value) {
+//  if (!value) {
+//    std::move(context).WritePointer(nullptr);
+//    return;
+//  }
+//  perfetto::WriteIntoTrace(std::move(context), *value);
+// }
+//
+// template <typename T>
+// TraceFormatTraits<std::vector<T>>::WriteIntoTrace(
+//    TracedValue context, const std::array<T>& value) {
+//  auto array = std::move(context).WriteArray();
+//  for (const auto& item: value) {
+//    array_scope.Append(item);
+//  }
+// }
+//
+// class Foo {
+//   void WriteIntoTrace(TracedValue context) const {
+//     auto dict = std::move(context).WriteDictionary();
+//     dict->Set("key", 42);
+//     dict->Set("foo", "bar");
+//     dict->Set("member", member_);
+//   }
+// }
+namespace internal {
+// TODO(altimin): Currently EventContext can be null due the need to support
+// TracedValue-based serialisation with the Chrome's TraceLog. After this is
+// gone, the second parameter should be changed to EventContext&.
+PERFETTO_EXPORT_COMPONENT TracedValue
+CreateTracedValueFromProto(protos::pbzero::DebugAnnotation*,
+                           EventContext* = nullptr);
+}
+
+class PERFETTO_EXPORT_COMPONENT TracedValue {
+ public:
+  TracedValue(const TracedValue&) = delete;
+  TracedValue& operator=(const TracedValue&) = delete;
+  TracedValue& operator=(TracedValue&&) = delete;
+  TracedValue(TracedValue&&);
+  ~TracedValue();
+
+  // TracedValue represents a context into which a single value can be written
+  // (either by writing it directly for primitive types, or by creating a
+  // TracedArray or TracedDictionary for the complex types). This is enforced
+  // by allowing Write* methods to be called only on rvalue references.
+
+  void WriteInt64(int64_t value) &&;
+  void WriteUInt64(uint64_t value) &&;
+  void WriteDouble(double value) &&;
+  void WriteBoolean(bool value) &&;
+  void WriteString(const char*) &&;
+  void WriteString(const char*, size_t len) &&;
+  void WriteString(const std::string&) &&;
+  void WriteString(std::string_view) &&;
+  void WritePointer(const void* value) &&;
+  template <typename MessageType>
+  TracedProto<MessageType> WriteProto() &&;
+
+  // Rules for writing nested dictionaries and arrays:
+  // - Only one scope (TracedArray, TracedDictionary or TracedValue) can be
+  // active at the same time. It's only allowed to call methods on the active
+  // scope.
+  // - When a scope creates a nested scope, the new scope becomes active.
+  // - When a scope is destroyed, its parent scope becomes active again.
+  //
+  // Typically users will have to create a scope only at the beginning of a
+  // conversion function and this scope should be destroyed at the end of it.
+  // TracedArray::Append and TracedDictionary::Add create, write and complete
+  // inner scopes automatically.
+
+  // Scope which allows multiple values to be appended.
+  TracedArray WriteArray() && PERFETTO_WARN_UNUSED_RESULT;
+
+  // Scope which allows multiple key-value pairs to be added.
+  TracedDictionary WriteDictionary() && PERFETTO_WARN_UNUSED_RESULT;
+
+ private:
+  friend class TracedArray;
+  friend class TracedDictionary;
+  friend TracedValue internal::CreateTracedValueFromProto(
+      protos::pbzero::DebugAnnotation*,
+      EventContext*);
+
+  static TracedValue CreateFromProto(protos::pbzero::DebugAnnotation* proto,
+                                     EventContext* event_context = nullptr);
+
+  inline TracedValue(protos::pbzero::DebugAnnotation* annotation,
+                     EventContext* event_context,
+                     internal::CheckedScope* parent_scope)
+      : annotation_(annotation),
+        event_context_(event_context),
+        checked_scope_(parent_scope) {}
+
+  protozero::Message* WriteProtoInternal(const char* name);
+
+  // Temporary support for perfetto::DebugAnnotation C++ class before it's going
+  // to be replaced by TracedValue.
+  // TODO(altimin): Convert v8 to use TracedValue directly and delete it.
+  friend class DebugAnnotation;
+
+  protos::pbzero::DebugAnnotation* const annotation_ = nullptr;
+  EventContext* const event_context_ = nullptr;
+
+  internal::CheckedScope checked_scope_;
+};
+
+template <typename MessageType>
+TracedProto<MessageType> TracedValue::WriteProto() && {
+  return TracedProto<MessageType>(
+      static_cast<MessageType*>(WriteProtoInternal(MessageType::GetName())),
+      event_context_);
+}
+
+class PERFETTO_EXPORT_COMPONENT TracedArray {
+ public:
+  // implicit
+  TracedArray(TracedValue);
+
+  TracedArray(const TracedArray&) = delete;
+  TracedArray& operator=(const TracedArray&) = delete;
+  TracedArray& operator=(TracedArray&&) = delete;
+  TracedArray(TracedArray&&) = default;
+  ~TracedArray() = default;
+
+  TracedValue AppendItem();
+
+  template <typename T>
+  void Append(T&& value) {
+    WriteIntoTracedValue(AppendItem(), std::forward<T>(value));
+  }
+
+  TracedDictionary AppendDictionary() PERFETTO_WARN_UNUSED_RESULT;
+  TracedArray AppendArray();
+
+ private:
+  friend class TracedValue;
+
+  inline TracedArray(protos::pbzero::DebugAnnotation* annotation,
+                     EventContext* event_context,
+                     internal::CheckedScope* parent_scope)
+      : annotation_(annotation),
+        event_context_(event_context),
+        checked_scope_(parent_scope) {}
+
+  protos::pbzero::DebugAnnotation* annotation_;
+  EventContext* const event_context_;
+
+  internal::CheckedScope checked_scope_;
+};
+
+class PERFETTO_EXPORT_COMPONENT TracedDictionary {
+ public:
+  // implicit
+  TracedDictionary(TracedValue);
+
+  TracedDictionary(const TracedDictionary&) = delete;
+  TracedDictionary& operator=(const TracedDictionary&) = delete;
+  TracedDictionary& operator=(TracedDictionary&&) = delete;
+  TracedDictionary(TracedDictionary&&) = default;
+  ~TracedDictionary() = default;
+
+  // There are two paths for writing dictionary keys: fast path for writing
+  // compile-time const, whose pointer is remains valid during the entire
+  // runtime of the program and the slow path for dynamic strings, which need to
+  // be copied.
+  // In the most common case, a string literal can be passed to `Add`/`AddItem`.
+  // In other cases, either StaticString or DynamicString declarations are
+  // needed.
+
+  TracedValue AddItem(StaticString key);
+  TracedValue AddItem(DynamicString key);
+
+  template <typename T>
+  void Add(StaticString key, T&& value) {
+    WriteIntoTracedValue(AddItem(key), std::forward<T>(value));
+  }
+
+  template <typename T>
+  void Add(DynamicString key, T&& value) {
+    WriteIntoTracedValue(AddItem(key), std::forward<T>(value));
+  }
+
+  TracedDictionary AddDictionary(StaticString key);
+  TracedDictionary AddDictionary(DynamicString key);
+  TracedArray AddArray(StaticString key);
+  TracedArray AddArray(DynamicString key);
+
+ private:
+  friend class TracedValue;
+  template <typename T>
+  friend class TracedProto;
+
+  // Create a |TracedDictionary| which will populate the given field of the
+  // given |message|.
+  template <typename MessageType, typename FieldMetadata>
+  inline TracedDictionary(MessageType* message,
+                          FieldMetadata,
+                          EventContext* event_context,
+                          internal::CheckedScope* parent_scope)
+      : message_(message),
+        field_id_(FieldMetadata::kFieldId),
+        event_context_(event_context),
+        checked_scope_(parent_scope) {
+    static_assert(std::is_base_of<protozero::Message, MessageType>::value,
+                  "Message should be a subclass of protozero::Message");
+    static_assert(std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+                                  FieldMetadata>::value,
+                  "FieldMetadata should be a subclass of FieldMetadataBase");
+    static_assert(
+        std::is_same<typename FieldMetadata::message_type, MessageType>::value,
+        "Field does not belong to this message");
+    static_assert(
+        std::is_same<typename FieldMetadata::cpp_field_type,
+                     ::perfetto::protos::pbzero::DebugAnnotation>::value,
+        "Field should be of DebugAnnotation type");
+    static_assert(
+        FieldMetadata::kRepetitionType ==
+            protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+        "Field should be non-packed repeated");
+  }
+
+  protozero::Message* const message_;
+  const uint32_t field_id_;
+  EventContext* event_context_;
+
+  internal::CheckedScope checked_scope_;
+};
+
+namespace internal {
+
+// SFINAE helpers for finding a right overload to convert a given class to
+// trace-friendly form, ordered from most to least preferred.
+
+constexpr int kMaxWriteImplPriority = 4;
+
+// If T has WriteIntoTracedValue member function, call it.
+template <typename T>
+decltype(std::declval<T>().WriteIntoTracedValue(std::declval<TracedValue>()),
+         void())
+WriteImpl(base::priority_tag<4>, TracedValue context, T&& value) {
+  value.WriteIntoTracedValue(std::move(context));
+}
+
+// If T has WriteIntoTrace member function, call it.
+template <typename T>
+decltype(std::declval<T>().WriteIntoTrace(std::declval<TracedValue>()), void())
+WriteImpl(base::priority_tag<4>, TracedValue context, T&& value) {
+  value.WriteIntoTrace(std::move(context));
+}
+
+// If perfetto::TraceFormatTraits<T>::WriteIntoTracedValue(TracedValue, const
+// T&) is available, use it.
+template <typename T>
+decltype(TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTracedValue(
+             std::declval<TracedValue>(),
+             std::declval<T>()),
+         void())
+WriteImpl(base::priority_tag<3>, TracedValue context, T&& value) {
+  TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTracedValue(
+      std::move(context), std::forward<T>(value));
+}
+
+// If perfetto::TraceFormatTraits<T>::WriteIntoTrace(TracedValue, const T&)
+// is available, use it.
+template <typename T>
+decltype(TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTrace(
+             std::declval<TracedValue>(),
+             std::declval<T>()),
+         void())
+WriteImpl(base::priority_tag<3>, TracedValue context, T&& value) {
+  TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTrace(
+      std::move(context), std::forward<T>(value));
+}
+
+// If T has operator(), which takes TracedValue, use it.
+// Very useful for lambda resolutions.
+template <typename T>
+decltype(std::declval<T>()(std::declval<TracedValue>()), void())
+WriteImpl(base::priority_tag<2>, TracedValue context, T&& value) {
+  std::forward<T>(value)(std::move(context));
+}
+
+// If T is a container and its elements have tracing support, use it.
+//
+// Note: a reference to T should be passed to std::begin, otherwise
+// for non-reference types const T& will be passed to std::begin, losing
+// support for non-const WriteIntoTracedValue methods.
+template <typename T>
+typename check_traced_value_support<
+    decltype(*std::begin(std::declval<T&>()))>::type
+WriteImpl(base::priority_tag<1>, TracedValue context, T&& value) {
+  auto array = std::move(context).WriteArray();
+  for (auto&& item : value) {
+    array.Append(item);
+  }
+}
+
+// std::underlying_type can't be used with non-enum types, so we need this
+// indirection.
+template <typename T, bool = std::is_enum<T>::value>
+struct safe_underlying_type {
+  using type = typename std::underlying_type<T>::type;
+};
+
+template <typename T>
+struct safe_underlying_type<T, false> {
+  using type = T;
+};
+
+template <typename T>
+struct is_incomplete_type {
+  static constexpr bool value = sizeof(T) != 0;
+};
+
+// sizeof is not available for const char[], but it's still not considered to be
+// an incomplete type for our purposes as the size can be determined at runtime
+// due to strings being null-terminated.
+template <>
+struct is_incomplete_type<const char[]> {
+  static constexpr bool value = true;
+};
+
+}  // namespace internal
+
+// Helper template to determine if a given type can be passed to
+// perfetto::WriteIntoTracedValue. These templates will fail to resolve if the
+// class does not have it support, so they are useful in SFINAE and in producing
+// helpful compiler results.
+template <typename T, class Result = void>
+using check_traced_value_support_t = decltype(
+    internal::WriteImpl(
+        std::declval<base::priority_tag<internal::kMaxWriteImplPriority>>(),
+        std::declval<TracedValue>(),
+        std::declval<T>()),
+    std::declval<Result>());
+
+// check_traced_value_support<T, V>::type is defined (and equal to V) iff T
+// supports being passed to WriteIntoTracedValue. See the comment in
+// traced_value_forward.h for more details.
+template <typename T, class Result>
+struct check_traced_value_support<T,
+                                  Result,
+                                  check_traced_value_support_t<T, Result>> {
+  static_assert(
+      internal::is_incomplete_type<T>::value,
+      "perfetto::TracedValue should not be used with incomplete types");
+
+  static constexpr bool value = true;
+  using type = Result;
+};
+
+namespace internal {
+
+// Helper class to check if a given type can be passed to
+// perfetto::WriteIntoTracedValue. This template will always resolve (with
+// |value| being set to either true or false depending on presence of the
+// support, so this macro is useful in the situation when you want to e.g. OR
+// the result with some other conditions.
+//
+// In this case, compiler will not give you the full deduction chain, so, for
+// example, use check_traced_value_support for writing positive static_asserts
+// and has_traced_value_support for writing negative.
+template <typename T>
+class has_traced_value_support {
+  using Yes = char[1];
+  using No = char[2];
+
+  template <typename V>
+  static Yes& check_support(check_traced_value_support_t<V, int>);
+  template <typename V>
+  static No& check_support(...);
+
+ public:
+  static constexpr bool value = sizeof(Yes) == sizeof(check_support<T>(0));
+};
+
+}  // namespace internal
+
+template <typename T>
+void WriteIntoTracedValue(TracedValue context, T&& value) {
+  // TODO(altimin): Add a URL to documentation and a list of common failure
+  // patterns.
+  static_assert(
+      internal::has_traced_value_support<T>::value,
+      "The provided type (passed to TRACE_EVENT argument / TracedArray::Append "
+      "/ TracedDictionary::Add) does not support being written in a trace "
+      "format. Please see the comment in traced_value.h for more details.");
+
+  // Should be kept in sync with check_traced_value_support_t!
+  internal::WriteImpl(base::priority_tag<internal::kMaxWriteImplPriority>(),
+                      std::move(context), std::forward<T>(value));
+}
+
+// Helpers to write a given value into TracedValue even if the given type
+// doesn't support conversion (in which case the provided fallback should be
+// used). Useful for automatically generating conversions for autogenerated
+// code, but otherwise shouldn't be used as non-autogenerated code is expected
+// to define WriteIntoTracedValue convertor.
+// See WriteWithFallback test in traced_value_unittest.cc for a concrete
+// example.
+template <typename T>
+typename std::enable_if<internal::has_traced_value_support<T>::value>::type
+WriteIntoTracedValueWithFallback(TracedValue context,
+                                 T&& value,
+                                 const std::string&) {
+  WriteIntoTracedValue(std::move(context), std::forward<T>(value));
+}
+
+template <typename T>
+typename std::enable_if<!internal::has_traced_value_support<T>::value>::type
+WriteIntoTracedValueWithFallback(TracedValue context,
+                                 T&&,
+                                 const std::string& fallback) {
+  std::move(context).WriteString(fallback);
+}
+
+// TraceFormatTraits implementations for primitive types.
+
+// Specialisation for signed integer types (note: it excludes enums, which have
+// their own explicit specialisation).
+template <typename T>
+struct TraceFormatTraits<
+    T,
+    typename std::enable_if<std::is_integral<T>::value &&
+                            !std::is_same<T, bool>::value &&
+                            std::is_signed<T>::value>::type> {
+  inline static void WriteIntoTrace(TracedValue context, T value) {
+    std::move(context).WriteInt64(value);
+  }
+};
+
+// Specialisation for unsigned integer types (note: it excludes enums, which
+// have their own explicit specialisation).
+template <typename T>
+struct TraceFormatTraits<
+    T,
+    typename std::enable_if<std::is_integral<T>::value &&
+                            !std::is_same<T, bool>::value &&
+                            std::is_unsigned<T>::value>::type> {
+  inline static void WriteIntoTrace(TracedValue context, T value) {
+    std::move(context).WriteUInt64(value);
+  }
+};
+
+// Specialisation for bools.
+template <>
+struct TraceFormatTraits<bool> {
+  inline static void WriteIntoTrace(TracedValue context, bool value) {
+    std::move(context).WriteBoolean(value);
+  }
+};
+
+// Specialisation for floating point values.
+template <typename T>
+struct TraceFormatTraits<
+    T,
+    typename std::enable_if<std::is_floating_point<T>::value>::type> {
+  inline static void WriteIntoTrace(TracedValue context, T value) {
+    std::move(context).WriteDouble(static_cast<double>(value));
+  }
+};
+
+// Specialisation for signed enums.
+template <typename T>
+struct TraceFormatTraits<
+    T,
+    typename std::enable_if<
+        std::is_enum<T>::value &&
+        std::is_signed<
+            typename internal::safe_underlying_type<T>::type>::value>::type> {
+  inline static void WriteIntoTrace(TracedValue context, T value) {
+    std::move(context).WriteInt64(static_cast<int64_t>(value));
+  }
+};
+
+// Specialisation for unsigned enums.
+template <typename T>
+struct TraceFormatTraits<
+    T,
+    typename std::enable_if<
+        std::is_enum<T>::value &&
+        std::is_unsigned<
+            typename internal::safe_underlying_type<T>::type>::value>::type> {
+  inline static void WriteIntoTrace(TracedValue context, T value) {
+    std::move(context).WriteUInt64(static_cast<uint64_t>(value));
+  }
+};
+
+// Specialisations for C-style strings.
+template <>
+struct TraceFormatTraits<const char*> {
+  inline static void WriteIntoTrace(TracedValue context, const char* value) {
+    std::move(context).WriteString(value);
+  }
+};
+
+template <>
+struct TraceFormatTraits<char[]> {
+  inline static void WriteIntoTrace(TracedValue context, const char value[]) {
+    std::move(context).WriteString(value);
+  }
+};
+
+template <size_t N>
+struct TraceFormatTraits<char[N]> {
+  inline static void WriteIntoTrace(TracedValue context, const char value[N]) {
+    std::move(context).WriteString(value);
+  }
+};
+
+// Specialization for Perfetto strings.
+template <>
+struct TraceFormatTraits<perfetto::StaticString> {
+  inline static void WriteIntoTrace(TracedValue context,
+                                    perfetto::StaticString str) {
+    std::move(context).WriteString(str.value);
+  }
+};
+
+template <>
+struct TraceFormatTraits<perfetto::DynamicString> {
+  inline static void WriteIntoTrace(TracedValue context,
+                                    perfetto::DynamicString str) {
+    std::move(context).WriteString(str.value, str.length);
+  }
+};
+
+// Specialisation for C++ strings.
+template <>
+struct TraceFormatTraits<std::string> {
+  inline static void WriteIntoTrace(TracedValue context,
+                                    const std::string& value) {
+    std::move(context).WriteString(value);
+  }
+};
+
+// Specialisation for C++ string_views.
+template <>
+struct TraceFormatTraits<std::string_view> {
+  inline static void WriteIntoTrace(TracedValue context,
+                                    std::string_view value) {
+    std::move(context).WriteString(value);
+  }
+};
+
+// Specialisation for (const) void*, which writes the pointer value.
+template <>
+struct TraceFormatTraits<void*> {
+  inline static void WriteIntoTrace(TracedValue context, void* value) {
+    std::move(context).WritePointer(value);
+  }
+};
+
+template <>
+struct TraceFormatTraits<const void*> {
+  inline static void WriteIntoTrace(TracedValue context, const void* value) {
+    std::move(context).WritePointer(value);
+  }
+};
+
+// Specialisation for std::unique_ptr<>, which writes either nullptr or the
+// object it points to.
+template <typename T>
+struct TraceFormatTraits<std::unique_ptr<T>, check_traced_value_support_t<T>> {
+  inline static void WriteIntoTrace(TracedValue context,
+                                    const std::unique_ptr<T>& value) {
+    ::perfetto::WriteIntoTracedValue(std::move(context), value.get());
+  }
+
+  template <typename MessageType>
+  inline static void WriteIntoTrace(TracedProto<MessageType> message,
+                                    const std::unique_ptr<T>& value) {
+    ::perfetto::WriteIntoTracedProto(std::move(message), value.get());
+  }
+};
+
+// Specialisation for raw pointer, which writes either nullptr or the object it
+// points to.
+template <typename T>
+struct TraceFormatTraits<T*, check_traced_value_support_t<T>> {
+  inline static void WriteIntoTrace(TracedValue context, T* value) {
+    if (!value) {
+      std::move(context).WritePointer(nullptr);
+      return;
+    }
+    ::perfetto::WriteIntoTracedValue(std::move(context), *value);
+  }
+
+  template <typename MessageType>
+  inline static void WriteIntoTrace(TracedProto<MessageType> message,
+                                    T* value) {
+    if (!value) {
+      // Start the message, but do not write anything. TraceProcessor will emit
+      // a NULL value.
+      return;
+    }
+
+    ::perfetto::WriteIntoTracedProto(std::move(message), *value);
+  }
+};
+
+// Specialisation for nullptr.
+template <>
+struct TraceFormatTraits<std::nullptr_t> {
+  inline static void WriteIntoTrace(TracedValue context, std::nullptr_t) {
+    std::move(context).WritePointer(nullptr);
+  }
+
+  template <typename MessageType>
+  inline static void WriteIntoTrace(TracedProto<MessageType>, std::nullptr_t) {
+    // Start the message, but do not write anything. TraceProcessor will emit a
+    // NULL value.
+  }
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACED_VALUE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track.h
+// gen_amalgamated begin header: include/perfetto/tracing/internal/compile_time_hash.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_COMPILE_TIME_HASH_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_COMPILE_TIME_HASH_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace perfetto {
+namespace internal {
+
+// A helper class which computes a 64-bit hash of the input data at compile
+// time. The algorithm used is FNV-1a as it is fast and easy to implement and
+// has relatively few collisions.
+// WARNING: This hash function should not be used for any cryptographic purpose.
+class CompileTimeHash {
+ public:
+  // Creates an empty hash object
+  constexpr inline CompileTimeHash() {}
+
+  // Hashes a byte array.
+  constexpr inline CompileTimeHash Update(const char* data, size_t size) const {
+    return CompileTimeHash(HashRecursively(kFnv1a64OffsetBasis, data, size));
+  }
+
+  constexpr inline uint64_t digest() const { return result_; }
+
+ private:
+  constexpr inline CompileTimeHash(uint64_t result) : result_(result) {}
+
+  static constexpr inline uint64_t HashRecursively(uint64_t value,
+                                                   const char* data,
+                                                   size_t size) {
+    return !size ? value
+                 : HashRecursively(
+                       (value ^ static_cast<uint8_t>(*data)) * kFnv1a64Prime,
+                       data + 1, size - 1);
+  }
+
+  static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
+  static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
+
+  uint64_t result_ = kFnv1a64OffsetBasis;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_COMPILE_TIME_HASH_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class CounterDescriptor;
+enum CounterDescriptor_BuiltinCounterType : int;
+enum CounterDescriptor_Unit : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum CounterDescriptor_BuiltinCounterType : int {
+  CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED = 0,
+  CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS = 1,
+  CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT = 2,
+};
+enum CounterDescriptor_Unit : int {
+  CounterDescriptor_Unit_UNIT_UNSPECIFIED = 0,
+  CounterDescriptor_Unit_UNIT_TIME_NS = 1,
+  CounterDescriptor_Unit_UNIT_COUNT = 2,
+  CounterDescriptor_Unit_UNIT_SIZE_BYTES = 3,
+};
+
+class PERFETTO_EXPORT_COMPONENT CounterDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using BuiltinCounterType = CounterDescriptor_BuiltinCounterType;
+  static constexpr auto COUNTER_UNSPECIFIED = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
+  static constexpr auto COUNTER_THREAD_TIME_NS = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS;
+  static constexpr auto COUNTER_THREAD_INSTRUCTION_COUNT = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
+  static constexpr auto BuiltinCounterType_MIN = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
+  static constexpr auto BuiltinCounterType_MAX = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
+  using Unit = CounterDescriptor_Unit;
+  static constexpr auto UNIT_UNSPECIFIED = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
+  static constexpr auto UNIT_TIME_NS = CounterDescriptor_Unit_UNIT_TIME_NS;
+  static constexpr auto UNIT_COUNT = CounterDescriptor_Unit_UNIT_COUNT;
+  static constexpr auto UNIT_SIZE_BYTES = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
+  static constexpr auto Unit_MIN = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
+  static constexpr auto Unit_MAX = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
+  enum FieldNumbers {
+    kTypeFieldNumber = 1,
+    kCategoriesFieldNumber = 2,
+    kUnitFieldNumber = 3,
+    kUnitNameFieldNumber = 6,
+    kUnitMultiplierFieldNumber = 4,
+    kIsIncrementalFieldNumber = 5,
+  };
+
+  CounterDescriptor();
+  ~CounterDescriptor() override;
+  CounterDescriptor(CounterDescriptor&&) noexcept;
+  CounterDescriptor& operator=(CounterDescriptor&&);
+  CounterDescriptor(const CounterDescriptor&);
+  CounterDescriptor& operator=(const CounterDescriptor&);
+  bool operator==(const CounterDescriptor&) const;
+  bool operator!=(const CounterDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_type() const { return _has_field_[1]; }
+  CounterDescriptor_BuiltinCounterType type() const { return type_; }
+  void set_type(CounterDescriptor_BuiltinCounterType value) { type_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& categories() const { return categories_; }
+  std::vector<std::string>* mutable_categories() { return &categories_; }
+  int categories_size() const { return static_cast<int>(categories_.size()); }
+  void clear_categories() { categories_.clear(); }
+  void add_categories(std::string value) { categories_.emplace_back(value); }
+  std::string* add_categories() { categories_.emplace_back(); return &categories_.back(); }
+
+  bool has_unit() const { return _has_field_[3]; }
+  CounterDescriptor_Unit unit() const { return unit_; }
+  void set_unit(CounterDescriptor_Unit value) { unit_ = value; _has_field_.set(3); }
+
+  bool has_unit_name() const { return _has_field_[6]; }
+  const std::string& unit_name() const { return unit_name_; }
+  void set_unit_name(const std::string& value) { unit_name_ = value; _has_field_.set(6); }
+
+  bool has_unit_multiplier() const { return _has_field_[4]; }
+  int64_t unit_multiplier() const { return unit_multiplier_; }
+  void set_unit_multiplier(int64_t value) { unit_multiplier_ = value; _has_field_.set(4); }
+
+  bool has_is_incremental() const { return _has_field_[5]; }
+  bool is_incremental() const { return is_incremental_; }
+  void set_is_incremental(bool value) { is_incremental_ = value; _has_field_.set(5); }
+
+ private:
+  CounterDescriptor_BuiltinCounterType type_{};
+  std::vector<std::string> categories_;
+  CounterDescriptor_Unit unit_{};
+  std::string unit_name_{};
+  int64_t unit_multiplier_{};
+  bool is_incremental_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/counter_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_CounterDescriptor {
+enum BuiltinCounterType : int32_t;
+}  // namespace perfetto_pbzero_enum_CounterDescriptor
+using CounterDescriptor_BuiltinCounterType = perfetto_pbzero_enum_CounterDescriptor::BuiltinCounterType;
+namespace perfetto_pbzero_enum_CounterDescriptor {
+enum Unit : int32_t;
+}  // namespace perfetto_pbzero_enum_CounterDescriptor
+using CounterDescriptor_Unit = perfetto_pbzero_enum_CounterDescriptor::Unit;
+
+namespace perfetto_pbzero_enum_CounterDescriptor {
+enum BuiltinCounterType : int32_t {
+  COUNTER_UNSPECIFIED = 0,
+  COUNTER_THREAD_TIME_NS = 1,
+  COUNTER_THREAD_INSTRUCTION_COUNT = 2,
+};
+} // namespace perfetto_pbzero_enum_CounterDescriptor
+using CounterDescriptor_BuiltinCounterType = perfetto_pbzero_enum_CounterDescriptor::BuiltinCounterType;
+
+
+constexpr CounterDescriptor_BuiltinCounterType CounterDescriptor_BuiltinCounterType_MIN = CounterDescriptor_BuiltinCounterType::COUNTER_UNSPECIFIED;
+constexpr CounterDescriptor_BuiltinCounterType CounterDescriptor_BuiltinCounterType_MAX = CounterDescriptor_BuiltinCounterType::COUNTER_THREAD_INSTRUCTION_COUNT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* CounterDescriptor_BuiltinCounterType_Name(::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType::COUNTER_UNSPECIFIED:
+    return "COUNTER_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType::COUNTER_THREAD_TIME_NS:
+    return "COUNTER_THREAD_TIME_NS";
+
+  case ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType::COUNTER_THREAD_INSTRUCTION_COUNT:
+    return "COUNTER_THREAD_INSTRUCTION_COUNT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_CounterDescriptor {
+enum Unit : int32_t {
+  UNIT_UNSPECIFIED = 0,
+  UNIT_TIME_NS = 1,
+  UNIT_COUNT = 2,
+  UNIT_SIZE_BYTES = 3,
+};
+} // namespace perfetto_pbzero_enum_CounterDescriptor
+using CounterDescriptor_Unit = perfetto_pbzero_enum_CounterDescriptor::Unit;
+
+
+constexpr CounterDescriptor_Unit CounterDescriptor_Unit_MIN = CounterDescriptor_Unit::UNIT_UNSPECIFIED;
+constexpr CounterDescriptor_Unit CounterDescriptor_Unit_MAX = CounterDescriptor_Unit::UNIT_SIZE_BYTES;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* CounterDescriptor_Unit_Name(::perfetto::protos::pbzero::CounterDescriptor_Unit value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::CounterDescriptor_Unit::UNIT_UNSPECIFIED:
+    return "UNIT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::CounterDescriptor_Unit::UNIT_TIME_NS:
+    return "UNIT_TIME_NS";
+
+  case ::perfetto::protos::pbzero::CounterDescriptor_Unit::UNIT_COUNT:
+    return "UNIT_COUNT";
+
+  case ::perfetto::protos::pbzero::CounterDescriptor_Unit::UNIT_SIZE_BYTES:
+    return "UNIT_SIZE_BYTES";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class CounterDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  CounterDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CounterDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CounterDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  int32_t type() const { return at<1>().as_int32(); }
+  bool has_categories() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> categories() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_unit() const { return at<3>().valid(); }
+  int32_t unit() const { return at<3>().as_int32(); }
+  bool has_unit_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars unit_name() const { return at<6>().as_string(); }
+  bool has_unit_multiplier() const { return at<4>().valid(); }
+  int64_t unit_multiplier() const { return at<4>().as_int64(); }
+  bool has_is_incremental() const { return at<5>().valid(); }
+  bool is_incremental() const { return at<5>().as_bool(); }
+};
+
+class CounterDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = CounterDescriptor_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kCategoriesFieldNumber = 2,
+    kUnitFieldNumber = 3,
+    kUnitNameFieldNumber = 6,
+    kUnitMultiplierFieldNumber = 4,
+    kIsIncrementalFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CounterDescriptor"; }
+
+
+  using BuiltinCounterType = ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType;
+  static inline const char* BuiltinCounterType_Name(BuiltinCounterType value) {
+    return ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType_Name(value);
+  }
+
+  using Unit = ::perfetto::protos::pbzero::CounterDescriptor_Unit;
+  static inline const char* Unit_Name(Unit value) {
+    return ::perfetto::protos::pbzero::CounterDescriptor_Unit_Name(value);
+  }
+  static inline const BuiltinCounterType COUNTER_UNSPECIFIED = BuiltinCounterType::COUNTER_UNSPECIFIED;
+  static inline const BuiltinCounterType COUNTER_THREAD_TIME_NS = BuiltinCounterType::COUNTER_THREAD_TIME_NS;
+  static inline const BuiltinCounterType COUNTER_THREAD_INSTRUCTION_COUNT = BuiltinCounterType::COUNTER_THREAD_INSTRUCTION_COUNT;
+  static inline const Unit UNIT_UNSPECIFIED = Unit::UNIT_UNSPECIFIED;
+  static inline const Unit UNIT_TIME_NS = Unit::UNIT_TIME_NS;
+  static inline const Unit UNIT_COUNT = Unit::UNIT_COUNT;
+  static inline const Unit UNIT_SIZE_BYTES = Unit::UNIT_SIZE_BYTES;
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(::perfetto::protos::pbzero::CounterDescriptor_BuiltinCounterType value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Categories =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_Categories kCategories{};
+  void add_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, data, size);
+  }
+  void add_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Categories::kFieldId, chars.data, chars.size);
+  }
+  void add_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Categories::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Unit =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::CounterDescriptor_Unit,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_Unit kUnit{};
+  void set_unit(::perfetto::protos::pbzero::CounterDescriptor_Unit value) {
+    static constexpr uint32_t field_id = FieldMetadata_Unit::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UnitName =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_UnitName kUnitName{};
+  void set_unit_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UnitName::kFieldId, data, size);
+  }
+  void set_unit_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_UnitName::kFieldId, chars.data, chars.size);
+  }
+  void set_unit_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnitName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UnitMultiplier =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_UnitMultiplier kUnitMultiplier{};
+  void set_unit_multiplier(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnitMultiplier::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsIncremental =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      CounterDescriptor>;
+
+  static constexpr FieldMetadata_IsIncremental kIsIncremental{};
+  void set_is_incremental(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsIncremental::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TrackDescriptor;
+class CounterDescriptor;
+class ChromeThreadDescriptor;
+class ThreadDescriptor;
+class ChromeProcessDescriptor;
+class ProcessDescriptor;
+enum CounterDescriptor_BuiltinCounterType : int;
+enum CounterDescriptor_Unit : int;
+enum ChromeThreadDescriptor_ThreadType : int;
+enum ThreadDescriptor_ChromeThreadType : int;
+enum ChromeProcessDescriptor_ProcessType : int;
+enum ProcessDescriptor_ChromeProcessType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TrackDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kUuidFieldNumber = 1,
+    kParentUuidFieldNumber = 5,
+    kNameFieldNumber = 2,
+    kProcessFieldNumber = 3,
+    kChromeProcessFieldNumber = 6,
+    kThreadFieldNumber = 4,
+    kChromeThreadFieldNumber = 7,
+    kCounterFieldNumber = 8,
+    kDisallowMergingWithSystemTracksFieldNumber = 9,
+  };
+
+  TrackDescriptor();
+  ~TrackDescriptor() override;
+  TrackDescriptor(TrackDescriptor&&) noexcept;
+  TrackDescriptor& operator=(TrackDescriptor&&);
+  TrackDescriptor(const TrackDescriptor&);
+  TrackDescriptor& operator=(const TrackDescriptor&);
+  bool operator==(const TrackDescriptor&) const;
+  bool operator!=(const TrackDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_uuid() const { return _has_field_[1]; }
+  uint64_t uuid() const { return uuid_; }
+  void set_uuid(uint64_t value) { uuid_ = value; _has_field_.set(1); }
+
+  bool has_parent_uuid() const { return _has_field_[5]; }
+  uint64_t parent_uuid() const { return parent_uuid_; }
+  void set_parent_uuid(uint64_t value) { parent_uuid_ = value; _has_field_.set(5); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+  bool has_process() const { return _has_field_[3]; }
+  const ProcessDescriptor& process() const { return *process_; }
+  ProcessDescriptor* mutable_process() { _has_field_.set(3); return process_.get(); }
+
+  bool has_chrome_process() const { return _has_field_[6]; }
+  const ChromeProcessDescriptor& chrome_process() const { return *chrome_process_; }
+  ChromeProcessDescriptor* mutable_chrome_process() { _has_field_.set(6); return chrome_process_.get(); }
+
+  bool has_thread() const { return _has_field_[4]; }
+  const ThreadDescriptor& thread() const { return *thread_; }
+  ThreadDescriptor* mutable_thread() { _has_field_.set(4); return thread_.get(); }
+
+  bool has_chrome_thread() const { return _has_field_[7]; }
+  const ChromeThreadDescriptor& chrome_thread() const { return *chrome_thread_; }
+  ChromeThreadDescriptor* mutable_chrome_thread() { _has_field_.set(7); return chrome_thread_.get(); }
+
+  bool has_counter() const { return _has_field_[8]; }
+  const CounterDescriptor& counter() const { return *counter_; }
+  CounterDescriptor* mutable_counter() { _has_field_.set(8); return counter_.get(); }
+
+  bool has_disallow_merging_with_system_tracks() const { return _has_field_[9]; }
+  bool disallow_merging_with_system_tracks() const { return disallow_merging_with_system_tracks_; }
+  void set_disallow_merging_with_system_tracks(bool value) { disallow_merging_with_system_tracks_ = value; _has_field_.set(9); }
+
+ private:
+  uint64_t uuid_{};
+  uint64_t parent_uuid_{};
+  std::string name_{};
+  ::protozero::CopyablePtr<ProcessDescriptor> process_;
+  ::protozero::CopyablePtr<ChromeProcessDescriptor> chrome_process_;
+  ::protozero::CopyablePtr<ThreadDescriptor> thread_;
+  ::protozero::CopyablePtr<ChromeThreadDescriptor> chrome_thread_;
+  ::protozero::CopyablePtr<CounterDescriptor> counter_;
+  bool disallow_merging_with_system_tracks_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<10> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeProcessDescriptor;
+class ChromeThreadDescriptor;
+class CounterDescriptor;
+class ProcessDescriptor;
+class ThreadDescriptor;
+
+class TrackDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrackDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_uuid() const { return at<1>().valid(); }
+  uint64_t uuid() const { return at<1>().as_uint64(); }
+  bool has_parent_uuid() const { return at<5>().valid(); }
+  uint64_t parent_uuid() const { return at<5>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_process() const { return at<3>().valid(); }
+  ::protozero::ConstBytes process() const { return at<3>().as_bytes(); }
+  bool has_chrome_process() const { return at<6>().valid(); }
+  ::protozero::ConstBytes chrome_process() const { return at<6>().as_bytes(); }
+  bool has_thread() const { return at<4>().valid(); }
+  ::protozero::ConstBytes thread() const { return at<4>().as_bytes(); }
+  bool has_chrome_thread() const { return at<7>().valid(); }
+  ::protozero::ConstBytes chrome_thread() const { return at<7>().as_bytes(); }
+  bool has_counter() const { return at<8>().valid(); }
+  ::protozero::ConstBytes counter() const { return at<8>().as_bytes(); }
+  bool has_disallow_merging_with_system_tracks() const { return at<9>().valid(); }
+  bool disallow_merging_with_system_tracks() const { return at<9>().as_bool(); }
+};
+
+class TrackDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = TrackDescriptor_Decoder;
+  enum : int32_t {
+    kUuidFieldNumber = 1,
+    kParentUuidFieldNumber = 5,
+    kNameFieldNumber = 2,
+    kProcessFieldNumber = 3,
+    kChromeProcessFieldNumber = 6,
+    kThreadFieldNumber = 4,
+    kChromeThreadFieldNumber = 7,
+    kCounterFieldNumber = 8,
+    kDisallowMergingWithSystemTracksFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackDescriptor"; }
+
+
+  using FieldMetadata_Uuid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_Uuid kUuid{};
+  void set_uuid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uuid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ParentUuid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_ParentUuid kParentUuid{};
+  void set_parent_uuid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParentUuid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Process =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessDescriptor,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_Process kProcess{};
+  template <typename T = ProcessDescriptor> T* set_process() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ChromeProcess =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeProcessDescriptor,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_ChromeProcess kChromeProcess{};
+  template <typename T = ChromeProcessDescriptor> T* set_chrome_process() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_Thread =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ThreadDescriptor,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_Thread kThread{};
+  template <typename T = ThreadDescriptor> T* set_thread() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_ChromeThread =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeThreadDescriptor,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_ChromeThread kChromeThread{};
+  template <typename T = ChromeThreadDescriptor> T* set_chrome_thread() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_Counter =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CounterDescriptor,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_Counter kCounter{};
+  template <typename T = CounterDescriptor> T* set_counter() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_DisallowMergingWithSystemTracks =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackDescriptor>;
+
+  static constexpr FieldMetadata_DisallowMergingWithSystemTracks kDisallowMergingWithSystemTracks{};
+  void set_disallow_merging_with_system_tracks(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisallowMergingWithSystemTracks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
+// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/compile_time_hash.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+
+#include <stdint.h>
+#include <map>
+#include <mutex>
+
+namespace perfetto {
+namespace internal {
+class TrackRegistry;
+}
+class Flow;
+class TerminatingFlow;
+
+// Track events are recorded on a timeline track, which maintains the relative
+// time ordering of all events on that track. Each thread has its own default
+// track (ThreadTrack), which is by default where all track events are written.
+// Thread tracks are grouped under their hosting process (ProcessTrack).
+
+// Events which aren't strictly scoped to a thread or a process, or don't
+// correspond to synchronous code execution on a thread can use a custom
+// track (Track, ThreadTrack or ProcessTrack). A Track object can also
+// optionally be parented to a thread or a process.
+//
+// A track is represented by a uuid, which must be unique across the entire
+// recorded trace.
+//
+// For example, to record an event that begins and ends on different threads,
+// use a matching id to tie the begin and end events together:
+//
+//   TRACE_EVENT_BEGIN("category", "AsyncEvent", perfetto::Track(8086));
+//   ...
+//   TRACE_EVENT_END("category", perfetto::Track(8086));
+//
+// Tracks can also be annotated with metadata:
+//
+//   auto desc = track.Serialize();
+//   desc.set_name("MyTrack");
+//   perfetto::TrackEvent::SetTrackDescriptor(track, desc);
+//
+// Threads and processes can also be named in a similar way, e.g.:
+//
+//   auto desc = perfetto::ProcessTrack::Current().Serialize();
+//   desc.mutable_process()->set_process_name("MyProcess");
+//   perfetto::TrackEvent::SetTrackDescriptor(
+//       perfetto::ProcessTrack::Current(), desc);
+//
+// The metadata remains valid between tracing sessions. To free up data for a
+// track, call EraseTrackDescriptor:
+//
+//   perfetto::TrackEvent::EraseTrackDescriptor(track);
+//
+struct PERFETTO_EXPORT_COMPONENT Track {
+  const uint64_t uuid;
+  const uint64_t parent_uuid;
+  constexpr Track() : uuid(0), parent_uuid(0) {}
+
+  // Construct a track with identifier |id|, optionally parented under |parent|.
+  // If no parent is specified, the track's parent is the current process's
+  // track.
+  //
+  // To minimize the chances for accidental id collisions across processes, the
+  // track's effective uuid is generated by xorring |id| with a random,
+  // per-process cookie.
+  explicit constexpr Track(uint64_t id, Track parent = MakeProcessTrack())
+      : uuid(id ^ parent.uuid), parent_uuid(parent.uuid) {}
+
+  explicit operator bool() const { return uuid; }
+  void Serialize(protos::pbzero::TrackDescriptor*) const;
+  protos::gen::TrackDescriptor Serialize() const;
+
+  // Construct a global track with identifier |id|.
+  //
+  // Beware: the globally unique |id| should be chosen carefully to avoid
+  // accidental clashes with track identifiers emitted by other producers.
+  static Track Global(uint64_t id) { return Track(id, Track()); }
+
+  // Construct a track using |ptr| as identifier.
+  static Track FromPointer(const void* ptr, Track parent = MakeProcessTrack()) {
+    // Using pointers as global TrackIds isn't supported as pointers are
+    // per-proccess and the same pointer value can be used in different
+    // processes. If you hit this check but are providing no |parent| track,
+    // verify that Tracing::Initialize() was called for the current process.
+    PERFETTO_DCHECK(parent.uuid != Track().uuid);
+
+    return Track(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(ptr)),
+                 parent);
+  }
+
+  // Construct a track using |ptr| as identifier within thread-scope.
+  // Shorthand for `Track::FromPointer(ptr, ThreadTrack::Current())`
+  // Usage: TRACE_EVENT_BEGIN("...", "...", perfetto::Track::ThreadScoped(this))
+  static Track ThreadScoped(
+      const void* ptr,
+      Track parent = MakeThreadTrack(base::GetThreadId())) {
+    return Track::FromPointer(ptr, parent);
+  }
+
+ protected:
+  constexpr Track(uint64_t uuid_, uint64_t parent_uuid_)
+      : uuid(uuid_), parent_uuid(parent_uuid_) {}
+
+  static Track MakeThreadTrack(base::PlatformThreadId tid) {
+    // If tid were 0 here (which is an invalid tid), we would create a thread
+    // track with a uuid that conflicts with the corresponding ProcessTrack.
+    PERFETTO_DCHECK(tid != 0);
+    return Track(static_cast<uint64_t>(tid), MakeProcessTrack());
+  }
+
+  static Track MakeProcessTrack() { return Track(process_uuid, Track()); }
+
+  static constexpr inline uint64_t CompileTimeHash(const char* string) {
+    return internal::CompileTimeHash()
+        .Update(string, static_cast<size_t>(base::StrEnd(string) - string))
+        .digest();
+  }
+
+ private:
+  friend class internal::TrackRegistry;
+  friend class Flow;
+  friend class TerminatingFlow;
+  static uint64_t process_uuid;
+};
+
+// A process track represents events that describe the state of the entire
+// application (e.g., counter events). Currently a ProcessTrack can only
+// represent the current process.
+struct PERFETTO_EXPORT_COMPONENT ProcessTrack : public Track {
+  const base::PlatformProcessId pid;
+
+  static ProcessTrack Current() { return ProcessTrack(); }
+
+  void Serialize(protos::pbzero::TrackDescriptor*) const;
+  protos::gen::TrackDescriptor Serialize() const;
+
+ private:
+  ProcessTrack()
+      : Track(MakeProcessTrack()), pid(Platform::GetCurrentProcessId()) {}
+};
+
+// A thread track is associated with a specific thread of execution. Currently
+// only threads in the current process can be referenced.
+struct PERFETTO_EXPORT_COMPONENT ThreadTrack : public Track {
+  const base::PlatformProcessId pid;
+  const base::PlatformThreadId tid;
+  bool disallow_merging_with_system_tracks = false;
+
+  static ThreadTrack Current();
+
+  // Represents a thread in the current process.
+  static ThreadTrack ForThread(base::PlatformThreadId tid_);
+
+  void Serialize(protos::pbzero::TrackDescriptor*) const;
+  protos::gen::TrackDescriptor Serialize() const;
+
+ private:
+  explicit ThreadTrack(base::PlatformThreadId tid_,
+                       bool disallow_merging_with_system_tracks_)
+      : Track(MakeThreadTrack(tid_)),
+        pid(ProcessTrack::Current().pid),
+        tid(tid_),
+        disallow_merging_with_system_tracks(
+            disallow_merging_with_system_tracks_) {}
+};
+
+// A track for recording counter values with the TRACE_COUNTER macro. Counter
+// tracks can optionally be given units and other metadata. See
+// /protos/perfetto/trace/track_event/counter_descriptor.proto for details.
+class PERFETTO_EXPORT_COMPONENT CounterTrack : public Track {
+  // A random value mixed into counter track uuids to avoid collisions with
+  // other types of tracks.
+  static constexpr uint64_t kCounterMagic = 0xb1a4a67d7970839eul;
+
+ public:
+  using Unit = perfetto::protos::pbzero::CounterDescriptor::Unit;
+  using CounterType =
+      perfetto::protos::gen::CounterDescriptor::BuiltinCounterType;
+
+  // |name| must be a string with static lifetime.
+  constexpr explicit CounterTrack(const char* name,
+                                  Track parent = MakeProcessTrack())
+      : Track(CompileTimeHash(name) ^ kCounterMagic, parent),
+        name_(name),
+        category_(nullptr) {}
+
+  // |unit_name| is a free-form description of the unit used by this counter. It
+  // must have static lifetime.
+  constexpr CounterTrack(const char* name,
+                         const char* unit_name,
+                         Track parent = MakeProcessTrack())
+      : Track(CompileTimeHash(name) ^ kCounterMagic, parent),
+        name_(name),
+        category_(nullptr),
+        unit_name_(unit_name) {}
+
+  constexpr CounterTrack(const char* name,
+                         Unit unit,
+                         Track parent = MakeProcessTrack())
+      : Track(CompileTimeHash(name) ^ kCounterMagic, parent),
+        name_(name),
+        category_(nullptr),
+        unit_(unit) {}
+
+  static constexpr CounterTrack Global(const char* name,
+                                       const char* unit_name) {
+    return CounterTrack(name, unit_name, Track());
+  }
+
+  static constexpr CounterTrack Global(const char* name, Unit unit) {
+    return CounterTrack(name, unit, Track());
+  }
+
+  static constexpr CounterTrack Global(const char* name) {
+    return Global(name, nullptr);
+  }
+
+  constexpr CounterTrack set_unit(Unit unit) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit, unit_name_,
+                        unit_multiplier_, is_incremental_, type_);
+  }
+
+  constexpr CounterTrack set_type(CounterType type) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
+                        unit_multiplier_, is_incremental_, type);
+  }
+
+  constexpr CounterTrack set_unit_name(const char* unit_name) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name,
+                        unit_multiplier_, is_incremental_, type_);
+  }
+
+  constexpr CounterTrack set_unit_multiplier(int64_t unit_multiplier) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
+                        unit_multiplier, is_incremental_, type_);
+  }
+
+  constexpr CounterTrack set_category(const char* category) const {
+    return CounterTrack(uuid, parent_uuid, name_, category, unit_, unit_name_,
+                        unit_multiplier_, is_incremental_, type_);
+  }
+
+  constexpr CounterTrack set_is_incremental(bool is_incremental = true) const {
+    return CounterTrack(uuid, parent_uuid, name_, category_, unit_, unit_name_,
+                        unit_multiplier_, is_incremental, type_);
+  }
+
+  constexpr bool is_incremental() const { return is_incremental_; }
+
+  void Serialize(protos::pbzero::TrackDescriptor*) const;
+  protos::gen::TrackDescriptor Serialize() const;
+
+ private:
+  constexpr CounterTrack(uint64_t uuid_,
+                         uint64_t parent_uuid_,
+                         const char* name,
+                         const char* category,
+                         Unit unit,
+                         const char* unit_name,
+                         int64_t unit_multiplier,
+                         bool is_incremental,
+                         CounterType type)
+      : Track(uuid_, parent_uuid_),
+        name_(name),
+        category_(category),
+        unit_(unit),
+        unit_name_(unit_name),
+        unit_multiplier_(unit_multiplier),
+        is_incremental_(is_incremental),
+        type_(type) {}
+
+  const char* const name_;
+  const char* const category_;
+  Unit unit_ = perfetto::protos::pbzero::CounterDescriptor::UNIT_UNSPECIFIED;
+  const char* const unit_name_ = nullptr;
+  int64_t unit_multiplier_ = 1;
+  const bool is_incremental_ = false;
+  CounterType type_ =
+      perfetto::protos::gen::CounterDescriptor::COUNTER_UNSPECIFIED;
+};
+
+namespace internal {
+
+// Keeps a map of uuids to serialized track descriptors and provides a
+// thread-safe way to read and write them. Each trace writer keeps a TLS set of
+// the tracks it has seen (see TrackEventIncrementalState). In the common case,
+// this registry is not consulted (and no locks are taken). However when a new
+// track is seen, this registry is used to write either 1) the default
+// descriptor for that track (see *Track::Serialize) or 2) a serialized
+// descriptor stored in the registry which may have additional metadata (e.g.,
+// track name).
+// TODO(eseckler): Remove PERFETTO_EXPORT_COMPONENT once Chromium no longer
+// calls TrackRegistry::InitializeInstance() directly.
+class PERFETTO_EXPORT_COMPONENT TrackRegistry {
+ public:
+  using SerializedTrackDescriptor = std::string;
+
+  TrackRegistry();
+  ~TrackRegistry();
+
+  static void InitializeInstance();
+  static void ResetForTesting();
+  static uint64_t ComputeProcessUuid();
+  static TrackRegistry* Get() { return instance_; }
+
+  void EraseTrack(Track);
+
+  // Store metadata for |track| in the registry. |fill_function| is called
+  // synchronously to record additional properties for the track.
+  template <typename TrackType>
+  void UpdateTrack(
+      const TrackType& track,
+      std::function<void(protos::pbzero::TrackDescriptor*)> fill_function) {
+    UpdateTrackImpl(track, [&](protos::pbzero::TrackDescriptor* desc) {
+      track.Serialize(desc);
+      fill_function(desc);
+    });
+  }
+
+  // This variant lets the user supply a serialized track descriptor directly.
+  void UpdateTrack(Track, const std::string& serialized_desc);
+
+  // If |track| exists in the registry, write out the serialized track
+  // descriptor for it into |packet|. Otherwise just the ephemeral track object
+  // is serialized without any additional metadata.
+  template <typename TrackType>
+  void SerializeTrack(
+      const TrackType& track,
+      protozero::MessageHandle<protos::pbzero::TracePacket> packet) {
+    // If the track has extra metadata (recorded with UpdateTrack), it will be
+    // found in the registry. To minimize the time the lock is held, make a copy
+    // of the data held in the registry and write it outside the lock.
+    std::string desc_copy;
+    {
+      std::lock_guard<std::mutex> lock(mutex_);
+      const auto& it = tracks_.find(track.uuid);
+      if (it != tracks_.end()) {
+        desc_copy = it->second;
+        PERFETTO_DCHECK(!desc_copy.empty());
+      }
+    }
+    if (!desc_copy.empty()) {
+      WriteTrackDescriptor(std::move(desc_copy), std::move(packet));
+    } else {
+      // Otherwise we just write the basic descriptor for this type of track
+      // (e.g., just uuid, no name).
+      track.Serialize(packet->set_track_descriptor());
+    }
+  }
+
+  static void WriteTrackDescriptor(
+      const SerializedTrackDescriptor& desc,
+      protozero::MessageHandle<protos::pbzero::TracePacket> packet);
+
+ private:
+  void UpdateTrackImpl(
+      Track,
+      std::function<void(protos::pbzero::TrackDescriptor*)> fill_function);
+
+  std::mutex mutex_;
+  std::map<uint64_t /* uuid */, SerializedTrackDescriptor> tracks_;
+
+  static TrackRegistry* instance_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/builtin_clock.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+enum BuiltinClock : int32_t {
+  BUILTIN_CLOCK_UNKNOWN = 0,
+  BUILTIN_CLOCK_REALTIME = 1,
+  BUILTIN_CLOCK_REALTIME_COARSE = 2,
+  BUILTIN_CLOCK_MONOTONIC = 3,
+  BUILTIN_CLOCK_MONOTONIC_COARSE = 4,
+  BUILTIN_CLOCK_MONOTONIC_RAW = 5,
+  BUILTIN_CLOCK_BOOTTIME = 6,
+  BUILTIN_CLOCK_MAX_ID = 63,
+};
+
+constexpr BuiltinClock BuiltinClock_MIN = BuiltinClock::BUILTIN_CLOCK_UNKNOWN;
+constexpr BuiltinClock BuiltinClock_MAX = BuiltinClock::BUILTIN_CLOCK_MAX_ID;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* BuiltinClock_Name(::perfetto::protos::pbzero::BuiltinClock value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_UNKNOWN:
+    return "BUILTIN_CLOCK_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_REALTIME:
+    return "BUILTIN_CLOCK_REALTIME";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_REALTIME_COARSE:
+    return "BUILTIN_CLOCK_REALTIME_COARSE";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MONOTONIC:
+    return "BUILTIN_CLOCK_MONOTONIC";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MONOTONIC_COARSE:
+    return "BUILTIN_CLOCK_MONOTONIC_COARSE";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MONOTONIC_RAW:
+    return "BUILTIN_CLOCK_MONOTONIC_RAW";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_BOOTTIME:
+    return "BUILTIN_CLOCK_BOOTTIME";
+
+  case ::perfetto::protos::pbzero::BuiltinClock::BUILTIN_CLOCK_MAX_ID:
+    return "BUILTIN_CLOCK_MAX_ID";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/interned_data/interned_data.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_INTERNED_DATA_INTERNED_DATA_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_INTERNED_DATA_INTERNED_DATA_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class Callstack;
+class DebugAnnotationName;
+class DebugAnnotationValueTypeName;
+class EventCategory;
+class EventName;
+class Frame;
+class HistogramName;
+class InternedGpuRenderStageSpecification;
+class InternedGraphicsContext;
+class InternedString;
+class LogMessageBody;
+class Mapping;
+class NetworkPacketContext;
+class ProfiledFrameSymbols;
+class SourceLocation;
+class UnsymbolizedSourceLocation;
+
+class InternedData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/30, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  InternedData_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedData_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedData_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_categories() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> event_categories() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_event_names() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> event_names() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_debug_annotation_names() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotation_names() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_debug_annotation_value_type_names() const { return at<27>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotation_value_type_names() const { return GetRepeated<::protozero::ConstBytes>(27); }
+  bool has_source_locations() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> source_locations() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_unsymbolized_source_locations() const { return at<28>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> unsymbolized_source_locations() const { return GetRepeated<::protozero::ConstBytes>(28); }
+  bool has_log_message_body() const { return at<20>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> log_message_body() const { return GetRepeated<::protozero::ConstBytes>(20); }
+  bool has_histogram_names() const { return at<25>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> histogram_names() const { return GetRepeated<::protozero::ConstBytes>(25); }
+  bool has_build_ids() const { return at<16>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> build_ids() const { return GetRepeated<::protozero::ConstBytes>(16); }
+  bool has_mapping_paths() const { return at<17>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mapping_paths() const { return GetRepeated<::protozero::ConstBytes>(17); }
+  bool has_source_paths() const { return at<18>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> source_paths() const { return GetRepeated<::protozero::ConstBytes>(18); }
+  bool has_function_names() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> function_names() const { return GetRepeated<::protozero::ConstBytes>(5); }
+  bool has_profiled_frame_symbols() const { return at<21>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> profiled_frame_symbols() const { return GetRepeated<::protozero::ConstBytes>(21); }
+  bool has_mappings() const { return at<19>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mappings() const { return GetRepeated<::protozero::ConstBytes>(19); }
+  bool has_frames() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> frames() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_callstacks() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> callstacks() const { return GetRepeated<::protozero::ConstBytes>(7); }
+  bool has_vulkan_memory_keys() const { return at<22>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> vulkan_memory_keys() const { return GetRepeated<::protozero::ConstBytes>(22); }
+  bool has_graphics_contexts() const { return at<23>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> graphics_contexts() const { return GetRepeated<::protozero::ConstBytes>(23); }
+  bool has_gpu_specifications() const { return at<24>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> gpu_specifications() const { return GetRepeated<::protozero::ConstBytes>(24); }
+  bool has_kernel_symbols() const { return at<26>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> kernel_symbols() const { return GetRepeated<::protozero::ConstBytes>(26); }
+  bool has_debug_annotation_string_values() const { return at<29>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotation_string_values() const { return GetRepeated<::protozero::ConstBytes>(29); }
+  bool has_packet_context() const { return at<30>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> packet_context() const { return GetRepeated<::protozero::ConstBytes>(30); }
+};
+
+class InternedData : public ::protozero::Message {
+ public:
+  using Decoder = InternedData_Decoder;
+  enum : int32_t {
+    kEventCategoriesFieldNumber = 1,
+    kEventNamesFieldNumber = 2,
+    kDebugAnnotationNamesFieldNumber = 3,
+    kDebugAnnotationValueTypeNamesFieldNumber = 27,
+    kSourceLocationsFieldNumber = 4,
+    kUnsymbolizedSourceLocationsFieldNumber = 28,
+    kLogMessageBodyFieldNumber = 20,
+    kHistogramNamesFieldNumber = 25,
+    kBuildIdsFieldNumber = 16,
+    kMappingPathsFieldNumber = 17,
+    kSourcePathsFieldNumber = 18,
+    kFunctionNamesFieldNumber = 5,
+    kProfiledFrameSymbolsFieldNumber = 21,
+    kMappingsFieldNumber = 19,
+    kFramesFieldNumber = 6,
+    kCallstacksFieldNumber = 7,
+    kVulkanMemoryKeysFieldNumber = 22,
+    kGraphicsContextsFieldNumber = 23,
+    kGpuSpecificationsFieldNumber = 24,
+    kKernelSymbolsFieldNumber = 26,
+    kDebugAnnotationStringValuesFieldNumber = 29,
+    kPacketContextFieldNumber = 30,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedData"; }
+
+
+  using FieldMetadata_EventCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EventCategory,
+      InternedData>;
+
+  static constexpr FieldMetadata_EventCategories kEventCategories{};
+  template <typename T = EventCategory> T* add_event_categories() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_EventNames =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EventName,
+      InternedData>;
+
+  static constexpr FieldMetadata_EventNames kEventNames{};
+  template <typename T = EventName> T* add_event_names() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_DebugAnnotationNames =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotationName,
+      InternedData>;
+
+  static constexpr FieldMetadata_DebugAnnotationNames kDebugAnnotationNames{};
+  template <typename T = DebugAnnotationName> T* add_debug_annotation_names() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_DebugAnnotationValueTypeNames =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotationValueTypeName,
+      InternedData>;
+
+  static constexpr FieldMetadata_DebugAnnotationValueTypeNames kDebugAnnotationValueTypeNames{};
+  template <typename T = DebugAnnotationValueTypeName> T* add_debug_annotation_value_type_names() {
+    return BeginNestedMessage<T>(27);
+  }
+
+
+  using FieldMetadata_SourceLocations =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SourceLocation,
+      InternedData>;
+
+  static constexpr FieldMetadata_SourceLocations kSourceLocations{};
+  template <typename T = SourceLocation> T* add_source_locations() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_UnsymbolizedSourceLocations =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UnsymbolizedSourceLocation,
+      InternedData>;
+
+  static constexpr FieldMetadata_UnsymbolizedSourceLocations kUnsymbolizedSourceLocations{};
+  template <typename T = UnsymbolizedSourceLocation> T* add_unsymbolized_source_locations() {
+    return BeginNestedMessage<T>(28);
+  }
+
+
+  using FieldMetadata_LogMessageBody =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LogMessageBody,
+      InternedData>;
+
+  static constexpr FieldMetadata_LogMessageBody kLogMessageBody{};
+  template <typename T = LogMessageBody> T* add_log_message_body() {
+    return BeginNestedMessage<T>(20);
+  }
+
+
+  using FieldMetadata_HistogramNames =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HistogramName,
+      InternedData>;
+
+  static constexpr FieldMetadata_HistogramNames kHistogramNames{};
+  template <typename T = HistogramName> T* add_histogram_names() {
+    return BeginNestedMessage<T>(25);
+  }
+
+
+  using FieldMetadata_BuildIds =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_BuildIds kBuildIds{};
+  template <typename T = InternedString> T* add_build_ids() {
+    return BeginNestedMessage<T>(16);
+  }
+
+
+  using FieldMetadata_MappingPaths =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_MappingPaths kMappingPaths{};
+  template <typename T = InternedString> T* add_mapping_paths() {
+    return BeginNestedMessage<T>(17);
+  }
+
+
+  using FieldMetadata_SourcePaths =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_SourcePaths kSourcePaths{};
+  template <typename T = InternedString> T* add_source_paths() {
+    return BeginNestedMessage<T>(18);
+  }
+
+
+  using FieldMetadata_FunctionNames =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_FunctionNames kFunctionNames{};
+  template <typename T = InternedString> T* add_function_names() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_ProfiledFrameSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfiledFrameSymbols,
+      InternedData>;
+
+  static constexpr FieldMetadata_ProfiledFrameSymbols kProfiledFrameSymbols{};
+  template <typename T = ProfiledFrameSymbols> T* add_profiled_frame_symbols() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_Mappings =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Mapping,
+      InternedData>;
+
+  static constexpr FieldMetadata_Mappings kMappings{};
+  template <typename T = Mapping> T* add_mappings() {
+    return BeginNestedMessage<T>(19);
+  }
+
+
+  using FieldMetadata_Frames =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Frame,
+      InternedData>;
+
+  static constexpr FieldMetadata_Frames kFrames{};
+  template <typename T = Frame> T* add_frames() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_Callstacks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Callstack,
+      InternedData>;
+
+  static constexpr FieldMetadata_Callstacks kCallstacks{};
+  template <typename T = Callstack> T* add_callstacks() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_VulkanMemoryKeys =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_VulkanMemoryKeys kVulkanMemoryKeys{};
+  template <typename T = InternedString> T* add_vulkan_memory_keys() {
+    return BeginNestedMessage<T>(22);
+  }
+
+
+  using FieldMetadata_GraphicsContexts =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedGraphicsContext,
+      InternedData>;
+
+  static constexpr FieldMetadata_GraphicsContexts kGraphicsContexts{};
+  template <typename T = InternedGraphicsContext> T* add_graphics_contexts() {
+    return BeginNestedMessage<T>(23);
+  }
+
+
+  using FieldMetadata_GpuSpecifications =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedGpuRenderStageSpecification,
+      InternedData>;
+
+  static constexpr FieldMetadata_GpuSpecifications kGpuSpecifications{};
+  template <typename T = InternedGpuRenderStageSpecification> T* add_gpu_specifications() {
+    return BeginNestedMessage<T>(24);
+  }
+
+
+  using FieldMetadata_KernelSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_KernelSymbols kKernelSymbols{};
+  template <typename T = InternedString> T* add_kernel_symbols() {
+    return BeginNestedMessage<T>(26);
+  }
+
+
+  using FieldMetadata_DebugAnnotationStringValues =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      InternedData>;
+
+  static constexpr FieldMetadata_DebugAnnotationStringValues kDebugAnnotationStringValues{};
+  template <typename T = InternedString> T* add_debug_annotation_string_values() {
+    return BeginNestedMessage<T>(29);
+  }
+
+
+  using FieldMetadata_PacketContext =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketContext,
+      InternedData>;
+
+  static constexpr FieldMetadata_PacketContext kPacketContext{};
+  template <typename T = NetworkPacketContext> T* add_packet_context() {
+    return BeginNestedMessage<T>(30);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNAL_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNAL_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/flat_set.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#include <unordered_map>
+
+namespace perfetto {
+
+// Represents a point in time for the clock specified by |clock_id|.
+struct TraceTimestamp {
+  // Clock IDs have the following semantic:
+  // [1, 63]:    Builtin types, see BuiltinClock from
+  //             ../common/builtin_clock.proto.
+  // [64, 127]:  User-defined clocks. These clocks are sequence-scoped. They
+  //             are only valid within the same |trusted_packet_sequence_id|
+  //             (i.e. only for TracePacket(s) emitted by the same TraceWriter
+  //             that emitted the clock snapshot).
+  // [128, MAX]: Reserved for future use. The idea is to allow global clock
+  //             IDs and setting this ID to hash(full_clock_name) & ~127.
+  // Learn more: `clock_snapshot.proto`
+  uint32_t clock_id;
+  uint64_t value;
+};
+
+class EventContext;
+class TrackEventSessionObserver;
+struct Category;
+struct TraceTimestamp;
+namespace protos {
+namespace gen {
+class TrackEventConfig;
+}  // namespace gen
+namespace pbzero {
+class DebugAnnotation;
+}  // namespace pbzero
+}  // namespace protos
+
+// A callback interface for observing track event tracing sessions starting and
+// stopping. See TrackEvent::{Add,Remove}SessionObserver. Note that all methods
+// will be called on an internal Perfetto thread.
+class PERFETTO_EXPORT_COMPONENT TrackEventSessionObserver {
+ public:
+  virtual ~TrackEventSessionObserver();
+  // Called when a track event tracing session is configured. Note tracing isn't
+  // active yet, so track events emitted here won't be recorded. See
+  // DataSourceBase::OnSetup.
+  virtual void OnSetup(const DataSourceBase::SetupArgs&);
+  // Called when a track event tracing session is started. It is possible to
+  // emit track events from this callback.
+  virtual void OnStart(const DataSourceBase::StartArgs&);
+  // Called when a track event tracing session is stopped. It is still possible
+  // to emit track events from this callback.
+  virtual void OnStop(const DataSourceBase::StopArgs&);
+  // Called when tracing muxer requests to clear incremental state.
+  virtual void WillClearIncrementalState(
+      const DataSourceBase::ClearIncrementalStateArgs&);
+};
+
+// A class that the embedder can store arbitrary data user data per thread.
+class PERFETTO_EXPORT_COMPONENT TrackEventTlsStateUserData {
+ public:
+  TrackEventTlsStateUserData() = default;
+  // Not clonable.
+  TrackEventTlsStateUserData(const TrackEventTlsStateUserData&) = delete;
+  TrackEventTlsStateUserData& operator=(const TrackEventTlsStateUserData&) =
+      delete;
+
+  virtual ~TrackEventTlsStateUserData();
+};
+
+namespace internal {
+class TrackEventCategoryRegistry;
+
+class PERFETTO_EXPORT_COMPONENT BaseTrackEventInternedDataIndex {
+ public:
+  virtual ~BaseTrackEventInternedDataIndex();
+
+#if PERFETTO_DCHECK_IS_ON()
+  const char* type_id_ = nullptr;
+  const void* add_function_ptr_ = nullptr;
+#endif  // PERFETTO_DCHECK_IS_ON()
+};
+
+struct TrackEventTlsState {
+  template <typename TraceContext>
+  explicit TrackEventTlsState(const TraceContext& trace_context);
+  bool enable_thread_time_sampling = false;
+  bool filter_debug_annotations = false;
+  bool filter_dynamic_event_names = false;
+  uint64_t timestamp_unit_multiplier = 1;
+  uint32_t default_clock;
+  std::map<const void*, std::unique_ptr<TrackEventTlsStateUserData>> user_data;
+};
+
+struct TrackEventIncrementalState {
+  static constexpr size_t kMaxInternedDataFields = 32;
+
+  // Packet-sequence-scoped clock that encodes nanosecond timestamps in the
+  // domain of the clock returned by GetClockId() as delta values - see
+  // Clock::is_incremental in perfetto/trace/clock_snapshot.proto.
+  // Default unit: nanoseconds.
+  static constexpr uint32_t kClockIdIncremental = 64;
+
+  // Packet-sequence-scoped clock that encodes timestamps in the domain of the
+  // clock returned by GetClockId() with custom unit_multiplier.
+  // Default unit: nanoseconds.
+  static constexpr uint32_t kClockIdAbsolute = 65;
+
+  bool was_cleared = true;
+
+  // A heap-allocated message for storing newly seen interned data while we are
+  // in the middle of writing a track event. When a track event wants to write
+  // new interned data into the trace, it is first serialized into this message
+  // and then flushed to the real trace in EventContext when the packet ends.
+  // The message is cached here as a part of incremental state so that we can
+  // reuse the underlying buffer allocation for subsequently written interned
+  // data.
+  protozero::HeapBuffered<protos::pbzero::InternedData>
+      serialized_interned_data;
+
+  // In-memory indices for looking up interned data ids.
+  // For each intern-able field (up to a max of 32) we keep a dictionary of
+  // field-value -> interning-key. Depending on the type we either keep the full
+  // value or a hash of it (See track_event_interned_data_index.h)
+  using InternedDataIndex =
+      std::pair</* interned_data.proto field number */ size_t,
+                std::unique_ptr<BaseTrackEventInternedDataIndex>>;
+  std::array<InternedDataIndex, kMaxInternedDataFields> interned_data_indices =
+      {};
+
+  // Track uuids for which we have written descriptors into the trace. If a
+  // trace event uses a track which is not in this set, we'll write out a
+  // descriptor for it.
+  base::FlatSet<uint64_t> seen_tracks;
+
+  // Dynamically registered category names that have been encountered during
+  // this tracing session. The value in the map indicates whether the category
+  // is enabled or disabled.
+  std::unordered_map<std::string, bool> dynamic_categories;
+
+  // The latest reference timestamp that was used in a TracePacket or in a
+  // ClockSnapshot. The increment between this timestamp and the current trace
+  // time (GetTimeNs) is a value in kClockIdIncremental's domain.
+  uint64_t last_timestamp_ns = 0;
+
+  // The latest known counter values that was used in a TracePacket for each
+  // counter track. The key (uint64_t) is the uuid of counter track.
+  // The value is used for delta encoding of counter values.
+  std::unordered_map<uint64_t, int64_t> last_counter_value_per_track;
+  int64_t last_thread_time_ns = 0;
+};
+
+// The backend portion of the track event trace point implemention. Outlined to
+// a separate .cc file so it can be shared by different track event category
+// namespaces.
+class PERFETTO_EXPORT_COMPONENT TrackEventInternal {
+ public:
+  static bool Initialize(
+      const TrackEventCategoryRegistry&,
+      bool (*register_data_source)(const DataSourceDescriptor&));
+
+  static bool AddSessionObserver(const TrackEventCategoryRegistry&,
+                                 TrackEventSessionObserver*);
+  static void RemoveSessionObserver(const TrackEventCategoryRegistry&,
+                                    TrackEventSessionObserver*);
+
+  static void EnableTracing(const TrackEventCategoryRegistry& registry,
+                            const protos::gen::TrackEventConfig& config,
+                            const DataSourceBase::SetupArgs&);
+  static void OnStart(const TrackEventCategoryRegistry&,
+                      const DataSourceBase::StartArgs&);
+  static void OnStop(const TrackEventCategoryRegistry&,
+                     const DataSourceBase::StopArgs&);
+  static void DisableTracing(const TrackEventCategoryRegistry& registry,
+                             uint32_t internal_instance_index);
+  static void WillClearIncrementalState(
+      const TrackEventCategoryRegistry&,
+      const DataSourceBase::ClearIncrementalStateArgs&);
+
+  static bool IsCategoryEnabled(const TrackEventCategoryRegistry& registry,
+                                const protos::gen::TrackEventConfig& config,
+                                const Category& category);
+
+  static void WriteEventName(perfetto::DynamicString event_name,
+                             perfetto::EventContext& event_ctx,
+                             const TrackEventTlsState&);
+
+  static void WriteEventName(perfetto::StaticString event_name,
+                             perfetto::EventContext& event_ctx,
+                             const TrackEventTlsState&);
+
+  static perfetto::EventContext WriteEvent(
+      TraceWriterBase*,
+      TrackEventIncrementalState*,
+      TrackEventTlsState& tls_state,
+      const Category* category,
+      perfetto::protos::pbzero::TrackEvent::Type,
+      const TraceTimestamp& timestamp,
+      bool on_current_thread_track);
+
+  static void ResetIncrementalStateIfRequired(
+      TraceWriterBase* trace_writer,
+      TrackEventIncrementalState* incr_state,
+      const TrackEventTlsState& tls_state,
+      const TraceTimestamp& timestamp) {
+    if (incr_state->was_cleared) {
+      incr_state->was_cleared = false;
+      ResetIncrementalState(trace_writer, incr_state, tls_state, timestamp);
+    }
+  }
+
+  // TODO(altimin): Remove this method once Chrome uses
+  // EventContext::AddDebugAnnotation directly.
+  template <typename NameType, typename ValueType>
+  static void AddDebugAnnotation(perfetto::EventContext* event_ctx,
+                                 NameType&& name,
+                                 ValueType&& value) {
+    auto annotation =
+        AddDebugAnnotation(event_ctx, std::forward<NameType>(name));
+    WriteIntoTracedValue(
+        internal::CreateTracedValueFromProto(annotation, event_ctx),
+        std::forward<ValueType>(value));
+  }
+
+  // If the given track hasn't been seen by the trace writer yet, write a
+  // descriptor for it into the trace. Doesn't take a lock unless the track
+  // descriptor is new.
+  template <typename TrackType>
+  static void WriteTrackDescriptorIfNeeded(
+      const TrackType& track,
+      TraceWriterBase* trace_writer,
+      TrackEventIncrementalState* incr_state,
+      const TrackEventTlsState& tls_state,
+      const TraceTimestamp& timestamp) {
+    auto it_and_inserted = incr_state->seen_tracks.insert(track.uuid);
+    if (PERFETTO_LIKELY(!it_and_inserted.second))
+      return;
+    WriteTrackDescriptor(track, trace_writer, incr_state, tls_state, timestamp);
+  }
+
+  // Unconditionally write a track descriptor into the trace.
+  template <typename TrackType>
+  static void WriteTrackDescriptor(const TrackType& track,
+                                   TraceWriterBase* trace_writer,
+                                   TrackEventIncrementalState* incr_state,
+                                   const TrackEventTlsState& tls_state,
+                                   const TraceTimestamp& timestamp) {
+    ResetIncrementalStateIfRequired(trace_writer, incr_state, tls_state,
+                                    timestamp);
+    TrackRegistry::Get()->SerializeTrack(
+        track, NewTracePacket(trace_writer, incr_state, tls_state, timestamp));
+  }
+
+  // Get the current time in nanoseconds in the trace clock timebase.
+  static uint64_t GetTimeNs();
+
+  static TraceTimestamp GetTraceTime();
+
+  static inline protos::pbzero::BuiltinClock GetClockId() { return clock_; }
+  static inline void SetClockId(protos::pbzero::BuiltinClock clock) {
+    clock_ = clock;
+  }
+
+  static inline bool GetDisallowMergingWithSystemTracks() {
+    return disallow_merging_with_system_tracks_;
+  }
+  static inline void SetDisallowMergingWithSystemTracks(
+      bool disallow_merging_with_system_tracks) {
+    disallow_merging_with_system_tracks_ = disallow_merging_with_system_tracks;
+  }
+
+  static int GetSessionCount();
+
+  // Represents the default track for the calling thread.
+  static const Track kDefaultTrack;
+
+ private:
+  static void ResetIncrementalState(TraceWriterBase* trace_writer,
+                                    TrackEventIncrementalState* incr_state,
+                                    const TrackEventTlsState& tls_state,
+                                    const TraceTimestamp& timestamp);
+
+  static protozero::MessageHandle<protos::pbzero::TracePacket> NewTracePacket(
+      TraceWriterBase*,
+      TrackEventIncrementalState*,
+      const TrackEventTlsState& tls_state,
+      TraceTimestamp,
+      uint32_t seq_flags =
+          protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE);
+
+  static protos::pbzero::DebugAnnotation* AddDebugAnnotation(
+      perfetto::EventContext*,
+      const char* name);
+
+  static protos::pbzero::DebugAnnotation* AddDebugAnnotation(
+      perfetto::EventContext*,
+      perfetto::DynamicString name);
+
+  static std::atomic<int> session_count_;
+
+  static protos::pbzero::BuiltinClock clock_;
+  static bool disallow_merging_with_system_tracks_;
+};
+
+template <typename TraceContext>
+TrackEventTlsState::TrackEventTlsState(const TraceContext& trace_context) {
+  auto locked_ds = trace_context.GetDataSourceLocked();
+  bool disable_incremental_timestamps = false;
+  if (locked_ds.valid()) {
+    const auto& config = locked_ds->GetConfig();
+    disable_incremental_timestamps = config.disable_incremental_timestamps();
+    filter_debug_annotations = config.filter_debug_annotations();
+    filter_dynamic_event_names = config.filter_dynamic_event_names();
+    enable_thread_time_sampling = config.enable_thread_time_sampling();
+    if (config.has_timestamp_unit_multiplier()) {
+      timestamp_unit_multiplier = config.timestamp_unit_multiplier();
+    }
+  }
+  if (disable_incremental_timestamps) {
+    if (timestamp_unit_multiplier == 1) {
+      default_clock = static_cast<uint32_t>(TrackEventInternal::GetClockId());
+    } else {
+      default_clock = TrackEventIncrementalState::kClockIdAbsolute;
+    }
+  } else {
+    default_clock = TrackEventIncrementalState::kClockIdIncremental;
+  }
+}
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNAL_H_
+// gen_amalgamated begin header: include/perfetto/tracing/traced_proto.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACED_PROTO_H_
+#define INCLUDE_PERFETTO_TRACING_TRACED_PROTO_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/template_util.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
+
+namespace perfetto {
+class EventContext;
+namespace internal {
+template <typename FieldMetadata,
+          bool is_message,
+          protozero::proto_utils::RepetitionType repetition_type>
+struct TypedProtoWriterImpl;
+}
+
+// A Wrapper around a protozero message to allow C++ classes to specify how it
+// should be serialised into the trace:
+//
+// class Foo {
+//  public:
+//   void WriteIntoTrace(perfetto::TracedProto<pbzero::Foo> message) {
+//     message->set_int_field(int_field_);
+//   }
+// };
+//
+// This class also exposes EventContext, e.g. to enable data interning.
+//
+// NOTE: the functionality below is not ready yet.
+// TODO(altimin): Make the interop below possible.
+// TracedProto also provides a seamless integration with writing untyped
+// values via TracedValue / TracedDictionary / TracedArray:
+//
+// - TracedValue can be converted to a TracedProto, either by calling
+//   TracedValue::WriteProto<T>() or implicitly.
+// - If a proto message has a repeating DebugAnnotation debug_annotations
+//   field, it can be filled using the TracedDictionary obtained from
+//   TracedProto::AddDebugAnnotations.
+template <typename MessageType>
+class TracedProto {
+ public:
+  // implicit
+  TracedProto(TracedValue&& value)
+      : TracedProto(std::move(value).WriteProto<MessageType>()) {}
+  ~TracedProto() = default;
+
+  TracedProto(const TracedProto&) = delete;
+  TracedProto& operator=(const TracedProto&) = delete;
+  TracedProto& operator=(TracedProto&&) = delete;
+  TracedProto(TracedProto&&) = default;
+
+  MessageType* operator->() const { return message_; }
+
+  MessageType* message() { return message_; }
+
+  // Write additional untyped values into the same context, which is useful
+  // when a given C++ class has a typed representation, but also either has
+  // members which can only be written into an untyped context (e.g. they are
+  // autogenerated) or it's desirable to have a way to quickly extend the
+  // trace representation of this class (e.g. for debugging).
+  //
+  // The usage of the returned TracedDictionary should not be interleaved with
+  // writing into |message| as this results in an inefficient proto layout. To
+  // enforce this, AddDebugAnnotations should be called on TracedProto&&, i.e.
+  // std::move(message).AddDebugAnnotations().
+  //
+  // This requires a 'repeated DebugAnnotations debug_annotations' field in
+  // MessageType.
+  template <typename Check = void>
+  TracedDictionary AddDebugAnnotations() && {
+    static_assert(
+        std::is_base_of<
+            protozero::proto_utils::FieldMetadataBase,
+            typename MessageType::FieldMetadata_DebugAnnotations>::value,
+        "This message does not have a |debug_annotations| field. Please add a"
+        "'repeated perfetto.protos.DebugAnnotation debug_annnotations = N;' "
+        "field to your message.");
+    return TracedDictionary(message_, MessageType::kDebugAnnotations, context_,
+                            nullptr);
+  }
+
+  // Start writing a single entry corresponding to the given |field| and return
+  // TracedProto should be used to populate this further.
+  // This method requires |field|'s type to be a nested message, but both
+  // repeated and non-repeated complex fields are supported.
+  template <typename FieldMetadata>
+  TracedProto<typename FieldMetadata::cpp_field_type> WriteNestedMessage(
+      FieldMetadata) {
+    static_assert(std::is_base_of<MessageType,
+                                  typename FieldMetadata::message_type>::value,
+                  "Field should belong to the current message");
+    static_assert(
+        FieldMetadata::kProtoFieldType ==
+            protozero::proto_utils::ProtoSchemaType::kMessage,
+        "AddItem() can be used only for nested message fields. To write a "
+        "primitive field, use traced_proto->set_field() or traced_proto.Set()");
+    return Wrap(
+        message_->template BeginNestedMessage<
+            typename FieldMetadata::cpp_field_type>(FieldMetadata::kFieldId));
+  }
+
+  // Write a given |value| into proto  as a new |field| of the current message.
+  // This method supports both nested messages and primitive types (i.e. int or
+  // string), but requires the |field| to be non-repeateable (i.e. optional).
+  // For repeatable fields, AppendValue or AppendFrom should be used.
+  template <typename FieldMetadata, typename ValueType>
+  void Set(FieldMetadata, ValueType&& value) {
+    static_assert(std::is_base_of<MessageType,
+                                  typename FieldMetadata::message_type>::value,
+                  "Field should belong to the current message");
+    static_assert(
+        FieldMetadata::kRepetitionType ==
+            protozero::proto_utils::RepetitionType::kNotRepeated,
+        "Set() can't be used with repeated fields due to ambiguity between "
+        "writing |value| as a single entry or treating |value| as a container "
+        "and writing all contained items as multiple entries. Please use "
+        "dedicated AppendValue() or AppendFrom() methods to differentiate "
+        "between "
+        "these two situations");
+
+    internal::TypedProtoWriterImpl<
+        FieldMetadata,
+        FieldMetadata::kProtoFieldType ==
+            protozero::proto_utils::ProtoSchemaType::kMessage,
+        protozero::proto_utils::RepetitionType::kNotRepeated>::
+        Write(*this, std::forward<ValueType>(value));
+  }
+
+  // Write a given |value| a single entry into the repeated |field| of the
+  // current message. If the field is not repeated, Set() should be used
+  // instead.
+  template <typename FieldMetadata, typename ValueType>
+  void AppendValue(FieldMetadata, ValueType&& value) {
+    static_assert(std::is_base_of<MessageType,
+                                  typename FieldMetadata::message_type>::value,
+                  "Field should belong to the current message");
+    static_assert(
+        FieldMetadata::kRepetitionType ==
+            protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+        "Append*() methods can be used only with repeated fields. "
+        "Please use Set() for non-repeated");
+
+    // Write a single value into a given repeated field by explicitly passing
+    // "kNotRepeated" to the TypedProtoWriterImpl.
+    internal::TypedProtoWriterImpl<
+        FieldMetadata,
+        FieldMetadata::kProtoFieldType ==
+            protozero::proto_utils::ProtoSchemaType::kMessage,
+        protozero::proto_utils::RepetitionType::kNotRepeated>::
+        Write(*this, std::forward<ValueType>(value));
+  }
+
+  // Write a given |value| as a set of entries into the repeated |field| of the
+  // current message. If the field is not repeated, Set() should be used
+  // instead.
+  template <typename FieldMetadata, typename ValueType>
+  void AppendFrom(FieldMetadata, ValueType&& value) {
+    static_assert(std::is_base_of<MessageType,
+                                  typename FieldMetadata::message_type>::value,
+                  "Field should belong to the current message");
+    static_assert(
+        FieldMetadata::kRepetitionType ==
+            protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+        "Append*() methods can be used only with repeated fields. "
+        "Please use Set() for non-repeated");
+
+    internal::TypedProtoWriterImpl<
+        FieldMetadata,
+        FieldMetadata::kProtoFieldType ==
+            protozero::proto_utils::ProtoSchemaType::kMessage,
+        protozero::proto_utils::RepetitionType::kRepeatedNotPacked>::
+        Write(*this, std::forward<ValueType>(value));
+  }
+
+  // Write a nested message into a field according to the provided metadata.
+  // TODO(altimin): Replace the current usages in Chrome with the functions
+  // above and make these methods private.
+  template <typename FieldMetadata>
+  TracedProto<typename FieldMetadata::cpp_field_type> WriteNestedMessage() {
+    return WriteNestedMessage(FieldMetadata());
+  }
+
+ private:
+  friend class EventContext;
+  friend class TracedValue;
+  // Allow TracedProto<Foo> to create TracedProto<Bar>.
+  template <typename T>
+  friend class TracedProto;
+
+  // Wraps a raw protozero message using the same context as the current object.
+  template <typename ChildMessageType>
+  TracedProto<ChildMessageType> Wrap(ChildMessageType* message) {
+    return TracedProto<ChildMessageType>(message, context_);
+  }
+
+  // Context might be null here when writing typed message which is
+  // nested into untyped legacy trace event macro argument.
+  // TODO(altimin): Turn this into EventContext& when this case is eliminated
+  // and expose it in public API.
+  EventContext* context() const { return context_; }
+
+  TracedProto(MessageType* message, EventContext* context)
+      : message_(message), context_(context) {}
+
+  MessageType* const message_;
+  EventContext* context_;
+};
+
+template <typename MessageType, typename ValueType>
+void WriteIntoTracedProto(TracedProto<MessageType> message, ValueType&& value);
+
+namespace internal {
+
+template <typename FieldMetadata,
+          bool is_message,
+          protozero::proto_utils::RepetitionType repetition_type>
+struct TypedProtoWriterImpl;
+
+// Simple non-repeated field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+    FieldMetadata,
+    /*is_message=*/false,
+    protozero::proto_utils::RepetitionType::kNotRepeated> {
+  template <typename Proto, typename ValueType>
+  static void Write(TracedProto<Proto>& context, ValueType&& value) {
+    protozero::internal::FieldWriter<FieldMetadata::kProtoFieldType>::Append(
+        *context.message(), FieldMetadata::kFieldId, value);
+  }
+};
+
+// Simple repeated non-packed field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+    FieldMetadata,
+    /*is_message=*/false,
+    protozero::proto_utils::RepetitionType::kRepeatedNotPacked> {
+  template <typename Proto, typename ValueType>
+  static void Write(TracedProto<Proto>& context, ValueType&& value) {
+    for (auto&& item : value) {
+      protozero::internal::FieldWriter<FieldMetadata::kProtoFieldType>::Append(
+          *context.message(), FieldMetadata::kFieldId, item);
+    }
+  }
+};
+
+// Nested repeated non-packed field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+    FieldMetadata,
+    /*is_message=*/true,
+    protozero::proto_utils::RepetitionType::kNotRepeated> {
+  template <typename Proto, typename ValueType>
+  static void Write(TracedProto<Proto>& context, ValueType&& value) {
+    WriteIntoTracedProto(context.template WriteNestedMessage<FieldMetadata>(),
+                         std::forward<ValueType>(value));
+  }
+};
+
+// Nested repeated non-packed field.
+template <typename FieldMetadata>
+struct TypedProtoWriterImpl<
+    FieldMetadata,
+    /*is_message=*/true,
+    protozero::proto_utils::RepetitionType::kRepeatedNotPacked> {
+  template <typename Proto, typename ValueType>
+  static void Write(TracedProto<Proto>& context, ValueType&& value) {
+    for (auto&& item : value) {
+      WriteIntoTracedProto(context.template WriteNestedMessage<FieldMetadata>(),
+                           item);
+    }
+  }
+};
+
+constexpr int kMaxWriteTracedProtoImplPriority = 1;
+
+// If perfetto::TraceFormatTraits<T>::WriteIntoTrace(TracedProto<MessageType>,
+// T) is available, use it.
+template <typename MessageType, typename T>
+decltype(TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTrace(
+             std::declval<TracedProto<MessageType>>(),
+             std::declval<T>()),
+         void())
+WriteIntoTracedProtoImpl(base::priority_tag<1>,
+                         TracedProto<MessageType> message,
+                         T&& value) {
+  TraceFormatTraits<base::remove_cvref_t<T>>::WriteIntoTrace(
+      std::move(message), std::forward<T>(value));
+}
+
+// If T has WriteIntoTrace(TracedProto<MessageType>) method, use it.
+template <typename MessageType, typename T>
+decltype(
+    std::declval<T>().WriteIntoTrace(std::declval<TracedProto<MessageType>>()),
+    void())
+WriteIntoTracedProtoImpl(base::priority_tag<0>,
+                         TracedProto<MessageType> message,
+                         T&& value) {
+  value.WriteIntoTrace(std::move(message));
+}
+
+// TypedProtoWriter takes the protozero message (TracedProto<MessageType>),
+// field description (FieldMetadata) and value and writes the given value
+// into the given field of the given protozero message.
+//
+// This is primarily used for inline writing of typed messages:
+// TRACE_EVENT(..., pbzero::Message:kField, value);
+//
+// Ideally we would use a function here and not a struct, but passing template
+// arguments directly to the function (e.g. foo<void>()) isn't supported until
+// C++20, so we have to use a helper struct here.
+template <typename FieldMetadata>
+struct TypedProtoWriter {
+ private:
+  using ProtoSchemaType = protozero::proto_utils::ProtoSchemaType;
+  using RepetitionType = protozero::proto_utils::RepetitionType;
+
+  static_assert(FieldMetadata::kRepetitionType !=
+                    RepetitionType::kRepeatedPacked,
+                "writing packed fields isn't supported yet");
+
+  template <bool is_message, RepetitionType repetition_type>
+  struct Writer;
+
+ public:
+  template <typename Proto, typename ValueType>
+  static void Write(TracedProto<Proto>& context, ValueType&& value) {
+    TypedProtoWriterImpl<
+        FieldMetadata,
+        FieldMetadata::kProtoFieldType == ProtoSchemaType::kMessage,
+        FieldMetadata::kRepetitionType>::Write(context,
+                                               std::forward<ValueType>(value));
+  }
+};
+
+}  // namespace internal
+
+// Helper template to determine if a given type can be passed to
+// perfetto::WriteIntoTracedProto. These templates will fail to resolve if the
+// class does not have necesary support, so they are useful for SFINAE and for
+// producing helpful compiler error messages.
+template <typename MessageType, typename ValueType, typename Result = void>
+using check_traced_proto_support_t =
+    decltype(internal::WriteIntoTracedProtoImpl(
+        std::declval<
+            base::priority_tag<internal::kMaxWriteTracedProtoImplPriority>>(),
+        std::declval<TracedProto<MessageType>>(),
+        std::declval<ValueType>()));
+
+// check_traced_proto_support<MessageType, T, V>::type is defined (and equal to
+// V) iff T supports being passed to WriteIntoTracedProto together with
+// TracedProto<MessageType>. See the comment in traced_value_forward.h for more
+// details.
+template <typename MessageType, typename ValueType, class Result>
+struct check_traced_proto_support<
+    MessageType,
+    ValueType,
+    Result,
+    check_traced_proto_support_t<MessageType, ValueType, Result>> {
+  static constexpr bool value = true;
+  using type = Result;
+};
+
+template <typename MessageType, typename ValueType>
+void WriteIntoTracedProto(TracedProto<MessageType> message, ValueType&& value) {
+  // TODO(altimin): Add a URL to the documentation and a list of common failure
+  // patterns.
+  static_assert(
+      std::is_same<check_traced_proto_support_t<MessageType, ValueType>,
+                   void>::value,
+      "The provided type does not support being serialised into the "
+      "provided protozero message. Please see the comment in traced_proto.h "
+      "for more details.");
+
+  internal::WriteIntoTracedProtoImpl(
+      base::priority_tag<internal::kMaxWriteTracedProtoImplPriority>(),
+      std::move(message), std::forward<ValueType>(value));
+}
+
+template <typename MessageType, typename FieldMetadataType, typename ValueType>
+void WriteTracedProtoField(TracedProto<MessageType>& message,
+                           FieldMetadataType,
+                           ValueType&& value) {
+  static_assert(
+      std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+                      FieldMetadataType>::value,
+      "Field name should be a protozero::internal::FieldMetadata<...>");
+  static_assert(
+      std::is_base_of<MessageType,
+                      typename FieldMetadataType::message_type>::value,
+      "Field's parent type should match the context.");
+
+  internal::TypedProtoWriter<FieldMetadataType>::Write(
+      message, std::forward<ValueType>(value));
+}
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACED_PROTO_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_EVENT_CONTEXT_H_
+#define INCLUDE_PERFETTO_TRACING_EVENT_CONTEXT_H_
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_proto.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class DebugAnnotation;
+}  // namespace pbzero
+}  // namespace protos
+
+namespace internal {
+class TrackEventInternal;
+}
+
+// Allows adding custom arguments into track events. Example:
+//
+//   TRACE_EVENT_BEGIN("category", "Title",
+//                     [](perfetto::EventContext ctx) {
+//                       auto* log = ctx.event()->set_log_message();
+//                       log->set_body_iid(1234);
+//
+//                       ctx.AddDebugAnnotation("name", 1234);
+//                     });
+//
+class PERFETTO_EXPORT_COMPONENT EventContext {
+ public:
+  EventContext(EventContext&&) = default;
+
+  // For Chromium during the transition phase to the client library.
+  // TODO(eseckler): Remove once Chromium has switched to client lib entirely.
+  explicit EventContext(
+      protos::pbzero::TrackEvent* event,
+      internal::TrackEventIncrementalState* incremental_state = nullptr,
+      bool filter_debug_annotations = false)
+      : event_(event),
+        incremental_state_(incremental_state),
+        filter_debug_annotations_(filter_debug_annotations) {}
+
+  ~EventContext();
+
+  internal::TrackEventIncrementalState* GetIncrementalState() const {
+    return incremental_state_;
+  }
+
+  // Disclaimer: Experimental method, subject to change.
+  // Exposed publicly to emit some TrackEvent fields in Chromium only in local
+  // tracing. Long-term, we really shouldn't be (ab)using the
+  // filter_debug_annotation setting for this.
+  //
+  // TODO(kraskevich): Come up with a more precise name once we have more than
+  // one usecase.
+  bool ShouldFilterDebugAnnotations() const {
+    if (tls_state_) {
+      return tls_state_->filter_debug_annotations;
+    }
+    // In Chromium tls_state_ is nullptr, so we need to get this information
+    // from a separate field.
+    return filter_debug_annotations_;
+  }
+
+  // Get a TrackEvent message to write typed arguments to.
+  //
+  // event() is a template method to allow callers to specify a subclass of
+  // TrackEvent instead. Those subclasses correspond to TrackEvent message with
+  // application-specific extensions. More information in
+  // design-docs/extensions.md.
+  template <typename EventType = protos::pbzero::TrackEvent>
+  EventType* event() const {
+    // As the method does downcasting, we check that a target subclass does
+    // not add new fields.
+    static_assert(
+        sizeof(EventType) == sizeof(protos::pbzero::TrackEvent),
+        "Event type must be binary-compatible with protos::pbzero::TrackEvent");
+    return static_cast<EventType*>(event_);
+  }
+
+  // Convert a raw pointer to protozero message to TracedProto which captures
+  // the reference to this EventContext.
+  template <typename MessageType>
+  TracedProto<MessageType> Wrap(MessageType* message) {
+    static_assert(std::is_base_of<protozero::Message, MessageType>::value,
+                  "TracedProto can be used only with protozero messages");
+
+    return TracedProto<MessageType>(message, this);
+  }
+
+  // Add a new `debug_annotation` proto message and populate it from |value|
+  // using perfetto::TracedValue API. Users should generally prefer passing
+  // values directly to TRACE_EVENT (i.e. TRACE_EVENT(..., "arg", value, ...);)
+  // but in rare cases (e.g. when an argument should be written conditionally)
+  // EventContext::AddDebugAnnotation provides an explicit equivalent.
+  template <typename EventNameType, typename T>
+  void AddDebugAnnotation(EventNameType&& name, T&& value) {
+    if (tls_state_ && tls_state_->filter_debug_annotations)
+      return;
+    auto annotation = AddDebugAnnotation(std::forward<EventNameType>(name));
+    WriteIntoTracedValue(internal::CreateTracedValueFromProto(annotation, this),
+                         std::forward<T>(value));
+  }
+
+  // Read arbitrary user data that is associated with the thread-local per
+  // instance state of the track event. `key` must be non-null and unique
+  // per TrackEventTlsStateUserData subclass.
+  TrackEventTlsStateUserData* GetTlsUserData(const void* key);
+
+  // Set arbitrary user data that is associated with the thread-local per
+  // instance state of the track event. `key` must be non-null and unique
+  // per TrackEventTlsStateUserData subclass.
+  void SetTlsUserData(const void* key,
+                      std::unique_ptr<TrackEventTlsStateUserData> data);
+
+ private:
+  template <typename, size_t, typename, typename>
+  friend class TrackEventInternedDataIndex;
+  friend class internal::TrackEventInternal;
+
+  using TracePacketHandle =
+      ::protozero::MessageHandle<protos::pbzero::TracePacket>;
+
+  EventContext(TraceWriterBase* trace_writer,
+               TracePacketHandle,
+               internal::TrackEventIncrementalState*,
+               internal::TrackEventTlsState*);
+  EventContext(const EventContext&) = delete;
+
+  protos::pbzero::DebugAnnotation* AddDebugAnnotation(const char* name);
+  protos::pbzero::DebugAnnotation* AddDebugAnnotation(
+      ::perfetto::DynamicString name);
+
+  TraceWriterBase* trace_writer_ = nullptr;
+  TracePacketHandle trace_packet_;
+  protos::pbzero::TrackEvent* event_;
+  internal::TrackEventIncrementalState* incremental_state_;
+  // TODO(mohitms): Make it const-reference instead of pointer, once we
+  // are certain that it cannot be nullptr. Once we switch to client library in
+  // chrome, we can make that happen.
+  internal::TrackEventTlsState* tls_state_ = nullptr;
+  // TODO(kraskevich): Come up with a more precise name once we have more than
+  // one usecase.
+  // TODO(kraskevich): Remove once Chromium has fully switched to client lib.
+  const bool filter_debug_annotations_ = false;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_EVENT_CONTEXT_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_legacy.h
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_LEGACY_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_LEGACY_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#ifndef PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+#define PERFETTO_ENABLE_LEGACY_TRACE_EVENTS 0
+#endif
+
+// ----------------------------------------------------------------------------
+// Constants.
+// ----------------------------------------------------------------------------
+
+namespace perfetto {
+namespace legacy {
+
+enum TraceEventFlag {
+  kTraceEventFlagNone = 0,
+  kTraceEventFlagCopy = 1u << 0,
+  kTraceEventFlagHasId = 1u << 1,
+  kTraceEventFlagScopeOffset = 1u << 2,
+  kTraceEventFlagScopeExtra = 1u << 3,
+  kTraceEventFlagExplicitTimestamp = 1u << 4,
+  kTraceEventFlagAsyncTTS = 1u << 5,
+  kTraceEventFlagBindToEnclosing = 1u << 6,
+  kTraceEventFlagFlowIn = 1u << 7,
+  kTraceEventFlagFlowOut = 1u << 8,
+  kTraceEventFlagHasContextId = 1u << 9,
+  kTraceEventFlagHasProcessId = 1u << 10,
+  kTraceEventFlagHasLocalId = 1u << 11,
+  kTraceEventFlagHasGlobalId = 1u << 12,
+  // TODO(eseckler): Remove once we have native support for typed proto events
+  // in TRACE_EVENT macros.
+  kTraceEventFlagTypedProtoArgs = 1u << 15,
+  kTraceEventFlagJavaStringLiterals = 1u << 16,
+};
+
+enum PerfettoLegacyCurrentThreadId { kCurrentThreadId };
+
+// The following user-provided adaptors are used to serialize user-defined
+// thread id and time types into track events. For full compatibility, the user
+// should also define the following macros appropriately:
+//
+//   #define TRACE_TIME_TICKS_NOW() ...
+//   #define TRACE_TIME_NOW() ...
+
+// User-provided function to convert an abstract thread id into a thread track.
+template <typename T>
+ThreadTrack ConvertThreadId(const T&);
+
+// Built-in implementation for events referring to the current thread.
+template <>
+ThreadTrack PERFETTO_EXPORT_COMPONENT
+ConvertThreadId(const PerfettoLegacyCurrentThreadId&);
+
+}  // namespace legacy
+}  // namespace perfetto
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+// The following constants are defined in the global namespace, since they were
+// originally implemented as macros.
+
+// Event phases.
+static constexpr char TRACE_EVENT_PHASE_BEGIN = 'B';
+static constexpr char TRACE_EVENT_PHASE_END = 'E';
+static constexpr char TRACE_EVENT_PHASE_COMPLETE = 'X';
+static constexpr char TRACE_EVENT_PHASE_INSTANT = 'I';
+static constexpr char TRACE_EVENT_PHASE_ASYNC_BEGIN = 'S';
+static constexpr char TRACE_EVENT_PHASE_ASYNC_STEP_INTO = 'T';
+static constexpr char TRACE_EVENT_PHASE_ASYNC_STEP_PAST = 'p';
+static constexpr char TRACE_EVENT_PHASE_ASYNC_END = 'F';
+static constexpr char TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN = 'b';
+static constexpr char TRACE_EVENT_PHASE_NESTABLE_ASYNC_END = 'e';
+static constexpr char TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT = 'n';
+static constexpr char TRACE_EVENT_PHASE_FLOW_BEGIN = 's';
+static constexpr char TRACE_EVENT_PHASE_FLOW_STEP = 't';
+static constexpr char TRACE_EVENT_PHASE_FLOW_END = 'f';
+static constexpr char TRACE_EVENT_PHASE_METADATA = 'M';
+static constexpr char TRACE_EVENT_PHASE_COUNTER = 'C';
+static constexpr char TRACE_EVENT_PHASE_SAMPLE = 'P';
+static constexpr char TRACE_EVENT_PHASE_CREATE_OBJECT = 'N';
+static constexpr char TRACE_EVENT_PHASE_SNAPSHOT_OBJECT = 'O';
+static constexpr char TRACE_EVENT_PHASE_DELETE_OBJECT = 'D';
+static constexpr char TRACE_EVENT_PHASE_MEMORY_DUMP = 'v';
+static constexpr char TRACE_EVENT_PHASE_MARK = 'R';
+static constexpr char TRACE_EVENT_PHASE_CLOCK_SYNC = 'c';
+
+// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
+static constexpr uint32_t TRACE_EVENT_FLAG_NONE =
+    perfetto::legacy::kTraceEventFlagNone;
+static constexpr uint32_t TRACE_EVENT_FLAG_COPY =
+    perfetto::legacy::kTraceEventFlagCopy;
+static constexpr uint32_t TRACE_EVENT_FLAG_HAS_ID =
+    perfetto::legacy::kTraceEventFlagHasId;
+static constexpr uint32_t TRACE_EVENT_FLAG_SCOPE_OFFSET =
+    perfetto::legacy::kTraceEventFlagScopeOffset;
+static constexpr uint32_t TRACE_EVENT_FLAG_SCOPE_EXTRA =
+    perfetto::legacy::kTraceEventFlagScopeExtra;
+static constexpr uint32_t TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP =
+    perfetto::legacy::kTraceEventFlagExplicitTimestamp;
+static constexpr uint32_t TRACE_EVENT_FLAG_ASYNC_TTS =
+    perfetto::legacy::kTraceEventFlagAsyncTTS;
+static constexpr uint32_t TRACE_EVENT_FLAG_BIND_TO_ENCLOSING =
+    perfetto::legacy::kTraceEventFlagBindToEnclosing;
+static constexpr uint32_t TRACE_EVENT_FLAG_FLOW_IN =
+    perfetto::legacy::kTraceEventFlagFlowIn;
+static constexpr uint32_t TRACE_EVENT_FLAG_FLOW_OUT =
+    perfetto::legacy::kTraceEventFlagFlowOut;
+static constexpr uint32_t TRACE_EVENT_FLAG_HAS_CONTEXT_ID =
+    perfetto::legacy::kTraceEventFlagHasContextId;
+static constexpr uint32_t TRACE_EVENT_FLAG_HAS_PROCESS_ID =
+    perfetto::legacy::kTraceEventFlagHasProcessId;
+static constexpr uint32_t TRACE_EVENT_FLAG_HAS_LOCAL_ID =
+    perfetto::legacy::kTraceEventFlagHasLocalId;
+static constexpr uint32_t TRACE_EVENT_FLAG_HAS_GLOBAL_ID =
+    perfetto::legacy::kTraceEventFlagHasGlobalId;
+static constexpr uint32_t TRACE_EVENT_FLAG_TYPED_PROTO_ARGS =
+    perfetto::legacy::kTraceEventFlagTypedProtoArgs;
+static constexpr uint32_t TRACE_EVENT_FLAG_JAVA_STRING_LITERALS =
+    perfetto::legacy::kTraceEventFlagJavaStringLiterals;
+
+static constexpr uint32_t TRACE_EVENT_FLAG_SCOPE_MASK =
+    TRACE_EVENT_FLAG_SCOPE_OFFSET | TRACE_EVENT_FLAG_SCOPE_EXTRA;
+
+// Type values for identifying types in the TraceValue union.
+static constexpr uint8_t TRACE_VALUE_TYPE_BOOL = 1;
+static constexpr uint8_t TRACE_VALUE_TYPE_UINT = 2;
+static constexpr uint8_t TRACE_VALUE_TYPE_INT = 3;
+static constexpr uint8_t TRACE_VALUE_TYPE_DOUBLE = 4;
+static constexpr uint8_t TRACE_VALUE_TYPE_POINTER = 5;
+static constexpr uint8_t TRACE_VALUE_TYPE_STRING = 6;
+static constexpr uint8_t TRACE_VALUE_TYPE_COPY_STRING = 7;
+static constexpr uint8_t TRACE_VALUE_TYPE_CONVERTABLE = 8;
+static constexpr uint8_t TRACE_VALUE_TYPE_PROTO = 9;
+
+// Enum reflecting the scope of an INSTANT event. Must fit within
+// TRACE_EVENT_FLAG_SCOPE_MASK.
+static constexpr uint8_t TRACE_EVENT_SCOPE_GLOBAL = 0u << 2;
+static constexpr uint8_t TRACE_EVENT_SCOPE_PROCESS = 1u << 2;
+static constexpr uint8_t TRACE_EVENT_SCOPE_THREAD = 2u << 2;
+
+static constexpr char TRACE_EVENT_SCOPE_NAME_GLOBAL = 'g';
+static constexpr char TRACE_EVENT_SCOPE_NAME_PROCESS = 'p';
+static constexpr char TRACE_EVENT_SCOPE_NAME_THREAD = 't';
+
+#define TRACE_EVENT_API_CURRENT_THREAD_ID ::perfetto::legacy::kCurrentThreadId
+
+#endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+namespace perfetto {
+namespace internal {
+
+// LegacyTraceId encapsulates an ID that can either be an integer or pointer.
+class PERFETTO_EXPORT_COMPONENT LegacyTraceId {
+ public:
+  // Can be combined with WithScope.
+  class LocalId {
+   public:
+    explicit LocalId(const void* raw_id)
+        : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {}
+    explicit LocalId(uint64_t raw_id) : raw_id_(raw_id) {}
+    uint64_t raw_id() const { return raw_id_; }
+
+   private:
+    uint64_t raw_id_;
+  };
+
+  // Can be combined with WithScope.
+  class GlobalId {
+   public:
+    explicit GlobalId(uint64_t raw_id) : raw_id_(raw_id) {}
+    uint64_t raw_id() const { return raw_id_; }
+
+   private:
+    uint64_t raw_id_;
+  };
+
+  class WithScope {
+   public:
+    WithScope(const char* scope, uint64_t raw_id)
+        : scope_(scope), raw_id_(raw_id) {}
+    WithScope(const char* scope, LocalId local_id)
+        : scope_(scope), raw_id_(local_id.raw_id()) {
+      id_flags_ = legacy::kTraceEventFlagHasLocalId;
+    }
+    WithScope(const char* scope, GlobalId global_id)
+        : scope_(scope), raw_id_(global_id.raw_id()) {
+      id_flags_ = legacy::kTraceEventFlagHasGlobalId;
+    }
+    WithScope(const char* scope, uint64_t prefix, uint64_t raw_id)
+        : scope_(scope), has_prefix_(true), prefix_(prefix), raw_id_(raw_id) {}
+    WithScope(const char* scope, uint64_t prefix, GlobalId global_id)
+        : scope_(scope),
+          has_prefix_(true),
+          prefix_(prefix),
+          raw_id_(global_id.raw_id()) {
+      id_flags_ = legacy::kTraceEventFlagHasGlobalId;
+    }
+    uint64_t raw_id() const { return raw_id_; }
+    const char* scope() const { return scope_; }
+    bool has_prefix() const { return has_prefix_; }
+    uint64_t prefix() const { return prefix_; }
+    uint32_t id_flags() const { return id_flags_; }
+
+   private:
+    const char* scope_ = nullptr;
+    bool has_prefix_ = false;
+    uint64_t prefix_;
+    uint64_t raw_id_;
+    uint32_t id_flags_ = legacy::kTraceEventFlagHasId;
+  };
+
+  explicit LegacyTraceId(const void* raw_id)
+      : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {
+    id_flags_ = legacy::kTraceEventFlagHasLocalId;
+  }
+  explicit LegacyTraceId(uint64_t raw_id) : raw_id_(raw_id) {}
+  explicit LegacyTraceId(uint32_t raw_id) : raw_id_(raw_id) {}
+  explicit LegacyTraceId(uint16_t raw_id) : raw_id_(raw_id) {}
+  explicit LegacyTraceId(uint8_t raw_id) : raw_id_(raw_id) {}
+  explicit LegacyTraceId(int64_t raw_id)
+      : raw_id_(static_cast<uint64_t>(raw_id)) {}
+  explicit LegacyTraceId(int32_t raw_id)
+      : raw_id_(static_cast<uint64_t>(raw_id)) {}
+  explicit LegacyTraceId(int16_t raw_id)
+      : raw_id_(static_cast<uint64_t>(raw_id)) {}
+  explicit LegacyTraceId(int8_t raw_id)
+      : raw_id_(static_cast<uint64_t>(raw_id)) {}
+// Different platforms disagree on which integer types are same and which
+// are different. E.g. on Mac size_t is considered a different type from
+// uint64_t even though it has the same size and signedness.
+// Below we add overloads for those types that are known to cause ambiguity.
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
+  explicit LegacyTraceId(size_t raw_id) : raw_id_(raw_id) {}
+  explicit LegacyTraceId(intptr_t raw_id)
+      : raw_id_(static_cast<uint64_t>(raw_id)) {}
+#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+  explicit LegacyTraceId(unsigned long raw_id) : raw_id_(raw_id) {}
+#endif
+  explicit LegacyTraceId(LocalId raw_id) : raw_id_(raw_id.raw_id()) {
+    id_flags_ = legacy::kTraceEventFlagHasLocalId;
+  }
+  explicit LegacyTraceId(GlobalId raw_id) : raw_id_(raw_id.raw_id()) {
+    id_flags_ = legacy::kTraceEventFlagHasGlobalId;
+  }
+  explicit LegacyTraceId(WithScope scoped_id)
+      : scope_(scoped_id.scope()),
+        has_prefix_(scoped_id.has_prefix()),
+        prefix_(scoped_id.prefix()),
+        raw_id_(scoped_id.raw_id()),
+        id_flags_(scoped_id.id_flags()) {}
+
+  uint64_t raw_id() const { return raw_id_; }
+  const char* scope() const { return scope_; }
+  bool has_prefix() const { return has_prefix_; }
+  uint64_t prefix() const { return prefix_; }
+  uint32_t id_flags() const { return id_flags_; }
+
+  void Write(protos::pbzero::TrackEvent::LegacyEvent*,
+             uint32_t event_flags) const;
+
+ private:
+  const char* scope_ = nullptr;
+  bool has_prefix_ = false;
+  uint64_t prefix_;
+  uint64_t raw_id_;
+  uint32_t id_flags_ = legacy::kTraceEventFlagHasId;
+};
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+template <typename T>
+bool IsEqual(T x, T y) {
+  return x == y;
+}
+
+template <typename T, typename U>
+bool IsEqual(T, U) {
+  return false;
+}
+
+class PERFETTO_EXPORT_COMPONENT TrackEventLegacy {
+ public:
+  static constexpr protos::pbzero::TrackEvent::Type PhaseToType(char phase) {
+    // clang-format off
+    return (phase == TRACE_EVENT_PHASE_BEGIN) ?
+               protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN :
+           (phase == TRACE_EVENT_PHASE_END) ?
+               protos::pbzero::TrackEvent::TYPE_SLICE_END :
+           (phase == TRACE_EVENT_PHASE_INSTANT) ?
+               protos::pbzero::TrackEvent::TYPE_INSTANT :
+           protos::pbzero::TrackEvent::TYPE_UNSPECIFIED;
+    // clang-format on
+  }
+
+  // Reduce binary size overhead by outlining most of the code for writing a
+  // legacy trace event.
+  template <typename... Args>
+  static void WriteLegacyEvent(EventContext ctx,
+                               char phase,
+                               uint32_t flags,
+                               Args&&... args) PERFETTO_NO_INLINE {
+    PERFETTO_DCHECK(!(flags & TRACE_EVENT_FLAG_HAS_PROCESS_ID));
+    AddDebugAnnotations(&ctx, std::forward<Args>(args)...);
+    if (NeedLegacyFlags(phase, flags)) {
+      auto legacy_event = ctx.event()->set_legacy_event();
+      SetLegacyFlags(legacy_event, phase, flags);
+    }
+  }
+
+  template <typename ThreadIdType, typename... Args>
+  static void WriteLegacyEventWithIdAndTid(EventContext ctx,
+                                           char phase,
+                                           uint32_t flags,
+                                           const LegacyTraceId& id,
+                                           const ThreadIdType& thread_id,
+                                           Args&&... args) PERFETTO_NO_INLINE {
+    //
+    // Overrides to consider:
+    //
+    // 1. If we have an id, we need to write {unscoped,local,global}_id and/or
+    //    bind_id.
+    // 2. If we have a thread id, we need to write track_uuid() or
+    //    {pid,tid}_override if the id represents another process.  The
+    //    conversion from |thread_id| happens in embedder code since the type is
+    //    embedder-specified.
+    // 3. If we have a timestamp, we need to write a different timestamp in the
+    //    trace packet itself and make sure TrackEvent won't write one
+    //    internally. This is already done at the call site.
+    //
+    PERFETTO_DCHECK(PhaseToType(phase) ==
+                        protos::pbzero::TrackEvent::TYPE_UNSPECIFIED ||
+                    !(flags & TRACE_EVENT_FLAG_HAS_PROCESS_ID));
+    flags |= id.id_flags();
+    AddDebugAnnotations(&ctx, std::forward<Args>(args)...);
+    if (NeedLegacyFlags(phase, flags)) {
+      auto legacy_event = ctx.event()->set_legacy_event();
+      SetLegacyFlags(legacy_event, phase, flags);
+      if (id.id_flags())
+        id.Write(legacy_event, flags);
+      if (flags & TRACE_EVENT_FLAG_HAS_PROCESS_ID) {
+        // The thread identifier actually represents a process id. Let's set an
+        // override for it.
+        int32_t pid_override =
+            static_cast<int32_t>(legacy::ConvertThreadId(thread_id).tid);
+        legacy_event->set_pid_override(pid_override);
+        legacy_event->set_tid_override(-1);
+      } else {
+        // Only synchronous phases are supported for other threads. These phases
+        // are supported in TrackEvent types and receive a track_uuid
+        // association via TrackEventDataSource::TraceForCategoryImpl().
+        PERFETTO_DCHECK(PhaseToType(phase) !=
+                            protos::pbzero::TrackEvent::TYPE_UNSPECIFIED ||
+                        IsEqual(thread_id, TRACE_EVENT_API_CURRENT_THREAD_ID) ||
+                        legacy::ConvertThreadId(thread_id).tid ==
+                            ThreadTrack::Current().tid);
+      }
+    }
+  }
+
+  // No arguments.
+  static void AddDebugAnnotations(EventContext*) {}
+
+  // N number of debug arguments.
+  template <typename ArgNameType, typename ArgType, typename... OtherArgs>
+  static void AddDebugAnnotations(EventContext* ctx,
+                                  ArgNameType&& arg_name,
+                                  ArgType&& arg_value,
+                                  OtherArgs&&... more_args) {
+    TrackEventInternal::AddDebugAnnotation(ctx,
+                                           std::forward<ArgNameType>(arg_name),
+                                           std::forward<ArgType>(arg_value));
+    AddDebugAnnotations(ctx, std::forward<OtherArgs>(more_args)...);
+  }
+
+ private:
+  static bool NeedLegacyFlags(char phase, uint32_t flags) {
+    if (PhaseToType(phase) == protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
+      return true;
+    // TODO(skyostil): Implement/deprecate:
+    // - TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP
+    // - TRACE_EVENT_FLAG_HAS_CONTEXT_ID
+    // - TRACE_EVENT_FLAG_TYPED_PROTO_ARGS
+    // - TRACE_EVENT_FLAG_JAVA_STRING_LITERALS
+    return flags &
+           (TRACE_EVENT_FLAG_HAS_ID | TRACE_EVENT_FLAG_HAS_LOCAL_ID |
+            TRACE_EVENT_FLAG_HAS_GLOBAL_ID | TRACE_EVENT_FLAG_ASYNC_TTS |
+            TRACE_EVENT_FLAG_BIND_TO_ENCLOSING | TRACE_EVENT_FLAG_FLOW_IN |
+            TRACE_EVENT_FLAG_FLOW_OUT | TRACE_EVENT_FLAG_HAS_PROCESS_ID);
+  }
+
+  static void SetLegacyFlags(
+      protos::pbzero::TrackEvent::LegacyEvent* legacy_event,
+      char phase,
+      uint32_t flags) {
+    if (PhaseToType(phase) == protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
+      legacy_event->set_phase(phase);
+    if (flags & TRACE_EVENT_FLAG_ASYNC_TTS)
+      legacy_event->set_use_async_tts(true);
+    if (flags & TRACE_EVENT_FLAG_BIND_TO_ENCLOSING)
+      legacy_event->set_bind_to_enclosing(true);
+
+    const auto kFlowIn = TRACE_EVENT_FLAG_FLOW_IN;
+    const auto kFlowOut = TRACE_EVENT_FLAG_FLOW_OUT;
+    const auto kFlowInOut = kFlowIn | kFlowOut;
+    if ((flags & kFlowInOut) == kFlowInOut) {
+      legacy_event->set_flow_direction(
+          protos::pbzero::TrackEvent::LegacyEvent::FLOW_INOUT);
+    } else if (flags & kFlowIn) {
+      legacy_event->set_flow_direction(
+          protos::pbzero::TrackEvent::LegacyEvent::FLOW_IN);
+    } else if (flags & kFlowOut) {
+      legacy_event->set_flow_direction(
+          protos::pbzero::TrackEvent::LegacyEvent::FLOW_OUT);
+    }
+  }
+};
+#endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+// Legacy macros allow argument values to be nullptr and convert them to the
+// "NULL" string. The following function helps mimic this behavior: it forwards
+// all types of arguments apart from a nullptr string as is, and in case of a
+// nullptr returns "NULL".
+template <typename T>
+inline T PossiblyNull(T&& value) {
+  return std::forward<T>(value);
+}
+
+inline const char* PossiblyNull(const char* name) {
+  return name ? name : "NULL";
+}
+
+inline const char* PossiblyNull(char* name) {
+  return name ? name : "NULL";
+}
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_LEGACY_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/write_track_event_args.h
+// gen_amalgamated begin header: include/perfetto/tracing/track_event_args.h
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
+
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+
+namespace perfetto {
+
+// A helper to add |flow_id| as a non-terminating flow id to TRACE_EVENT
+// inline: TRACE_EVENT(..., perfetto::Flow::ProcessScoped(42));
+class Flow {
+ public:
+  // |flow_id| which is local within a given process (e.g. atomic counter xor'ed
+  // with feature-specific value). This value is xor'ed with Perfetto's internal
+  // process track id to attempt to ensure that it's globally-unique.
+  static PERFETTO_ALWAYS_INLINE inline Flow ProcessScoped(uint64_t flow_id) {
+    return Global(flow_id ^ Track::process_uuid);
+  }
+
+  // Same as above, but construct an id from a pointer.
+  // NOTE: After the object is destroyed, the value of |ptr| can be reused for a
+  // different object (in particular if the object is allocated on a stack).
+  // Please ensure that you emit a trace event with the flow id of
+  // perfetto::TerminatingFlow::FromPointer(this) from the destructor of the
+  // object to avoid accidental conflicts.
+  static PERFETTO_ALWAYS_INLINE inline Flow FromPointer(void* ptr) {
+    return ProcessScoped(reinterpret_cast<uintptr_t>(ptr));
+  }
+
+  // Add the |flow_id|. The caller is responsible for ensuring that it's
+  // globally-unique (e.g. by generating a random value). This should be used
+  // only for flow events which cross the process boundary (e.g. IPCs).
+  static PERFETTO_ALWAYS_INLINE inline Flow Global(uint64_t flow_id) {
+    return Flow(flow_id);
+  }
+
+  // TODO(altimin): Remove once converting a single usage in Chromium.
+  explicit constexpr Flow(uint64_t flow_id) : flow_id_(flow_id) {}
+
+  void operator()(EventContext& ctx) const {
+    ctx.event()->add_flow_ids(flow_id_);
+  }
+
+ private:
+  uint64_t flow_id_;
+};
+
+// A helper to add a given |flow_id| as a terminating flow to TRACE_EVENT
+// inline.
+class TerminatingFlow {
+ public:
+  // See `Flow::ProcessScoped(uint64_t)`.
+  static PERFETTO_ALWAYS_INLINE inline TerminatingFlow ProcessScoped(
+      uint64_t flow_id) {
+    return Global(flow_id ^ Track::process_uuid);
+  }
+
+  // See `Flow::FromPointer(void*)`.
+  static PERFETTO_ALWAYS_INLINE inline TerminatingFlow FromPointer(void* ptr) {
+    return ProcessScoped(reinterpret_cast<uintptr_t>(ptr));
+  }
+
+  // See `Flow::Global(uint64_t)`.
+  static PERFETTO_ALWAYS_INLINE inline TerminatingFlow Global(
+      uint64_t flow_id) {
+    TerminatingFlow tf;
+    tf.flow_id_ = flow_id;
+    return tf;
+  }
+
+  void operator()(EventContext& ctx) const {
+    ctx.event()->add_terminating_flow_ids(flow_id_);
+  }
+
+ private:
+  uint64_t flow_id_;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_ARGS_H_
+/*
+ * 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_WRITE_TRACK_EVENT_ARGS_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_WRITE_TRACK_EVENT_ARGS_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/traced_proto.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_args.h"
+
+namespace perfetto {
+namespace internal {
+
+// No arguments means that we don't have to write anything.
+PERFETTO_ALWAYS_INLINE inline void WriteTrackEventArgs(EventContext) {}
+
+namespace {
+
+// A template helper for determining whether a type can be used as a track event
+// lambda, i.e., it has the signature "void(EventContext)". This is achieved by
+// checking that we can pass an EventContext value (the inner declval) into a T
+// instance (the outer declval). If this is a valid expression, the result
+// evaluates to sizeof(0), i.e., true.
+// TODO(skyostil): Replace this with std::is_convertible<std::function<...>>
+// once we have C++14.
+template <typename T>
+static constexpr bool IsValidTraceLambdaImpl(
+    typename std::enable_if<static_cast<bool>(
+        sizeof(std::declval<T>()(std::declval<EventContext>()), 0))>::type* =
+        nullptr) {
+  return true;
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambdaImpl(...) {
+  return false;
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambda() {
+  return IsValidTraceLambdaImpl<T>(nullptr);
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambdaTakingReferenceImpl(
+    typename std::enable_if<static_cast<bool>(
+        sizeof(std::declval<T>()(std::declval<EventContext&>()), 0))>::type* =
+        nullptr) {
+  return true;
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambdaTakingReferenceImpl(...) {
+  return false;
+}
+
+template <typename T>
+static constexpr bool IsValidTraceLambdaTakingReference() {
+  return IsValidTraceLambdaTakingReferenceImpl<T>(nullptr);
+}
+
+template <typename T>
+static constexpr bool IsFieldMetadataTypeImpl(
+    typename std::enable_if<
+        std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+                        T>::value>::type* = nullptr) {
+  return true;
+}
+
+template <typename T>
+static constexpr bool IsFieldMetadataTypeImpl(...) {
+  return false;
+}
+
+template <typename T>
+static constexpr bool IsFieldMetadataType() {
+  return IsFieldMetadataTypeImpl<T>(nullptr);
+}
+
+}  // namespace
+
+// Write an old-style lambda taking an EventContext (without a reference)
+// as it will consume EventContext via std::move, it can only be the last
+// argument.
+template <typename ArgumentFunction,
+          typename ArgFunctionCheck = typename std::enable_if<
+              IsValidTraceLambda<ArgumentFunction>()>::type>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(
+    EventContext event_ctx,
+    const ArgumentFunction& arg_function) {
+  arg_function(std::move(event_ctx));
+}
+
+// Forward-declare the specification for writing untyped arguments to ensure
+// that typed specification could recursively pick it up.
+template <typename ArgValue, typename... Args>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                const char* arg_name,
+                                                ArgValue&& arg_value,
+                                                Args&&... args);
+
+template <typename FieldMetadataType,
+          typename ArgValue,
+          typename... Args,
+          typename FieldMetadataTypeCheck = typename std::enable_if<
+              IsFieldMetadataType<FieldMetadataType>()>::type>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                FieldMetadataType field_name,
+                                                ArgValue&& arg_value,
+                                                Args&&... args);
+
+template <typename ArgumentFunction,
+          typename... Args,
+          typename ArgFunctionCheck = typename std::enable_if<
+              IsValidTraceLambdaTakingReference<ArgumentFunction>()>::type>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(
+    EventContext event_ctx,
+    const ArgumentFunction& arg_function,
+    Args&&... args) {
+  // |arg_function| will capture EventContext by reference, so std::move isn't
+  // needed.
+  arg_function(event_ctx);
+
+  WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
+}
+
+// Write one typed message and recursively write the rest of the arguments.
+template <typename FieldMetadataType,
+          typename ArgValue,
+          typename... Args,
+          typename FieldMetadataTypeCheck>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                FieldMetadataType field_name,
+                                                ArgValue&& arg_value,
+                                                Args&&... args) {
+  static_assert(std::is_base_of<protozero::proto_utils::FieldMetadataBase,
+                                FieldMetadataType>::value,
+                "");
+  static_assert(
+      std::is_base_of<protos::pbzero::TrackEvent,
+                      typename FieldMetadataType::message_type>::value,
+      "Only fields of TrackEvent (and TrackEvent's extensions) can "
+      "be passed to TRACE_EVENT");
+  auto track_event_proto = event_ctx.Wrap(
+      event_ctx.event<typename FieldMetadataType::message_type>());
+  WriteTracedProtoField(track_event_proto, field_name,
+                        std::forward<ArgValue>(arg_value));
+  WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
+}
+
+// Write one debug annotation and recursively write the rest of the arguments.
+template <typename ArgValue, typename... Args>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                const char* arg_name,
+                                                ArgValue&& arg_value,
+                                                Args&&... args) {
+  event_ctx.AddDebugAnnotation(arg_name, std::forward<ArgValue>(arg_value));
+  WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
+}
+
+// Write one debug annotation and recursively write the rest of the arguments.
+template <typename ArgValue, typename... Args>
+PERFETTO_ALWAYS_INLINE void WriteTrackEventArgs(EventContext event_ctx,
+                                                DynamicString arg_name,
+                                                ArgValue&& arg_value,
+                                                Args&&... args) {
+  event_ctx.AddDebugAnnotation(arg_name, std::forward<ArgValue>(arg_value));
+  WriteTrackEventArgs(std::move(event_ctx), std::forward<Args>(args)...);
+}
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_WRITE_TRACK_EVENT_ARGS_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event_category_registry.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_CATEGORY_REGISTRY_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_CATEGORY_REGISTRY_H_
+
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+
+#include <stddef.h>
+
+#include <atomic>
+#include <utility>
+
+namespace perfetto {
+class DynamicCategory;
+
+// A compile-time representation of a track event category. See
+// PERFETTO_DEFINE_CATEGORIES for registering your own categories.
+struct PERFETTO_EXPORT_COMPONENT Category {
+  using Tags = std::array<const char*, 4>;
+
+  const char* const name = nullptr;
+  const char* const description = nullptr;
+  const Tags tags = {};
+
+  constexpr Category(const Category&) = default;
+  constexpr explicit Category(const char* name_)
+      : name(CheckIsValidCategory(name_)),
+        name_sizes_(ComputeNameSizes(name_)) {}
+
+  constexpr Category SetDescription(const char* description_) const {
+    return Category(name, description_, tags, name_sizes_);
+  }
+
+  template <typename... Args>
+  constexpr Category SetTags(Args&&... args) const {
+    return Category(name, description, {std::forward<Args>(args)...},
+                    name_sizes_);
+  }
+
+  // A comma separated list of multiple categories to be used in a single trace
+  // point.
+  static constexpr Category Group(const char* names) {
+    return Category(names, AllowGroup{});
+  }
+
+  // Used for parsing dynamic category groups. Note that |name| and
+  // |DynamicCategory| must outlive the returned object because the category
+  // name isn't copied.
+  static Category FromDynamicCategory(const char* name);
+  static Category FromDynamicCategory(const DynamicCategory&);
+
+  constexpr bool IsGroup() const { return GetNameSize(1) > 0; }
+
+  // Returns the number of character in the category name. Not valid for
+  // category groups.
+  size_t name_size() const {
+    PERFETTO_DCHECK(!IsGroup());
+    return GetNameSize(0);
+  }
+
+  // Iterates over all the members of this category group, or just the name of
+  // the category itself if this isn't a category group. Return false from
+  // |callback| to stop iteration.
+  template <typename T>
+  void ForEachGroupMember(T callback) const {
+    const char* name_ptr = name;
+    size_t i = 0;
+    while (size_t name_size = GetNameSize(i++)) {
+      if (!callback(name_ptr, name_size))
+        break;
+      name_ptr += name_size + 1;
+    }
+  }
+
+ private:
+  static constexpr size_t kMaxGroupSize = 4;
+  using NameSizes = std::array<uint8_t, kMaxGroupSize>;
+
+  constexpr Category(const char* name_,
+                     const char* description_,
+                     Tags tags_,
+                     NameSizes name_sizes)
+      : name(name_),
+        description(description_),
+        tags(tags_),
+        name_sizes_(name_sizes) {}
+
+  enum AllowGroup {};
+  constexpr Category(const char* name_, AllowGroup)
+      : name(CheckIsValidCategoryGroup(name_)),
+        name_sizes_(ComputeNameSizes(name_)) {}
+
+  constexpr size_t GetNameSize(size_t i) const {
+    return i < name_sizes_.size() ? name_sizes_[i] : 0;
+  }
+
+  static constexpr NameSizes ComputeNameSizes(const char* s) {
+    static_assert(kMaxGroupSize == 4, "Unexpected maximum category group size");
+    return NameSizes{{static_cast<uint8_t>(GetNthNameSize(0, s, s)),
+                      static_cast<uint8_t>(GetNthNameSize(1, s, s)),
+                      static_cast<uint8_t>(GetNthNameSize(2, s, s)),
+                      static_cast<uint8_t>(GetNthNameSize(3, s, s))}};
+  }
+
+  static constexpr ptrdiff_t GetNthNameSize(int n,
+                                            const char* start,
+                                            const char* end,
+                                            int counter = 0) {
+    return (!*end || *end == ',')
+               ? ((!*end || counter == n)
+                      ? (counter == n ? end - start : 0)
+                      : GetNthNameSize(n, end + 1, end + 1, counter + 1))
+               : GetNthNameSize(n, start, end + 1, counter);
+  }
+
+  static constexpr const char* CheckIsValidCategory(const char* n) {
+    // We just replace invalid input with a nullptr here; it will trigger a
+    // static assert in TrackEventCategoryRegistry::ValidateCategories().
+    return GetNthNameSize(1, n, n) ? nullptr : n;
+  }
+
+  static constexpr const char* CheckIsValidCategoryGroup(const char* n) {
+    // Same as above: replace invalid input with nullptr.
+    return !GetNthNameSize(1, n, n) || GetNthNameSize(kMaxGroupSize, n, n)
+               ? nullptr
+               : n;
+  }
+
+  // An array of lengths of the different names associated with this category.
+  // If this category doesn't represent a group of multiple categories, only the
+  // first element is non-zero.
+  const NameSizes name_sizes_ = {};
+};
+
+// Dynamically constructed category names should marked as such through this
+// container type to make it less likely for trace points to accidentally start
+// using dynamic categories. Events with dynamic categories will always be
+// slightly more expensive than regular events, so use them sparingly.
+class PERFETTO_EXPORT_COMPONENT DynamicCategory final {
+ public:
+  explicit DynamicCategory(const std::string& name_) : name(name_) {}
+  explicit DynamicCategory(const char* name_) : name(name_) {}
+  DynamicCategory() {}
+  ~DynamicCategory() = default;
+
+  DynamicCategory(const DynamicCategory&) = default;
+  DynamicCategory& operator=(const DynamicCategory&) = delete;
+
+  DynamicCategory(DynamicCategory&&) = default;
+  DynamicCategory& operator=(DynamicCategory&&) = delete;
+
+  const std::string name;
+};
+
+namespace internal {
+
+constexpr const char* NullCategory(const char*) {
+  return nullptr;
+}
+
+perfetto::DynamicCategory NullCategory(const perfetto::DynamicCategory&);
+
+constexpr bool StringMatchesPrefix(const char* str, const char* prefix) {
+  return !*str ? !*prefix
+               : !*prefix ? true
+                          : *str != *prefix
+                                ? false
+                                : StringMatchesPrefix(str + 1, prefix + 1);
+}
+
+constexpr bool IsStringInPrefixList(const char*) {
+  return false;
+}
+
+template <typename... Args>
+constexpr bool IsStringInPrefixList(const char* str,
+                                    const char* prefix,
+                                    Args... args) {
+  return StringMatchesPrefix(str, prefix) ||
+         IsStringInPrefixList(str, std::forward<Args>(args)...);
+}
+
+// Holds all the registered categories for one category namespace. See
+// PERFETTO_DEFINE_CATEGORIES for building the registry.
+class PERFETTO_EXPORT_COMPONENT TrackEventCategoryRegistry {
+ public:
+  constexpr TrackEventCategoryRegistry(size_t category_count,
+                                       const Category* categories,
+                                       std::atomic<uint8_t>* state_storage)
+      : categories_(categories),
+        category_count_(category_count),
+        state_storage_(state_storage) {
+    static_assert(
+        sizeof(state_storage[0].load()) * 8 >= kMaxDataSourceInstances,
+        "The category state must have enough bits for all possible data source "
+        "instances");
+  }
+
+  size_t category_count() const { return category_count_; }
+
+  // Returns a category based on its index.
+  const Category* GetCategory(size_t index) const {
+    PERFETTO_DCHECK(index < category_count_);
+    return &categories_[index];
+  }
+
+  // Turn tracing on or off for the given category in a track event data source
+  // instance.
+  void EnableCategoryForInstance(size_t category_index,
+                                 uint32_t instance_index) const;
+  void DisableCategoryForInstance(size_t category_index,
+                                  uint32_t instance_index) const;
+
+  constexpr std::atomic<uint8_t>* GetCategoryState(
+      size_t category_index) const {
+    return &state_storage_[category_index];
+  }
+
+  // --------------------------------------------------------------------------
+  // Trace point support
+  // --------------------------------------------------------------------------
+  //
+  // (The following methods are used by the track event trace point
+  // implementation and typically don't need to be called by other code.)
+
+  // At compile time, turn a category name into an index into the registry.
+  // Returns kInvalidCategoryIndex if the category was not found, or
+  // kDynamicCategoryIndex if |is_dynamic| is true or a DynamicCategory was
+  // passed in.
+  static constexpr size_t kInvalidCategoryIndex = static_cast<size_t>(-1);
+  static constexpr size_t kDynamicCategoryIndex = static_cast<size_t>(-2);
+  constexpr size_t Find(const char* name, bool is_dynamic) const {
+    return CheckIsValidCategoryIndex(FindImpl(name, is_dynamic));
+  }
+
+  constexpr size_t Find(const DynamicCategory&, bool) const {
+    return kDynamicCategoryIndex;
+  }
+
+  constexpr bool ValidateCategories(size_t index = 0) const {
+    return (index == category_count_)
+               ? true
+               : IsValidCategoryName(categories_[index].name)
+                     ? ValidateCategories(index + 1)
+                     : false;
+  }
+
+ private:
+  // TODO(skyostil): Make the compile-time routines nicer with C++14.
+  constexpr size_t FindImpl(const char* name,
+                            bool is_dynamic,
+                            size_t index = 0) const {
+    return is_dynamic ? kDynamicCategoryIndex
+                      : (index == category_count_)
+                            ? kInvalidCategoryIndex
+                            : StringEq(categories_[index].name, name)
+                                  ? index
+                                  : FindImpl(name, false, index + 1);
+  }
+
+  // A compile time helper for checking that a category index is valid.
+  static constexpr size_t CheckIsValidCategoryIndex(size_t index) {
+    // Relies on PERFETTO_CHECK() (and the surrounding lambda) being a
+    // non-constexpr function, which will fail the build if the given |index| is
+    // invalid. The funny formatting here is so that clang shows the comment
+    // below as part of the error message.
+    // clang-format off
+    return index != kInvalidCategoryIndex ? index : \
+        /* Invalid category -- add it to PERFETTO_DEFINE_CATEGORIES(). */ [] {
+        PERFETTO_CHECK(
+            false &&
+            "A track event used an unknown category. Please add it to "
+            "PERFETTO_DEFINE_CATEGORIES().");
+        return kInvalidCategoryIndex;
+      }();
+    // clang-format on
+  }
+
+  static constexpr bool IsValidCategoryName(const char* name) {
+    return (!name || *name == '\"' || *name == '*' || *name == ' ')
+               ? false
+               : *name ? IsValidCategoryName(name + 1) : true;
+  }
+
+  static constexpr bool StringEq(const char* a, const char* b) {
+    return *a != *b ? false
+                    : (!*a || !*b) ? (*a == *b) : StringEq(a + 1, b + 1);
+  }
+
+  const Category* const categories_;
+  const size_t category_count_;
+  std::atomic<uint8_t>* const state_storage_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_CATEGORY_REGISTRY_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/track_event/track_event_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TrackEventConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TrackEventConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDisabledCategoriesFieldNumber = 1,
+    kEnabledCategoriesFieldNumber = 2,
+    kDisabledTagsFieldNumber = 3,
+    kEnabledTagsFieldNumber = 4,
+    kDisableIncrementalTimestampsFieldNumber = 5,
+    kTimestampUnitMultiplierFieldNumber = 6,
+    kFilterDebugAnnotationsFieldNumber = 7,
+    kEnableThreadTimeSamplingFieldNumber = 8,
+    kFilterDynamicEventNamesFieldNumber = 9,
+  };
+
+  TrackEventConfig();
+  ~TrackEventConfig() override;
+  TrackEventConfig(TrackEventConfig&&) noexcept;
+  TrackEventConfig& operator=(TrackEventConfig&&);
+  TrackEventConfig(const TrackEventConfig&);
+  TrackEventConfig& operator=(const TrackEventConfig&);
+  bool operator==(const TrackEventConfig&) const;
+  bool operator!=(const TrackEventConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& disabled_categories() const { return disabled_categories_; }
+  std::vector<std::string>* mutable_disabled_categories() { return &disabled_categories_; }
+  int disabled_categories_size() const { return static_cast<int>(disabled_categories_.size()); }
+  void clear_disabled_categories() { disabled_categories_.clear(); }
+  void add_disabled_categories(std::string value) { disabled_categories_.emplace_back(value); }
+  std::string* add_disabled_categories() { disabled_categories_.emplace_back(); return &disabled_categories_.back(); }
+
+  const std::vector<std::string>& enabled_categories() const { return enabled_categories_; }
+  std::vector<std::string>* mutable_enabled_categories() { return &enabled_categories_; }
+  int enabled_categories_size() const { return static_cast<int>(enabled_categories_.size()); }
+  void clear_enabled_categories() { enabled_categories_.clear(); }
+  void add_enabled_categories(std::string value) { enabled_categories_.emplace_back(value); }
+  std::string* add_enabled_categories() { enabled_categories_.emplace_back(); return &enabled_categories_.back(); }
+
+  const std::vector<std::string>& disabled_tags() const { return disabled_tags_; }
+  std::vector<std::string>* mutable_disabled_tags() { return &disabled_tags_; }
+  int disabled_tags_size() const { return static_cast<int>(disabled_tags_.size()); }
+  void clear_disabled_tags() { disabled_tags_.clear(); }
+  void add_disabled_tags(std::string value) { disabled_tags_.emplace_back(value); }
+  std::string* add_disabled_tags() { disabled_tags_.emplace_back(); return &disabled_tags_.back(); }
+
+  const std::vector<std::string>& enabled_tags() const { return enabled_tags_; }
+  std::vector<std::string>* mutable_enabled_tags() { return &enabled_tags_; }
+  int enabled_tags_size() const { return static_cast<int>(enabled_tags_.size()); }
+  void clear_enabled_tags() { enabled_tags_.clear(); }
+  void add_enabled_tags(std::string value) { enabled_tags_.emplace_back(value); }
+  std::string* add_enabled_tags() { enabled_tags_.emplace_back(); return &enabled_tags_.back(); }
+
+  bool has_disable_incremental_timestamps() const { return _has_field_[5]; }
+  bool disable_incremental_timestamps() const { return disable_incremental_timestamps_; }
+  void set_disable_incremental_timestamps(bool value) { disable_incremental_timestamps_ = value; _has_field_.set(5); }
+
+  bool has_timestamp_unit_multiplier() const { return _has_field_[6]; }
+  uint64_t timestamp_unit_multiplier() const { return timestamp_unit_multiplier_; }
+  void set_timestamp_unit_multiplier(uint64_t value) { timestamp_unit_multiplier_ = value; _has_field_.set(6); }
+
+  bool has_filter_debug_annotations() const { return _has_field_[7]; }
+  bool filter_debug_annotations() const { return filter_debug_annotations_; }
+  void set_filter_debug_annotations(bool value) { filter_debug_annotations_ = value; _has_field_.set(7); }
+
+  bool has_enable_thread_time_sampling() const { return _has_field_[8]; }
+  bool enable_thread_time_sampling() const { return enable_thread_time_sampling_; }
+  void set_enable_thread_time_sampling(bool value) { enable_thread_time_sampling_ = value; _has_field_.set(8); }
+
+  bool has_filter_dynamic_event_names() const { return _has_field_[9]; }
+  bool filter_dynamic_event_names() const { return filter_dynamic_event_names_; }
+  void set_filter_dynamic_event_names(bool value) { filter_dynamic_event_names_ = value; _has_field_.set(9); }
+
+ private:
+  std::vector<std::string> disabled_categories_;
+  std::vector<std::string> enabled_categories_;
+  std::vector<std::string> disabled_tags_;
+  std::vector<std::string> enabled_tags_;
+  bool disable_incremental_timestamps_{};
+  uint64_t timestamp_unit_multiplier_{};
+  bool filter_debug_annotations_{};
+  bool enable_thread_time_sampling_{};
+  bool filter_dynamic_event_names_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<10> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_CPP_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/base/template_util.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_legacy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/write_track_event_args.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
+// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
+// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#include <type_traits>
+
+namespace perfetto {
+
+namespace {
+
+class StopArgsImpl : public DataSourceBase::StopArgs {
+ public:
+  // HandleAsynchronously() can optionally be called to defer the tracing
+  // session stop and write track events just before stopping. This function
+  // returns a closure that must be invoked after the last track events have
+  // been emitted. The caller also needs to explicitly call
+  // TrackEvent::Flush() because no other implicit flushes will happen after
+  // the stop signal.
+  // See the comment in include/perfetto/tracing/data_source.h for more info.
+  std::function<void()> HandleStopAsynchronously() const override {
+    auto closure = std::move(async_stop_closure);
+    async_stop_closure = std::function<void()>();
+    return closure;
+  }
+
+  mutable std::function<void()> async_stop_closure;
+};
+
+}  // namespace
+
+// A function for converting an abstract timestamp into a
+// perfetto::TraceTimestamp struct. By specialising this template and defining
+// static ConvertTimestampToTraceTimeNs function in it the user can register
+// additional timestamp types. The return value should specify the
+// clock domain used by the timestamp as well as its value.
+//
+// The supported clock domains are the ones described in
+// perfetto.protos.ClockSnapshot. However, custom clock IDs (>=64) are
+// reserved for internal use by the SDK for the time being.
+// The timestamp value should be in nanoseconds regardless of the clock domain.
+template <typename T>
+struct TraceTimestampTraits;
+
+// A pass-through implementation for raw uint64_t nanosecond timestamps.
+template <>
+struct TraceTimestampTraits<uint64_t> {
+  static inline TraceTimestamp ConvertTimestampToTraceTimeNs(
+      const uint64_t& timestamp) {
+    return {static_cast<uint32_t>(internal::TrackEventInternal::GetClockId()), timestamp};
+  }
+};
+
+// A pass-through implementation for the trace timestamp structure.
+template <>
+struct TraceTimestampTraits<TraceTimestamp> {
+  static inline TraceTimestamp ConvertTimestampToTraceTimeNs(
+      const TraceTimestamp& timestamp) {
+    return timestamp;
+  }
+};
+
+namespace internal {
+namespace {
+
+// Checks if |T| is a valid track.
+template <typename T>
+static constexpr bool IsValidTrack() {
+  return std::is_convertible<T, Track>::value;
+}
+
+// Checks if |T| is a valid non-counter track.
+template <typename T>
+static constexpr bool IsValidNormalTrack() {
+  return std::is_convertible<T, Track>::value &&
+         !std::is_convertible<T, CounterTrack>::value;
+}
+
+// Because the user can use arbitrary timestamp types, we can't compare against
+// any known base type here. Instead, we check that a track or a trace lambda
+// isn't being interpreted as a timestamp.
+template <typename T,
+          typename CanBeConvertedToNsCheck = decltype(
+              ::perfetto::TraceTimestampTraits<typename base::remove_cvref_t<
+                  T>>::ConvertTimestampToTraceTimeNs(std::declval<T>())),
+          typename NotTrackCheck =
+              typename std::enable_if<!IsValidNormalTrack<T>()>::type,
+          typename NotLambdaCheck =
+              typename std::enable_if<!IsValidTraceLambda<T>()>::type>
+static constexpr bool IsValidTimestamp() {
+  return true;
+}
+
+// Taken from C++17
+template <typename...>
+using void_t = void;
+
+// Returns true iff `GetStaticString(T)` is defined OR T == DynamicString.
+template <typename T, typename = void>
+struct IsValidEventNameType
+    : std::is_same<perfetto::DynamicString, typename std::decay<T>::type> {};
+
+template <typename T>
+struct IsValidEventNameType<
+    T,
+    void_t<decltype(GetStaticString(std::declval<T>()))>> : std::true_type {};
+
+template <typename T>
+inline void ValidateEventNameType() {
+  static_assert(
+      IsValidEventNameType<T>::value,
+      "Event names must be static strings. To use dynamic event names, see "
+      "https://perfetto.dev/docs/instrumentation/"
+      "track-events#dynamic-event-names");
+}
+
+inline bool UnorderedEqual(std::vector<std::string> vec1,
+                           std::vector<std::string> vec2) {
+  std::sort(vec1.begin(), vec1.end());
+  vec1.erase(std::unique(vec1.begin(), vec1.end()), vec1.end());
+  std::sort(vec2.begin(), vec2.end());
+  vec2.erase(std::unique(vec2.begin(), vec2.end()), vec2.end());
+  return vec1 == vec2;
+}
+
+}  // namespace
+
+inline ::perfetto::DynamicString DecayEventNameType(
+    ::perfetto::DynamicString name) {
+  return name;
+}
+
+inline ::perfetto::StaticString DecayEventNameType(
+    ::perfetto::StaticString name) {
+  return name;
+}
+
+// Convert all static strings of different length to StaticString to avoid
+// unnecessary template instantiations.
+inline ::perfetto::StaticString DecayEventNameType(const char* name) {
+  return ::perfetto::StaticString{name};
+}
+
+// Traits for dynamic categories.
+template <typename CategoryType>
+struct CategoryTraits {
+  static constexpr bool kIsDynamic = true;
+  static constexpr const Category* GetStaticCategory(
+      const TrackEventCategoryRegistry*,
+      const CategoryType&) {
+    return nullptr;
+  }
+  static size_t GetStaticIndex(const CategoryType&) {
+    PERFETTO_DCHECK(false);  // Not reached.
+    return TrackEventCategoryRegistry::kDynamicCategoryIndex;
+  }
+  static DynamicCategory GetDynamicCategory(const CategoryType& category) {
+    return DynamicCategory{category};
+  }
+};
+
+// Traits for static categories.
+template <>
+struct CategoryTraits<size_t> {
+  static constexpr bool kIsDynamic = false;
+  static const Category* GetStaticCategory(
+      const TrackEventCategoryRegistry* registry,
+      size_t category_index) {
+    return registry->GetCategory(category_index);
+  }
+  static constexpr size_t GetStaticIndex(size_t category_index) {
+    return category_index;
+  }
+  static DynamicCategory GetDynamicCategory(size_t) {
+    PERFETTO_DCHECK(false);  // Not reached.
+    return DynamicCategory();
+  }
+};
+
+struct TrackEventDataSourceTraits : public perfetto::DefaultDataSourceTraits {
+  using IncrementalStateType = TrackEventIncrementalState;
+  using TlsStateType = TrackEventTlsState;
+
+  // Use a one shared TLS slot so that all track event data sources write into
+  // the same sequence and share interning dictionaries.
+  static DataSourceThreadLocalState* GetDataSourceTLS(DataSourceStaticState*,
+                                                      TracingTLS* root_tls) {
+    return &root_tls->track_event_tls;
+  }
+};
+
+// A generic track event data source which is instantiated once per track event
+// category namespace.
+template <typename DerivedDataSource,
+          const TrackEventCategoryRegistry* Registry>
+class TrackEventDataSource
+    : public DataSource<DerivedDataSource, TrackEventDataSourceTraits> {
+  using Base = DataSource<DerivedDataSource, TrackEventDataSourceTraits>;
+
+ public:
+  static constexpr bool kRequiresCallbacksUnderLock = false;
+
+  // Add or remove a session observer for this track event data source. The
+  // observer will be notified about started and stopped tracing sessions.
+  // Returns |true| if the observer was successfully added (i.e., the maximum
+  // number of observers wasn't exceeded).
+  static bool AddSessionObserver(TrackEventSessionObserver* observer) {
+    return TrackEventInternal::AddSessionObserver(*Registry, observer);
+  }
+
+  static void RemoveSessionObserver(TrackEventSessionObserver* observer) {
+    TrackEventInternal::RemoveSessionObserver(*Registry, observer);
+  }
+
+  // DataSource implementation.
+  void OnSetup(const DataSourceBase::SetupArgs& args) override {
+    auto config_raw = args.config->track_event_config_raw();
+    bool ok = config_.ParseFromArray(config_raw.data(), config_raw.size());
+    PERFETTO_DCHECK(ok);
+    TrackEventInternal::EnableTracing(*Registry, config_, args);
+  }
+
+  void OnStart(const DataSourceBase::StartArgs& args) override {
+    TrackEventInternal::OnStart(*Registry, args);
+  }
+
+  void OnStop(const DataSourceBase::StopArgs& args) override {
+    auto outer_stop_closure = args.HandleStopAsynchronously();
+    StopArgsImpl inner_stop_args{};
+    uint32_t internal_instance_index = args.internal_instance_index;
+    inner_stop_args.internal_instance_index = internal_instance_index;
+    inner_stop_args.async_stop_closure = [internal_instance_index,
+                                          outer_stop_closure] {
+      TrackEventInternal::DisableTracing(*Registry, internal_instance_index);
+      outer_stop_closure();
+    };
+
+    TrackEventInternal::OnStop(*Registry, inner_stop_args);
+
+    // If inner_stop_args.HandleStopAsynchronously() hasn't been called,
+    // run the async closure here.
+    if (inner_stop_args.async_stop_closure)
+      std::move(inner_stop_args.async_stop_closure)();
+  }
+
+  void WillClearIncrementalState(
+      const DataSourceBase::ClearIncrementalStateArgs& args) override {
+    TrackEventInternal::WillClearIncrementalState(*Registry, args);
+  }
+
+  // In Chrome, startup sessions are propagated from the browser process to
+  // child processes using command-line flags. Command-line flags can only
+  // convey the category filter and privacy settings, so we use only those
+  // to determine which startup sessions to adopt.
+  // TODO(khokhlov): After Chrome is able to propagate the entire config to the
+  // child process, we can make this comparison more strict by only clearing
+  // selected fields and comparing everything else. One specific thing to keep
+  // in mind is to clear the |convert_to_legacy_json| field, because Telemetry
+  // initiates tracing with proto format, but in some cases adopts the tracing
+  // session later via devtools which expect json format.
+  bool CanAdoptStartupSession(const DataSourceConfig& startup_config,
+                              const DataSourceConfig& service_config) override {
+    if (startup_config.track_event_config_raw().empty() ||
+        service_config.track_event_config_raw().empty()) {
+      return false;
+    }
+
+    protos::gen::TrackEventConfig startup_te_cfg;
+    startup_te_cfg.ParseFromString(startup_config.track_event_config_raw());
+    protos::gen::TrackEventConfig service_te_cfg;
+    service_te_cfg.ParseFromString(service_config.track_event_config_raw());
+
+    if (!UnorderedEqual(startup_te_cfg.enabled_categories(),
+                        service_te_cfg.enabled_categories())) {
+      return false;
+    }
+    if (!UnorderedEqual(startup_te_cfg.disabled_categories(),
+                        service_te_cfg.disabled_categories())) {
+      return false;
+    }
+    if (!UnorderedEqual(startup_te_cfg.enabled_tags(),
+                        service_te_cfg.enabled_tags())) {
+      return false;
+    }
+    if (!UnorderedEqual(startup_te_cfg.disabled_tags(),
+                        service_te_cfg.disabled_tags())) {
+      return false;
+    }
+    if (startup_te_cfg.filter_debug_annotations() !=
+        service_te_cfg.filter_debug_annotations()) {
+      return false;
+    }
+    if (startup_te_cfg.filter_dynamic_event_names() !=
+        service_te_cfg.filter_dynamic_event_names()) {
+      return false;
+    }
+
+    return true;
+  }
+
+  static void Flush() {
+    Base::template Trace([](typename Base::TraceContext ctx) { ctx.Flush(); });
+  }
+
+  // Determine if *any* tracing category is enabled.
+  static bool IsEnabled() {
+    bool enabled = false;
+    Base::template CallIfEnabled(
+        [&](uint32_t /*instances*/) { enabled = true; });
+    return enabled;
+  }
+
+  // Determine if tracing for the given static category is enabled.
+  static bool IsCategoryEnabled(size_t category_index) {
+    return Registry->GetCategoryState(category_index)
+        ->load(std::memory_order_relaxed);
+  }
+
+  // Determine if tracing for the given dynamic category is enabled.
+  static bool IsDynamicCategoryEnabled(
+      const DynamicCategory& dynamic_category) {
+    bool enabled = false;
+    Base::template Trace([&](typename Base::TraceContext ctx) {
+      enabled = enabled || IsDynamicCategoryEnabled(&ctx, dynamic_category);
+    });
+    return enabled;
+  }
+
+  // This is the inlined entrypoint for all track event trace points. It tries
+  // to be as lightweight as possible in terms of instructions and aims to
+  // compile down to an unlikely conditional jump to the actual trace writing
+  // function.
+  template <typename Callback>
+  static void CallIfCategoryEnabled(size_t category_index,
+                                    Callback callback) PERFETTO_ALWAYS_INLINE {
+    Base::template CallIfEnabled<CategoryTracePointTraits>(
+        [&callback](uint32_t instances) { callback(instances); },
+        {category_index});
+  }
+
+  // The following methods forward all arguments to TraceForCategoryBody
+  // while casting string constants to const char* and integer arguments to
+  // int64_t, uint64_t or bool.
+  template <typename CategoryType,
+            typename EventNameType,
+            typename... Arguments>
+  static void TraceForCategory(uint32_t instances,
+                               const CategoryType& category,
+                               const EventNameType& name,
+                               perfetto::protos::pbzero::TrackEvent::Type type,
+                               Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    TraceForCategoryBody(instances, DecayStrType(category), DecayStrType(name),
+                         type, DecayArgType(args)...);
+  }
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategoryLegacy(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    TraceForCategoryLegacyBody(instances, DecayStrType(category),
+                               DecayStrType(event_name), type, track, phase,
+                               flags, DecayArgType(args)...);
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryLegacy(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    TraceForCategoryLegacyBody(instances, DecayStrType(category),
+                               DecayStrType(event_name), type, track, phase,
+                               flags, timestamp, DecayArgType(args)...);
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename ThreadIdType,
+            typename LegacyIdType,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategoryLegacyWithId(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      ThreadIdType thread_id,
+      LegacyIdType legacy_id,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    TraceForCategoryLegacyWithIdBody(
+        instances, DecayStrType(category), DecayStrType(event_name), type,
+        track, phase, flags, thread_id, legacy_id, DecayArgType(args)...);
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename ThreadIdType,
+            typename LegacyIdType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryLegacyWithId(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      ThreadIdType thread_id,
+      LegacyIdType legacy_id,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    TraceForCategoryLegacyWithIdBody(instances, DecayStrType(category),
+                                     DecayStrType(event_name), type, track,
+                                     phase, flags, thread_id, legacy_id,
+                                     timestamp, DecayArgType(args)...);
+  }
+#endif
+
+  // Initialize the track event library. Should be called before tracing is
+  // enabled.
+  static bool Register() {
+    // Registration is performed out-of-line so users don't need to depend on
+    // DataSourceDescriptor C++ bindings.
+    return TrackEventInternal::Initialize(
+        *Registry,
+        [](const DataSourceDescriptor& dsd) { return Base::Register(dsd); });
+  }
+
+  // Record metadata about different types of timeline tracks. See Track.
+  static void SetTrackDescriptor(const Track& track,
+                                 const protos::gen::TrackDescriptor& desc) {
+    PERFETTO_DCHECK(track.uuid == desc.uuid());
+    TrackRegistry::Get()->UpdateTrack(track, desc.SerializeAsString());
+    Base::template Trace([&](typename Base::TraceContext ctx) {
+      TrackEventInternal::WriteTrackDescriptor(
+          track, ctx.tls_inst_->trace_writer.get(), ctx.GetIncrementalState(),
+          *ctx.GetCustomTlsState(), TrackEventInternal::GetTraceTime());
+    });
+  }
+
+  // DEPRECATED. Only kept for backwards compatibility.
+  static void SetTrackDescriptor(
+      const Track& track,
+      std::function<void(protos::pbzero::TrackDescriptor*)> callback) {
+    SetTrackDescriptorImpl(track, std::move(callback));
+  }
+
+  // DEPRECATED. Only kept for backwards compatibility.
+  static void SetProcessDescriptor(
+      std::function<void(protos::pbzero::TrackDescriptor*)> callback,
+      const ProcessTrack& track = ProcessTrack::Current()) {
+    SetTrackDescriptorImpl(std::move(track), std::move(callback));
+  }
+
+  // DEPRECATED. Only kept for backwards compatibility.
+  static void SetThreadDescriptor(
+      std::function<void(protos::pbzero::TrackDescriptor*)> callback,
+      const ThreadTrack& track = ThreadTrack::Current()) {
+    SetTrackDescriptorImpl(std::move(track), std::move(callback));
+  }
+
+  static void EraseTrackDescriptor(const Track& track) {
+    TrackRegistry::Get()->EraseTrack(track);
+  }
+
+  // Returns the current trace timestamp in nanoseconds. Note the returned
+  // timebase may vary depending on the platform, but will always match the
+  // timestamps recorded by track events (see GetTraceClockId).
+  static uint64_t GetTraceTimeNs() { return TrackEventInternal::GetTimeNs(); }
+
+  // Returns the type of clock used by GetTraceTimeNs().
+  static constexpr protos::pbzero::BuiltinClock GetTraceClockId() {
+    return TrackEventInternal::GetClockId();
+  }
+
+  const protos::gen::TrackEventConfig& GetConfig() const { return config_; }
+
+ private:
+  // The DecayStrType method is used to avoid unnecessary instantiations of
+  // templates on string constants of different sizes. Without it, strings
+  // of different lengths have different types: char[10], char[15] etc.
+  // DecayStrType forwards all types of arguments as is, with the exception
+  // of string constants which are all cast to const char*. This allows to
+  // avoid extra instantiations of TraceForCategory templates.
+  template <typename T>
+  static T&& DecayStrType(T&& t) {
+    return std::forward<T>(t);
+  }
+
+  static const char* DecayStrType(const char* t) { return t; }
+
+  // The DecayArgType method is used to avoid unnecessary instantiations of
+  // templates on:
+  // * string constants of different sizes.
+  // * primitive of different constness (or references).
+  // This avoids extra instantiations of TraceForCategory templates.
+  template <typename T>
+  static T&& DecayArgType(T&& t) {
+    return std::forward<T>(t);
+  }
+
+  static const char* DecayArgType(const char* s) { return s; }
+  static uint64_t DecayArgType(uint64_t u) { return u; }
+  static uint32_t DecayArgType(uint32_t u) { return u; }
+  static uint16_t DecayArgType(uint16_t u) { return u; }
+  static uint8_t DecayArgType(uint8_t u) { return u; }
+  static int64_t DecayArgType(int64_t i) { return i; }
+  static int32_t DecayArgType(int32_t i) { return i; }
+  static int16_t DecayArgType(int16_t i) { return i; }
+  static int8_t DecayArgType(int8_t i) { return i; }
+  static bool DecayArgType(bool b) { return b; }
+  static float DecayArgType(float f) { return f; }
+  static double DecayArgType(double f) { return f; }
+
+  // Once we've determined tracing to be enabled for this category, actually
+  // write a trace event onto this thread's default track. Outlined to avoid
+  // bloating code (mostly stack depth) at the actual trace point.
+  //
+  // The following combination of parameters is supported (in the given order):
+  // - Zero or one track,
+  // - Zero or one custom timestamp,
+  // - Arbitrary number of debug annotations.
+  // - Zero or one lambda.
+
+  // Trace point which does not take a track or timestamp.
+  template <typename CategoryType,
+            typename EventNameType,
+            typename... Arguments>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImplNoTimestamp(instances, category, event_name, type,
+                                    TrackEventInternal::kDefaultTrack,
+                                    std::forward<Arguments>(args)...);
+  }
+
+  // Trace point which takes a track, but not timestamp.
+  // NOTE: Here track should be captured using universal reference (TrackType&&)
+  // instead of const TrackType& to ensure that the proper overload is selected
+  // (otherwise the compiler will fail to disambiguate between adding const& and
+  // parsing track as a part of Arguments...).
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImplNoTimestamp(instances, category, event_name, type,
+                                    std::forward<TrackType>(track),
+                                    std::forward<Arguments>(args)...);
+  }
+
+  // Trace point which takes a timestamp, but not track.
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImpl(instances, category, event_name, type,
+                         TrackEventInternal::kDefaultTrack,
+                         std::forward<TimestampType>(timestamp),
+                         std::forward<Arguments>(args)...);
+  }
+
+  // Trace point which takes a timestamp and a track.
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImpl(instances, category, event_name, type,
+                         std::forward<TrackType>(track),
+                         std::forward<TimestampType>(timestamp),
+                         std::forward<Arguments>(args)...);
+  }
+
+  // Trace point with with a counter sample.
+  template <typename CategoryType, typename EventNameType, typename ValueType>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType&,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      CounterTrack track,
+      ValueType value) PERFETTO_ALWAYS_INLINE {
+    PERFETTO_DCHECK(type == perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER);
+    TraceForCategory(instances, category, /*name=*/nullptr, type, track,
+                     TrackEventInternal::GetTraceTime(), value);
+  }
+
+  // Trace point with with a timestamp and a counter sample.
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TimestampType = uint64_t,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type,
+            typename ValueType>
+  static void TraceForCategoryBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType&,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      CounterTrack track,
+      TimestampType timestamp,
+      ValueType value) PERFETTO_NO_INLINE {
+    PERFETTO_DCHECK(type == perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER);
+    TraceForCategoryImpl(
+        instances, category, /*name=*/nullptr, type, track, timestamp,
+        [&](EventContext event_ctx) {
+          if (std::is_integral<ValueType>::value) {
+            int64_t value_int64 = static_cast<int64_t>(value);
+            if (track.is_incremental()) {
+              TrackEventIncrementalState* incr_state =
+                  event_ctx.GetIncrementalState();
+              PERFETTO_DCHECK(incr_state != nullptr);
+              auto prv_value =
+                  incr_state->last_counter_value_per_track[track.uuid];
+              event_ctx.event()->set_counter_value(value_int64 - prv_value);
+              prv_value = value_int64;
+              incr_state->last_counter_value_per_track[track.uuid] = prv_value;
+            } else {
+              event_ctx.event()->set_counter_value(value_int64);
+            }
+          } else {
+            event_ctx.event()->set_double_counter_value(
+                static_cast<double>(value));
+          }
+        });
+  }
+
+// Additional trace points used in legacy macros.
+// It's possible to implement legacy macros using a common TraceForCategory,
+// by supplying a lambda that sets all necessary legacy fields. But this
+// results in a binary size bloat because every trace point generates its own
+// template instantiation with its own lambda. ICF can't eliminate those as
+// each lambda captures different variables and so the code is not completely
+// identical.
+// What we do instead is define additional TraceForCategoryLegacy templates
+// that take legacy arguments directly. Their instantiations can have the same
+// binary code for at least some macro invocations and so can be successfully
+// folded by the linker.
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategoryLegacyBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImplNoTimestamp(
+        instances, category, event_name, type, track,
+        [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {
+          using ::perfetto::internal::TrackEventLegacy;
+          TrackEventLegacy::WriteLegacyEvent(std::move(ctx), phase, flags,
+                                             args...);
+        });
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryLegacyBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImpl(
+        instances, category, event_name, type, track, timestamp,
+        [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {
+          using ::perfetto::internal::TrackEventLegacy;
+          TrackEventLegacy::WriteLegacyEvent(std::move(ctx), phase, flags,
+                                             args...);
+        });
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename ThreadIdType,
+            typename LegacyIdType,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type>
+  static void TraceForCategoryLegacyWithIdBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      ThreadIdType thread_id,
+      LegacyIdType legacy_id,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImplNoTimestamp(
+        instances, category, event_name, type, track,
+        [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {
+          using ::perfetto::internal::TrackEventLegacy;
+          ::perfetto::internal::LegacyTraceId trace_id{legacy_id};
+          TrackEventLegacy::WriteLegacyEventWithIdAndTid(
+              std::move(ctx), phase, flags, trace_id, thread_id, args...);
+        });
+  }
+
+  template <typename TrackType,
+            typename CategoryType,
+            typename EventNameType,
+            typename ThreadIdType,
+            typename LegacyIdType,
+            typename TimestampType = uint64_t,
+            typename... Arguments,
+            typename TrackTypeCheck = typename std::enable_if<
+                std::is_convertible<TrackType, Track>::value>::type,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type>
+  static void TraceForCategoryLegacyWithIdBody(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      TrackType&& track,
+      char phase,
+      uint32_t flags,
+      ThreadIdType thread_id,
+      LegacyIdType legacy_id,
+      TimestampType&& timestamp,
+      Arguments&&... args) PERFETTO_NO_INLINE {
+    TraceForCategoryImpl(
+        instances, category, event_name, type, track, timestamp,
+        [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {
+          using ::perfetto::internal::TrackEventLegacy;
+          ::perfetto::internal::LegacyTraceId trace_id{legacy_id};
+          TrackEventLegacy::WriteLegacyEventWithIdAndTid(
+              std::move(ctx), phase, flags, trace_id, thread_id, args...);
+        });
+  }
+#endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+  // Each category has its own enabled/disabled state, stored in the category
+  // registry.
+  struct CategoryTracePointTraits {
+    // Each trace point with a static category has an associated category index.
+    struct TracePointData {
+      size_t category_index;
+    };
+    // Called to get the enabled state bitmap of a given category.
+    // |data| is the trace point data structure given to
+    // DataSource::TraceWithInstances.
+    static constexpr std::atomic<uint8_t>* GetActiveInstances(
+        TracePointData data) {
+      return Registry->GetCategoryState(data.category_index);
+    }
+  };
+
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TrackType = Track,
+            typename TrackTypeCheck =
+                typename std::enable_if<IsValidTrack<TrackType>()>::type>
+  static perfetto::EventContext WriteTrackEventImpl(
+      typename Base::TraceContext& ctx,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track,
+      const TraceTimestamp& trace_timestamp) PERFETTO_ALWAYS_INLINE {
+    using CatTraits = CategoryTraits<CategoryType>;
+    const Category* static_category =
+        CatTraits::GetStaticCategory(Registry, category);
+
+    TrackEventTlsState& tls_state = *ctx.GetCustomTlsState();
+    TraceWriterBase* trace_writer = ctx.tls_inst_->trace_writer.get();
+    // Make sure incremental state is valid.
+    TrackEventIncrementalState* incr_state = ctx.GetIncrementalState();
+    TrackEventInternal::ResetIncrementalStateIfRequired(
+        trace_writer, incr_state, tls_state, trace_timestamp);
+
+    // Write the track descriptor before any event on the track.
+    if (track) {
+      TrackEventInternal::WriteTrackDescriptorIfNeeded(
+          track, trace_writer, incr_state, tls_state, trace_timestamp);
+    }
+
+    // Write the event itself.
+    bool on_current_thread_track =
+        (&track == &TrackEventInternal::kDefaultTrack);
+    auto event_ctx = TrackEventInternal::WriteEvent(
+        trace_writer, incr_state, tls_state, static_category, type,
+        trace_timestamp, on_current_thread_track);
+    // event name should be emitted with `TRACE_EVENT_BEGIN` macros
+    // but not with `TRACE_EVENT_END`.
+    if (type != protos::pbzero::TrackEvent::TYPE_SLICE_END) {
+      TrackEventInternal::WriteEventName(event_name, event_ctx, tls_state);
+    }
+    // Write dynamic categories (except for events that don't require
+    // categories). For counter events, the counter name (and optional
+    // category) is stored as part of the track descriptor instead being
+    // recorded with individual events.
+    if (CatTraits::kIsDynamic &&
+        type != protos::pbzero::TrackEvent::TYPE_SLICE_END &&
+        type != protos::pbzero::TrackEvent::TYPE_COUNTER) {
+      DynamicCategory dynamic_category =
+          CatTraits::GetDynamicCategory(category);
+      Category cat = Category::FromDynamicCategory(dynamic_category);
+      cat.ForEachGroupMember([&](const char* member_name, size_t name_size) {
+        event_ctx.event()->add_categories(member_name, name_size);
+        return true;
+      });
+    }
+    if (type == protos::pbzero::TrackEvent::TYPE_UNSPECIFIED) {
+      // Explicitly clear the track, so that the event is not associated
+      // with the default track, but instead uses the legacy mechanism
+      // based on the phase and pid/tid override.
+      event_ctx.event()->set_track_uuid(0);
+    } else if (!on_current_thread_track) {
+      // We emit these events using TrackDescriptors, and we cannot emit
+      // events on behalf of other processes using the TrackDescriptor
+      // format. Chrome is the only user of events with explicit process
+      // ids and currently only Chrome emits PHASE_MEMORY_DUMP events
+      // with an explicit process id, so we should be fine here.
+      // TODO(mohitms): Get rid of events with explicit process ids
+      // entirely.
+      event_ctx.event()->set_track_uuid(track.uuid);
+    }
+
+    return event_ctx;
+  }
+
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TrackType = Track,
+            typename TimestampType = uint64_t,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type,
+            typename TrackTypeCheck =
+                typename std::enable_if<IsValidTrack<TrackType>()>::type>
+  static perfetto::EventContext WriteTrackEvent(
+      typename Base::TraceContext& ctx,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track,
+      const TimestampType& timestamp) PERFETTO_NO_INLINE {
+    TraceTimestamp trace_timestamp = ::perfetto::TraceTimestampTraits<
+        TimestampType>::ConvertTimestampToTraceTimeNs(timestamp);
+    return WriteTrackEventImpl(ctx, category, event_name, type, track,
+                               trace_timestamp);
+  }
+
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TrackType = Track,
+            typename TrackTypeCheck =
+                typename std::enable_if<IsValidTrack<TrackType>()>::type>
+  static perfetto::EventContext WriteTrackEvent(
+      typename Base::TraceContext& ctx,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track) PERFETTO_NO_INLINE {
+    TraceTimestamp trace_timestamp = TrackEventInternal::GetTraceTime();
+    return WriteTrackEventImpl(ctx, category, event_name, type, track,
+                               trace_timestamp);
+  }
+
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TrackType = Track,
+            typename TimestampType = uint64_t,
+            typename TimestampTypeCheck = typename std::enable_if<
+                IsValidTimestamp<TimestampType>()>::type,
+            typename TrackTypeCheck =
+                typename std::enable_if<IsValidTrack<TrackType>()>::type,
+            typename... Arguments>
+  static void TraceForCategoryImpl(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track,
+      const TimestampType& timestamp,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    using CatTraits = CategoryTraits<CategoryType>;
+    TraceWithInstances(
+        instances, category, [&](typename Base::TraceContext ctx) {
+          // If this category is dynamic, first check whether it's enabled.
+          if (CatTraits::kIsDynamic &&
+              !IsDynamicCategoryEnabled(
+                  &ctx, CatTraits::GetDynamicCategory(category))) {
+            return;
+          }
+
+          auto event_ctx = WriteTrackEvent(ctx, category, event_name, type,
+                                           track, timestamp);
+          WriteTrackEventArgs(std::move(event_ctx),
+                              std::forward<Arguments>(args)...);
+        });
+  }
+
+  template <typename CategoryType,
+            typename EventNameType,
+            typename TrackType = Track,
+            typename TrackTypeCheck =
+                typename std::enable_if<IsValidTrack<TrackType>()>::type,
+            typename... Arguments>
+  static void TraceForCategoryImplNoTimestamp(
+      uint32_t instances,
+      const CategoryType& category,
+      const EventNameType& event_name,
+      perfetto::protos::pbzero::TrackEvent::Type type,
+      const TrackType& track,
+      Arguments&&... args) PERFETTO_ALWAYS_INLINE {
+    using CatTraits = CategoryTraits<CategoryType>;
+    TraceWithInstances(
+        instances, category, [&](typename Base::TraceContext ctx) {
+          // If this category is dynamic, first check whether it's enabled.
+          if (CatTraits::kIsDynamic &&
+              !IsDynamicCategoryEnabled(
+                  &ctx, CatTraits::GetDynamicCategory(category))) {
+            return;
+          }
+
+          auto event_ctx =
+              WriteTrackEvent(ctx, category, event_name, type, track);
+          WriteTrackEventArgs(std::move(event_ctx),
+                              std::forward<Arguments>(args)...);
+        });
+  }
+
+  template <typename CategoryType, typename Lambda>
+  static void TraceWithInstances(uint32_t instances,
+                                 const CategoryType& category,
+                                 Lambda lambda) PERFETTO_ALWAYS_INLINE {
+    using CatTraits = CategoryTraits<CategoryType>;
+    if (CatTraits::kIsDynamic) {
+      Base::template TraceWithInstances(instances, std::move(lambda));
+    } else {
+      Base::template TraceWithInstances<CategoryTracePointTraits>(
+          instances, std::move(lambda), {CatTraits::GetStaticIndex(category)});
+    }
+  }
+
+  // Records a track descriptor into the track descriptor registry and, if we
+  // are tracing, also mirrors the descriptor into the trace.
+  template <typename TrackType>
+  static void SetTrackDescriptorImpl(
+      const TrackType& track,
+      std::function<void(protos::pbzero::TrackDescriptor*)> callback) {
+    TrackRegistry::Get()->UpdateTrack(track, std::move(callback));
+    Base::template Trace([&](typename Base::TraceContext ctx) {
+      TrackEventInternal::WriteTrackDescriptor(
+          track, ctx.tls_inst_->trace_writer.get(), ctx.GetIncrementalState(),
+          *ctx.GetCustomTlsState(), TrackEventInternal::GetTraceTime());
+    });
+  }
+
+  // Determines if the given dynamic category is enabled, first by checking the
+  // per-trace writer cache or by falling back to computing it based on the
+  // trace config for the given session.
+  static bool IsDynamicCategoryEnabled(
+      typename Base::TraceContext* ctx,
+      const DynamicCategory& dynamic_category) {
+    auto incr_state = ctx->GetIncrementalState();
+    auto it = incr_state->dynamic_categories.find(dynamic_category.name);
+    if (it == incr_state->dynamic_categories.end()) {
+      // We haven't seen this category before. Let's figure out if it's enabled.
+      // This requires grabbing a lock to read the session's trace config.
+      auto ds = ctx->GetDataSourceLocked();
+      if (!ds) {
+        return false;
+      }
+      Category category{Category::FromDynamicCategory(dynamic_category)};
+      bool enabled = TrackEventInternal::IsCategoryEnabled(
+          *Registry, ds->config_, category);
+      // TODO(skyostil): Cap the size of |dynamic_categories|.
+      incr_state->dynamic_categories[dynamic_category.name] = enabled;
+      return enabled;
+    }
+    return it->second;
+  }
+
+  // Config for the current tracing session.
+  protos::gen::TrackEventConfig config_;
+};
+
+}  // namespace internal
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_DATA_SOURCE_H_
+// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_macros.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
+#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
+
+// This file contains underlying macros for the trace point track event
+// implementation. Perfetto API users typically don't need to use anything here
+// directly.
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/string_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
+
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC system_header
+#endif
+
+// Defines data structures for backing a category registry.
+//
+// Each category has one enabled/disabled bit per possible data source instance.
+// The bits are packed, i.e., each byte holds the state for instances. To
+// improve cache locality, the bits for each instance are stored separately from
+// the names of the categories:
+//
+//   byte 0                      byte 1
+//   (inst0, inst1, ..., inst7), (inst0, inst1, ..., inst7)
+//
+#define PERFETTO_INTERNAL_DECLARE_CATEGORIES(attrs, ...)                      \
+  namespace internal {                                                        \
+  constexpr ::perfetto::Category kCategories[] = {__VA_ARGS__};               \
+  constexpr size_t kCategoryCount =                                           \
+      sizeof(kCategories) / sizeof(kCategories[0]);                           \
+  /* The per-instance enable/disable state per category */                    \
+  attrs extern std::atomic<uint8_t> g_category_state_storage[kCategoryCount]; \
+  /* The category registry which mediates access to the above structures. */  \
+  /* The registry is used for two purposes: */                                \
+  /**/                                                                        \
+  /*    1) For looking up categories at build (constexpr) time. */            \
+  /*    2) For declaring the per-namespace TrackEvent data source. */         \
+  /**/                                                                        \
+  /* Because usage #1 requires a constexpr type and usage #2 requires an */   \
+  /* extern type (to avoid declaring a type based on a translation-unit */    \
+  /* variable), we need two separate copies of the registry with different */ \
+  /* storage specifiers. */                                                   \
+  /**/                                                                        \
+  /* Note that because of a Clang/Windows bug, the constexpr category */      \
+  /* registry isn't given the enabled/disabled state array. All access */     \
+  /* to the category states should therefore be done through the */           \
+  /* non-constexpr registry. See */                                           \
+  /* https://bugs.llvm.org/show_bug.cgi?id=51558 */                           \
+  /**/                                                                        \
+  /* TODO(skyostil): Unify these using a C++17 inline constexpr variable. */  \
+  constexpr ::perfetto::internal::TrackEventCategoryRegistry                  \
+      kConstExprCategoryRegistry(kCategoryCount, &kCategories[0], nullptr);   \
+  attrs extern const ::perfetto::internal::TrackEventCategoryRegistry         \
+      kCategoryRegistry;                                                      \
+  static_assert(kConstExprCategoryRegistry.ValidateCategories(),              \
+                "Invalid category names found");                              \
+  }  // namespace internal
+
+// In a .cc file, declares storage for each category's runtime state.
+#define PERFETTO_INTERNAL_CATEGORY_STORAGE(attrs)                      \
+  namespace internal {                                                 \
+  attrs std::atomic<uint8_t> g_category_state_storage[kCategoryCount]; \
+  attrs const ::perfetto::internal::TrackEventCategoryRegistry         \
+      kCategoryRegistry(kCategoryCount,                                \
+                        &kCategories[0],                               \
+                        &g_category_state_storage[0]);                 \
+  }  // namespace internal
+
+// Defines the TrackEvent data source for the current track event namespace.
+// `virtual ~TrackEvent` is added to avoid `-Wweak-vtables` warning.
+// Learn more : aosp/2019906
+#define PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE(attrs)               \
+  struct attrs TrackEvent : public ::perfetto::internal::TrackEventDataSource< \
+                                TrackEvent, &internal::kCategoryRegistry> {    \
+    virtual ~TrackEvent();                                                     \
+  }
+
+#define PERFETTO_INTERNAL_DEFINE_TRACK_EVENT_DATA_SOURCE() \
+  TrackEvent::~TrackEvent() = default;
+
+// At compile time, turns a category name represented by a static string into an
+// index into the current category registry. A build error will be generated if
+// the category hasn't been registered or added to the list of allowed dynamic
+// categories. See PERFETTO_DEFINE_CATEGORIES.
+#define PERFETTO_GET_CATEGORY_INDEX(category)                                \
+  PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry.Find( \
+      category,                                                              \
+      ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(category))
+
+// Generate a unique variable name with a given prefix.
+#define PERFETTO_INTERNAL_CONCAT2(a, b) a##b
+#define PERFETTO_INTERNAL_CONCAT(a, b) PERFETTO_INTERNAL_CONCAT2(a, b)
+#define PERFETTO_UID(prefix) PERFETTO_INTERNAL_CONCAT(prefix, __LINE__)
+
+// Efficiently determines whether tracing is enabled for the given category, and
+// if so, emits one trace event with the given arguments.
+#define PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(method, category, name, ...) \
+  do {                                                                         \
+    ::perfetto::internal::ValidateEventNameType<decltype(name)>();             \
+    namespace tns = PERFETTO_TRACK_EVENT_NAMESPACE;                            \
+    /* Compute the category index outside the lambda to work around a */       \
+    /* GCC 7 bug */                                                            \
+    constexpr auto PERFETTO_UID(                                               \
+        kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_) =               \
+        PERFETTO_GET_CATEGORY_INDEX(category);                                 \
+    if (::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(         \
+            category)) {                                                       \
+      tns::TrackEvent::CallIfEnabled(                                          \
+          [&](uint32_t instances) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {         \
+            tns::TrackEvent::method(instances, category, name, ##__VA_ARGS__); \
+          });                                                                  \
+    } else {                                                                   \
+      tns::TrackEvent::CallIfCategoryEnabled(                                  \
+          PERFETTO_UID(kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_), \
+          [&](uint32_t instances) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {         \
+            tns::TrackEvent::method(                                           \
+                instances,                                                     \
+                PERFETTO_UID(                                                  \
+                    kCatIndex_ADD_TO_PERFETTO_DEFINE_CATEGORIES_IF_FAILS_),    \
+                name, ##__VA_ARGS__);                                          \
+          });                                                                  \
+    }                                                                          \
+  } while (false)
+
+// This internal macro is unused from the repo now, but some improper usage
+// remain outside of the repo.
+// TODO(b/294800182): Remove this.
+#define PERFETTO_INTERNAL_TRACK_EVENT(...) \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(TraceForCategory, ##__VA_ARGS__)
+
+// C++17 doesn't like a move constructor being defined for the EventFinalizer
+// class but C++11 and MSVC doesn't compile without it being defined so support
+// both.
+#if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
+#define PERFETTO_INTERNAL_EVENT_FINALIZER_KEYWORD delete
+#else
+#define PERFETTO_INTERNAL_EVENT_FINALIZER_KEYWORD default
+#endif
+
+#define PERFETTO_INTERNAL_SCOPED_EVENT_FINALIZER(category)                    \
+  struct PERFETTO_UID(ScopedEvent) {                                          \
+    struct EventFinalizer {                                                   \
+      /* The parameter is an implementation detail. It allows the          */ \
+      /* anonymous struct to use aggregate initialization to invoke the    */ \
+      /* lambda (which emits the BEGIN event and returns an integer)       */ \
+      /* with the proper reference capture for any                         */ \
+      /* TrackEventArgumentFunction in |__VA_ARGS__|. This is required so  */ \
+      /* that the scoped event is exactly ONE line and can't escape the    */ \
+      /* scope if used in a single line if statement.                      */ \
+      EventFinalizer(...) {}                                                  \
+      ~EventFinalizer() { TRACE_EVENT_END(category); }                        \
+                                                                              \
+      EventFinalizer(const EventFinalizer&) = delete;                         \
+      inline EventFinalizer& operator=(const EventFinalizer&) = delete;       \
+                                                                              \
+      EventFinalizer(EventFinalizer&&) =                                      \
+          PERFETTO_INTERNAL_EVENT_FINALIZER_KEYWORD;                          \
+      EventFinalizer& operator=(EventFinalizer&&) = delete;                   \
+    } finalizer;                                                              \
+  }
+
+#define PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(category, name, ...) \
+  PERFETTO_INTERNAL_SCOPED_EVENT_FINALIZER(category)              \
+  PERFETTO_UID(scoped_event) {                                    \
+    [&]() {                                                       \
+      TRACE_EVENT_BEGIN(category, name, ##__VA_ARGS__);           \
+      return 0;                                                   \
+    }()                                                           \
+  }
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+// Required for TRACE_EVENT_WITH_FLOW legacy macros, which pass the bind_id as
+// id.
+#define PERFETTO_INTERNAL_SCOPED_LEGACY_TRACK_EVENT_WITH_ID(               \
+    category, name, track, flags, thread_id, id, ...)                      \
+  PERFETTO_INTERNAL_SCOPED_EVENT_FINALIZER(category)                       \
+  PERFETTO_UID(scoped_event) {                                             \
+    [&]() {                                                                \
+      PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(                           \
+          TraceForCategoryLegacyWithId, category, name,                    \
+          ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN, track, \
+          'B', flags, thread_id, id, ##__VA_ARGS__);                       \
+      return 0;                                                            \
+    }()                                                                    \
+  }
+#endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC) || \
+    PERFETTO_BUILDFLAG(PERFETTO_COMPILER_MSVC)
+// On GCC versions <9 there's a bug that prevents using captured constant
+// variables in constexpr evaluation inside a lambda:
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82643
+// TODO(khokhlov): Remove this fallback after Perfetto moves to a more recent
+// GCC version.
+#define PERFETTO_INTERNAL_CATEGORY_ENABLED(category)                           \
+  (::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory(category)     \
+       ? PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsDynamicCategoryEnabled( \
+             ::perfetto::DynamicCategory(category))                            \
+       : PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsCategoryEnabled(        \
+             PERFETTO_GET_CATEGORY_INDEX(category)))
+#else  // !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
+#define PERFETTO_INTERNAL_CATEGORY_ENABLED(category)                     \
+  [&]() -> bool {                                                        \
+    using PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent;                    \
+    using ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::IsDynamicCategory; \
+    constexpr auto PERFETTO_UID(index) =                                 \
+        PERFETTO_GET_CATEGORY_INDEX(category);                           \
+    constexpr auto PERFETTO_UID(dynamic) = IsDynamicCategory(category);  \
+    return PERFETTO_UID(dynamic)                                         \
+               ? TrackEvent::IsDynamicCategoryEnabled(                   \
+                     ::perfetto::DynamicCategory(category))              \
+               : TrackEvent::IsCategoryEnabled(PERFETTO_UID(index));     \
+  }()
+#endif  // !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
+
+// Emits an empty trace packet into the trace to ensure that the service can
+// safely read the last event from the trace buffer. This can be used to
+// periodically "flush" the last event on threads that don't support explicit
+// flushing of the shared memory buffer chunk when the tracing session stops
+// (e.g. thread pool workers in Chromium).
+//
+// This workaround is only required because the tracing service cannot safely
+// read the last trace packet from an incomplete SMB chunk (crbug.com/1021571
+// and b/162206162) when scraping the SMB. Adding an empty trace packet ensures
+// that all prior events can be scraped by the service.
+#define PERFETTO_INTERNAL_ADD_EMPTY_EVENT()                                \
+  do {                                                                     \
+    PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::Trace(                     \
+        [](PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::TraceContext ctx) { \
+          ctx.AddEmptyTracePacket();                                       \
+        });                                                                \
+  } while (false)
+
+#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_MACROS_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_macros.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/string_helpers.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+#include <type_traits>
+
+// This file contains a set of macros designed for instrumenting applications
+// with track event trace points. While the underlying TrackEvent API can also
+// be used directly, doing so efficiently requires some care (e.g., to avoid
+// evaluating arguments while tracing is disabled). These types of optimizations
+// are abstracted away by the macros below.
+//
+// ================
+// Quickstart guide
+// ================
+//
+//   To add track events to your application, first define your categories in,
+//   e.g., my_tracing.h:
+//
+//       PERFETTO_DEFINE_CATEGORIES(
+//           perfetto::Category("base"),
+//           perfetto::Category("v8"),
+//           perfetto::Category("cc"));
+//
+//   Then in a single .cc file, e.g., my_tracing.cc:
+//
+//       #include "my_tracing.h"
+//       PERFETTO_TRACK_EVENT_STATIC_STORAGE();
+//
+//   Finally, register track events at startup, after which you can record
+//   events with the TRACE_EVENT macros:
+//
+//       #include "my_tracing.h"
+//
+//       int main() {
+//         perfetto::TrackEvent::Register();
+//
+//         // A basic track event with just a name.
+//         TRACE_EVENT("category", "MyEvent");
+//
+//         // A track event with (up to two) debug annotations.
+//         TRACE_EVENT("category", "MyEvent", "parameter", 42);
+//
+//         // A track event with a strongly typed parameter.
+//         TRACE_EVENT("category", "MyEvent", [](perfetto::EventContext ctx) {
+//           ctx.event()->set_foo(42);
+//           ctx.event()->set_bar(.5f);
+//         });
+//       }
+//
+//  Note that track events must be nested consistently, i.e., the following is
+//  not allowed:
+//
+//    TRACE_EVENT_BEGIN("a", "bar", ...);
+//    TRACE_EVENT_BEGIN("b", "foo", ...);
+//    TRACE_EVENT_END("a");  // "foo" must be closed before "bar".
+//    TRACE_EVENT_END("b");
+//
+// ====================
+// Implementation notes
+// ====================
+//
+// The track event library consists of the following layers and components. The
+// classes the internal namespace shouldn't be considered part of the public
+// API.
+//                    .--------------------------------.
+//               .----|  TRACE_EVENT                   |----.
+//      write   |     |   - App instrumentation point  |     |  write
+//      event   |     '--------------------------------'     |  arguments
+//              V                                            V
+//  .----------------------------------.    .-----------------------------.
+//  | TrackEvent                       |    | EventContext                |
+//  |  - Registry of event categories  |    |  - One track event instance |
+//  '----------------------------------'    '-----------------------------'
+//              |                                            |
+//              |                                            | look up
+//              | is                                         | interning ids
+//              V                                            V
+//  .----------------------------------.    .-----------------------------.
+//  | internal::TrackEventDataSource   |    | TrackEventInternedDataIndex |
+//  | - Perfetto data source           |    | - Corresponds to a field in |
+//  | - Has TrackEventIncrementalState |    |   in interned_data.proto    |
+//  '----------------------------------'    '-----------------------------'
+//              |                  |                         ^
+//              |                  |       owns (1:many)     |
+//              | write event      '-------------------------'
+//              V
+//  .----------------------------------.
+//  | internal::TrackEventInternal     |
+//  | - Outlined code to serialize     |
+//  |   one track event                |
+//  '----------------------------------'
+//
+
+// DEPRECATED: Please use PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE to implement
+// multiple track event category sets in one program.
+//
+// Each compilation unit can be in exactly one track event namespace,
+// allowing the overall program to use multiple track event data sources and
+// category lists if necessary. Use this macro to select the namespace for the
+// current compilation unit.
+//
+// If the program uses multiple track event namespaces, category & track event
+// registration (see quickstart above) needs to happen for both namespaces
+// separately.
+
+#ifndef PERFETTO_TRACK_EVENT_NAMESPACE
+#define PERFETTO_TRACK_EVENT_NAMESPACE perfetto_track_event
+#endif
+
+// Deprecated; see perfetto::Category().
+#define PERFETTO_CATEGORY(name) \
+  ::perfetto::Category { #name }
+
+// Internal helpers for determining if a given category is defined at build or
+// runtime.
+namespace PERFETTO_TRACK_EVENT_NAMESPACE {
+namespace internal {
+
+// By default no statically defined categories are dynamic, but this can be
+// overridden with PERFETTO_DEFINE_TEST_CATEGORY_PREFIXES.
+template <typename... T>
+constexpr bool IsDynamicCategory(const char*) {
+  return false;
+}
+
+// Explicitly dynamic categories are always dynamic.
+constexpr bool IsDynamicCategory(const ::perfetto::DynamicCategory&) {
+  return true;
+}
+
+}  // namespace internal
+}  // namespace PERFETTO_TRACK_EVENT_NAMESPACE
+
+// Normally all categories are defined statically at build-time (see
+// PERFETTO_DEFINE_CATEGORIES). However, some categories are only used for
+// testing, and we shouldn't publish them to the tracing service or include them
+// in a production binary. Use this macro to define a list of prefixes for these
+// types of categories. Note that trace points using these categories will be
+// slightly less efficient compared to regular trace points.
+#define PERFETTO_DEFINE_TEST_CATEGORY_PREFIXES(...)                       \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                              \
+  namespace internal {                                                    \
+  template <>                                                             \
+  constexpr bool IsDynamicCategory(const char* name) {                    \
+    return ::perfetto::internal::IsStringInPrefixList(name, __VA_ARGS__); \
+  }                                                                       \
+  } /* namespace internal */                                              \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */                        \
+  PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
+
+// Register the set of available categories by passing a list of categories to
+// this macro: perfetto::Category("cat1"), perfetto::Category("cat2"), ...
+// `ns` is the name of the namespace in which the categories should be declared.
+// `attrs` are linkage attributes for the underlying data source. See
+// PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS.
+//
+// Implementation note: the extra namespace (PERFETTO_TRACK_EVENT_NAMESPACE) is
+// kept here only for backward compatibility.
+#define PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS(ns, attrs, ...) \
+  namespace ns {                                                           \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                               \
+  /* The list of category names */                                         \
+  PERFETTO_INTERNAL_DECLARE_CATEGORIES(attrs, __VA_ARGS__)                 \
+  /* The track event data source for this set of categories */             \
+  PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE(attrs);                \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE  */                        \
+  using PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent;                        \
+  } /* namespace ns */                                                     \
+  PERFETTO_DECLARE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(                  \
+      attrs, ns::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent,               \
+      ::perfetto::internal::TrackEventDataSourceTraits)
+
+// Register the set of available categories by passing a list of categories to
+// this macro: perfetto::Category("cat1"), perfetto::Category("cat2"), ...
+// `ns` is the name of the namespace in which the categories should be declared.
+#define PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE(ns, ...) \
+  PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE_WITH_ATTRS(    \
+      ns, PERFETTO_COMPONENT_EXPORT, __VA_ARGS__)
+
+// Make categories in a given namespace the default ones used by track events
+// for the current translation unit. Can only be used *once* in a given global
+// or namespace scope.
+#define PERFETTO_USE_CATEGORIES_FROM_NAMESPACE(ns)                         \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                               \
+  using ::ns::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent;                  \
+  namespace internal {                                                     \
+  using ::ns::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry; \
+  using ::ns::PERFETTO_TRACK_EVENT_NAMESPACE::internal::                   \
+      kConstExprCategoryRegistry;                                          \
+  } /* namespace internal */                                               \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */                         \
+  PERFETTO_INTERNAL_SWALLOW_SEMICOLON()
+
+// Make categories in a given namespace the default ones used by track events
+// for the current block scope. Can only be used in a function or block scope.
+#define PERFETTO_USE_CATEGORIES_FROM_NAMESPACE_SCOPED(ns) \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE = ns::PERFETTO_TRACK_EVENT_NAMESPACE
+
+// Register categories in the default (global) namespace. Warning: only one set
+// of global categories can be defined in a single program. Create namespaced
+// categories with PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE to work around this
+// limitation.
+#define PERFETTO_DEFINE_CATEGORIES(...)                           \
+  PERFETTO_DEFINE_CATEGORIES_IN_NAMESPACE(perfetto, __VA_ARGS__); \
+  PERFETTO_USE_CATEGORIES_FROM_NAMESPACE(perfetto)
+
+// Allocate storage for each category by using this macro once per track event
+// namespace. `ns` is the name of the namespace in which the categories should
+// be declared and `attrs` specify linkage attributes for the data source.
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE_WITH_ATTRS(ns, attrs) \
+  namespace ns {                                                               \
+  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                                   \
+  PERFETTO_INTERNAL_CATEGORY_STORAGE(attrs)                                    \
+  PERFETTO_INTERNAL_DEFINE_TRACK_EVENT_DATA_SOURCE()                           \
+  } /* namespace PERFETTO_TRACK_EVENT_NAMESPACE */                             \
+  } /* namespace ns */                                                         \
+  PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS_WITH_ATTRS(                       \
+      attrs, ns::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent,                   \
+      ::perfetto::internal::TrackEventDataSourceTraits)
+
+// Allocate storage for each category by using this macro once per track event
+// namespace.
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE(ns)   \
+  PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE_WITH_ATTRS( \
+      ns, PERFETTO_COMPONENT_EXPORT)
+
+// Allocate storage for each category by using this macro once per track event
+// namespace.
+#define PERFETTO_TRACK_EVENT_STATIC_STORAGE() \
+  PERFETTO_TRACK_EVENT_STATIC_STORAGE_IN_NAMESPACE(perfetto)
+
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC system_header
+#endif
+
+// Begin a slice under |category| with the title |name|. Both strings must be
+// static constants. The track event is only recorded if |category| is enabled
+// for a tracing session.
+//
+// The slice is thread-scoped (i.e., written to the default track of the current
+// thread) unless overridden with a custom track object (see Track).
+//
+// |name| must be a string with static lifetime (i.e., the same
+// address must not be used for a different event name in the future). If you
+// want to use a dynamically allocated name, do this:
+//
+//  TRACE_EVENT("category", nullptr, [&](perfetto::EventContext ctx) {
+//    ctx.event()->set_name(dynamic_name);
+//  });
+//
+// The following optional arguments can be passed to `TRACE_EVENT` to add extra
+// information to events:
+//
+// TRACE_EVENT("cat", "name"[, track][, timestamp]
+//                          [, "debug_name1", debug_value1]
+//                          [, "debug_name2", debug_value2]
+//                          ...
+//                          [, "debug_nameN", debug_valueN]
+//                          [, lambda]);
+//
+// Some examples of valid combinations:
+//
+// 1. A lambda for writing custom TrackEvent fields:
+//
+//   TRACE_EVENT("category", "Name", [&](perfetto::EventContext ctx) {
+//     ctx.event()->set_custom_value(...);
+//   });
+//
+// 2. A timestamp and a lambda:
+//
+//   TRACE_EVENT("category", "Name", time_in_nanoseconds,
+//       [&](perfetto::EventContext ctx) {
+//     ctx.event()->set_custom_value(...);
+//   });
+//
+//   |time_in_nanoseconds| should be an uint64_t by default. To support custom
+//   timestamp types,
+//   |perfetto::TraceTimestampTraits<T>::ConvertTimestampToTraceTimeNs|
+//   should be defined. See |ConvertTimestampToTraceTimeNs| for more details.
+//
+// 3. Arbitrary number of debug annotations:
+//
+//   TRACE_EVENT("category", "Name", "arg", value);
+//   TRACE_EVENT("category", "Name", "arg", value, "arg2", value2);
+//   TRACE_EVENT("category", "Name", "arg", value, "arg2", value2,
+//                                   "arg3", value3);
+//
+//   See |TracedValue| for recording custom types as debug annotations.
+//
+// 4. Arbitrary number of debug annotations and a lambda:
+//
+//   TRACE_EVENT("category", "Name", "arg", value,
+//       [&](perfetto::EventContext ctx) {
+//     ctx.event()->set_custom_value(...);
+//   });
+//
+// 5. An overridden track:
+//
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234));
+//
+//   See |Track| for other types of tracks which may be used.
+//
+// 6. A track and a lambda:
+//
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234),
+//       [&](perfetto::EventContext ctx) {
+//     ctx.event()->set_custom_value(...);
+//   });
+//
+// 7. A track and a timestamp:
+//
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234),
+//       time_in_nanoseconds);
+//
+// 8. A track, a timestamp and a lambda:
+//
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234),
+//       time_in_nanoseconds, [&](perfetto::EventContext ctx) {
+//     ctx.event()->set_custom_value(...);
+//   });
+//
+// 9. A track and an arbitrary number of debug annotions:
+//
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234),
+//               "arg", value);
+//   TRACE_EVENT("category", "Name", perfetto::Track(1234),
+//               "arg", value, "arg2", value2);
+//
+#define TRACE_EVENT_BEGIN(category, name, ...)        \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(          \
+      TraceForCategory, category,                     \
+      ::perfetto::internal::DecayEventNameType(name), \
+      ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN, ##__VA_ARGS__)
+
+// End a slice under |category|.
+#define TRACE_EVENT_END(category, ...)              \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(        \
+      TraceForCategory, category, /*name=*/nullptr, \
+      ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END, ##__VA_ARGS__)
+
+// Begin a slice which gets automatically closed when going out of scope.
+#define TRACE_EVENT(category, name, ...) \
+  PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(  \
+      category, ::perfetto::internal::DecayEventNameType(name), ##__VA_ARGS__)
+
+// Emit a slice which has zero duration.
+#define TRACE_EVENT_INSTANT(category, name, ...)      \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(          \
+      TraceForCategory, category,                     \
+      ::perfetto::internal::DecayEventNameType(name), \
+      ::perfetto::protos::pbzero::TrackEvent::TYPE_INSTANT, ##__VA_ARGS__)
+
+// Efficiently determine if the given static or dynamic trace category or
+// category group is enabled for tracing.
+#define TRACE_EVENT_CATEGORY_ENABLED(category) \
+  PERFETTO_INTERNAL_CATEGORY_ENABLED(category)
+
+// Time-varying numeric data can be recorded with the TRACE_COUNTER macro:
+//
+//   TRACE_COUNTER("cat", counter_track[, timestamp], value);
+//
+// For example, to record a single value for a counter called "MyCounter":
+//
+//   TRACE_COUNTER("category", "MyCounter", 1234.5);
+//
+// This data is displayed as a counter track in the Perfetto UI.
+//
+// Both integer and floating point counter values are supported. Counters can
+// also be annotated with additional information such as units, for example, for
+// tracking the rendering framerate in terms of frames per second or "fps":
+//
+//   TRACE_COUNTER("category", perfetto::CounterTrack("Framerate", "fps"), 120);
+//
+// As another example, a memory counter that records bytes but accepts samples
+// as kilobytes (to reduce trace binary size) can be defined like this:
+//
+//   perfetto::CounterTrack memory_track = perfetto::CounterTrack("Memory")
+//       .set_unit("bytes")
+//       .set_multiplier(1024);
+//   TRACE_COUNTER("category", memory_track, 4 /* = 4096 bytes */);
+//
+// See /protos/perfetto/trace/track_event/counter_descriptor.proto
+// for the full set of attributes for a counter track.
+//
+// To record a counter value at a specific point in time (instead of the current
+// time), you can pass in a custom timestamp:
+//
+//   // First record the current time and counter value.
+//   uint64_t timestamp = perfetto::TrackEvent::GetTraceTimeNs();
+//   int64_t value = 1234;
+//
+//   // Later, emit a sample at that point in time.
+//   TRACE_COUNTER("category", "MyCounter", timestamp, value);
+//
+#define TRACE_COUNTER(category, track, ...)                 \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(                \
+      TraceForCategory, category, /*name=*/nullptr,         \
+      ::perfetto::protos::pbzero::TrackEvent::TYPE_COUNTER, \
+      ::perfetto::CounterTrack(track), ##__VA_ARGS__)
+
+// TODO(skyostil): Add flow events.
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event_interned_data_index.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_INTERNED_DATA_INDEX_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_INTERNED_DATA_INDEX_H_
+
+// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
+
+#include <map>
+#include <type_traits>
+#include <unordered_map>
+
+// This file has templates for defining your own interned data types to be used
+// with track event. Interned data can be useful for avoiding repeating the same
+// constant data (e.g., strings) throughout the trace.
+//
+// =============
+// Example usage
+// =============
+//
+// First define an interning index for your type. It should map to a specific
+// field of interned_data.proto and define how the interned data is written into
+// that message.
+//
+//   struct MyInternedData
+//       : public perfetto::TrackEventInternedDataIndex<
+//           MyInternedData,
+//           perfetto::protos::pbzero::InternedData::kMyInternedDataFieldNumber,
+//           const char*> {
+//     static void Add(perfetto::protos::pbzero::InternedData* interned_data,
+//                      size_t iid,
+//                      const char* value) {
+//       auto my_data = interned_data->add_my_interned_data();
+//       my_data->set_iid(iid);
+//       my_data->set_value(value);
+//     }
+//   };
+//
+// Next, use your interned data in a trace point as shown below. The interned
+// string will only be emitted the first time the trace point is hit.
+//
+//   TRACE_EVENT_BEGIN(
+//      "category", "Event", [&](perfetto::EventContext ctx) {
+//        auto my_message = ctx.event()->set_my_message();
+//        size_t iid = MyInternedData::Get(&ctx, "Some data");
+//        my_message->set_iid(iid);
+//      });
+//
+
+namespace perfetto {
+
+// By default, the interning index stores a full copy of the interned data. This
+// ensures the same data is always mapped to the same interning id, and there is
+// no danger of collisions. This comes at the cost of memory usage, however, so
+// consider using HashedInternedDataTraits if that may be an issue.
+//
+// This type of index also performs hashing on the stored data for lookups; for
+// types where this isn't necessary (e.g., raw const char*), use
+// SmallInternedDataTraits.
+struct BigInternedDataTraits {
+  template <typename ValueType>
+  class Index {
+   public:
+    bool LookUpOrInsert(size_t* iid, const ValueType& value) {
+      size_t next_id = data_.size() + 1;
+      auto it_and_inserted = data_.insert(std::make_pair(value, next_id));
+      if (!it_and_inserted.second) {
+        *iid = it_and_inserted.first->second;
+        return true;
+      }
+      *iid = next_id;
+      return false;
+    }
+
+   private:
+    std::unordered_map<ValueType, size_t> data_;
+  };
+};
+
+// This type of interning index keeps full copies of interned data without
+// hashing the values. This is a good fit for small types that can be directly
+// used as index keys.
+struct SmallInternedDataTraits {
+  template <typename ValueType>
+  class Index {
+   public:
+    bool LookUpOrInsert(size_t* iid, const ValueType& value) {
+      size_t next_id = data_.size() + 1;
+      auto it_and_inserted = data_.insert(std::make_pair(value, next_id));
+      if (!it_and_inserted.second) {
+        *iid = it_and_inserted.first->second;
+        return true;
+      }
+      *iid = next_id;
+      return false;
+    }
+
+   private:
+    std::map<ValueType, size_t> data_;
+  };
+};
+
+// This type of interning index only stores the hash of the interned values
+// instead of the values themselves. This is more efficient in terms of memory
+// usage, but assumes that there are no hash collisions. If a hash collision
+// occurs, two or more values will be mapped to the same interning id.
+//
+// Note that the given type must have a specialization for std::hash.
+struct HashedInternedDataTraits {
+  template <typename ValueType>
+  class Index {
+   public:
+    bool LookUpOrInsert(size_t* iid, const ValueType& value) {
+      auto key = std::hash<ValueType>()(value);
+      size_t next_id = data_.size() + 1;
+      auto it_and_inserted = data_.insert(std::make_pair(key, next_id));
+      if (!it_and_inserted.second) {
+        *iid = it_and_inserted.first->second;
+        return true;
+      }
+      *iid = next_id;
+      return false;
+    }
+
+   private:
+    std::map<size_t, size_t> data_;
+  };
+};
+
+// A templated base class for an interned data type which corresponds to a field
+// in interned_data.proto.
+//
+// |InternedDataType| must be the type of the subclass.
+// |FieldNumber| is the corresponding protobuf field in InternedData.
+// |ValueType| is the type which is stored in the index. It must be copyable.
+// |Traits| can be used to customize the storage and lookup mechanism.
+//
+// The subclass should define a static method with the following signature for
+// committing interned data together with the interning id |iid| into the trace:
+//
+//   static void Add(perfetto::protos::pbzero::InternedData*,
+//                   size_t iid,
+//                   const ValueType& value);
+//
+template <typename InternedDataType,
+          size_t FieldNumber,
+          typename ValueType,
+          // Avoid unnecessary hashing for pointers by default.
+          typename Traits =
+              typename std::conditional<(std::is_pointer<ValueType>::value),
+                                        SmallInternedDataTraits,
+                                        BigInternedDataTraits>::type>
+class TrackEventInternedDataIndex
+    : public internal::BaseTrackEventInternedDataIndex {
+ public:
+  // Return an interning id for |value|. The returned id can be immediately
+  // written to the trace. The optional |add_args| are passed to the Add()
+  // function.
+  template <typename... Args>
+  static size_t Get(EventContext* ctx,
+                    const ValueType& value,
+                    Args&&... add_args) {
+    return Get(ctx->incremental_state_, value, std::forward<Args>(add_args)...);
+  }
+
+  template <typename... Args>
+  static size_t Get(internal::TrackEventIncrementalState* incremental_state,
+                    const ValueType& value,
+                    Args&&... add_args) {
+    // First check if the value exists in the dictionary.
+    auto index_for_field = GetOrCreateIndexForField(incremental_state);
+    size_t iid;
+    if (PERFETTO_LIKELY(index_for_field->index_.LookUpOrInsert(&iid, value))) {
+      PERFETTO_DCHECK(iid);
+      return iid;
+    }
+
+    // If not, we need to serialize the definition of the interned value into
+    // the heap buffered message (which is committed to the trace when the
+    // packet ends).
+    PERFETTO_DCHECK(iid);
+    InternedDataType::Add(incremental_state->serialized_interned_data.get(),
+                          iid, std::move(value),
+                          std::forward<Args>(add_args)...);
+    return iid;
+  }
+
+ protected:
+  // Some use cases require a custom Get implemention, so they need access to
+  // GetOrCreateIndexForField + the returned index.
+  static InternedDataType* GetOrCreateIndexForField(
+      internal::TrackEventIncrementalState* incremental_state) {
+    // Fast path: look for matching field number.
+    for (const auto& entry : incremental_state->interned_data_indices) {
+      if (entry.first == FieldNumber) {
+#if PERFETTO_DCHECK_IS_ON()
+        if (strcmp(PERFETTO_DEBUG_FUNCTION_IDENTIFIER(),
+                   entry.second->type_id_)) {
+          PERFETTO_FATAL(
+              "Interned data accessed under different types! Previous type: "
+              "%s. New type: %s.",
+              entry.second->type_id_, PERFETTO_DEBUG_FUNCTION_IDENTIFIER());
+        }
+        // If an interned data index is defined in an anonymous namespace, we
+        // can end up with multiple copies of it in the same program. Because
+        // they will all share a memory address through TLS, this can lead to
+        // subtle data corruption if all the copies aren't exactly identical.
+        // Try to detect this by checking if the Add() function address remains
+        // constant.
+        if (reinterpret_cast<void*>(&InternedDataType::Add) !=
+            entry.second->add_function_ptr_) {
+          PERFETTO_FATAL(
+              "Inconsistent interned data index. Maybe the index was defined "
+              "in an anonymous namespace in a header or copied to multiple "
+              "files? Duplicate index definitions can lead to memory "
+              "corruption! Type id: %s",
+              entry.second->type_id_);
+        }
+#endif  // PERFETTO_DCHECK_IS_ON()
+        return reinterpret_cast<InternedDataType*>(entry.second.get());
+      }
+    }
+    // No match -- add a new entry for this field.
+    for (auto& entry : incremental_state->interned_data_indices) {
+      if (!entry.first) {
+        entry.first = FieldNumber;
+        entry.second.reset(new InternedDataType());
+#if PERFETTO_DCHECK_IS_ON()
+        entry.second->type_id_ = PERFETTO_DEBUG_FUNCTION_IDENTIFIER();
+        entry.second->add_function_ptr_ =
+            reinterpret_cast<void*>(&InternedDataType::Add);
+#endif  // PERFETTO_DCHECK_IS_ON()
+        return reinterpret_cast<InternedDataType*>(entry.second.get());
+      }
+    }
+    // Out of space in the interned data index table.
+    PERFETTO_CHECK(false);
+  }
+
+  // The actual interning dictionary for this type of interned data. The actual
+  // container type is defined by |Traits|, hence the extra layer of template
+  // indirection here.
+  typename Traits::template Index<ValueType> index_;
+};
+
+}  // namespace perfetto
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_INTERNED_DATA_INDEX_H_
+// gen_amalgamated begin header: include/perfetto/tracing/track_event_legacy.h
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_LEGACY_H_
+#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_LEGACY_H_
+
+// This file defines a compatibility shim between legacy (Chrome, V8) trace
+// event macros and track events. To avoid accidentally introducing legacy
+// events in new code, the PERFETTO_ENABLE_LEGACY_TRACE_EVENTS macro must be set
+// to 1 activate the compatibility layer.
+
+// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event.h"
+
+#include <stdint.h>
+
+#ifndef PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+#define PERFETTO_ENABLE_LEGACY_TRACE_EVENTS 0
+#endif
+
+// Ignore GCC warning about a missing argument for a variadic macro parameter.
+#if defined(__GNUC__) || defined(__clang__)
+#pragma GCC system_header
+#endif
+
+// ----------------------------------------------------------------------------
+// Internal legacy trace point implementation.
+// ----------------------------------------------------------------------------
+
+namespace perfetto {
+namespace legacy {
+
+// The following user-provided adaptors are used to serialize user-defined
+// thread id and time types into track events. For full compatibility, the user
+// should also define the following macros appropriately:
+//
+//   #define TRACE_TIME_TICKS_NOW() ...
+//   #define TRACE_TIME_NOW() ...
+
+// User-provided function to convert an abstract thread id into a thread track.
+template <typename T>
+ThreadTrack ConvertThreadId(const T&);
+
+// Built-in implementation for events referring to the current thread.
+template <>
+ThreadTrack PERFETTO_EXPORT_COMPONENT
+ConvertThreadId(const PerfettoLegacyCurrentThreadId&);
+
+}  // namespace legacy
+}  // namespace perfetto
+
+#if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+// Implementations for the INTERNAL_* adapter macros used by the trace points
+// below.
+#define PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(phase, category, name, track, \
+                                                ...)                          \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(                                  \
+      TraceForCategory, category,                                             \
+      ::perfetto::internal::DecayEventNameType(name),                         \
+      ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track,      \
+      ##__VA_ARGS__);
+
+#define PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(              \
+    phase, category, name, track, flags, ...)                            \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(                             \
+      TraceForCategoryLegacy, category,                                  \
+      ::perfetto::internal::DecayEventNameType(name),                    \
+      ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track, \
+      phase, flags, ##__VA_ARGS__);
+
+#define PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                 \
+    phase, category, name, track, flags, thread_id, id, ...)             \
+  PERFETTO_INTERNAL_TRACK_EVENT_WITH_METHOD(                             \
+      TraceForCategoryLegacyWithId, category,                            \
+      ::perfetto::internal::DecayEventNameType(name),                    \
+      ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track, \
+      phase, flags, thread_id, id, ##__VA_ARGS__);
+
+// The main entrypoint for writing unscoped legacy events.  This macro
+// determines the right track to write the event on based on |flags| and
+// |thread_id|.
+#define PERFETTO_INTERNAL_LEGACY_EVENT(phase, category, name, flags,       \
+                                       thread_id, ...)                     \
+  [&]() {                                                                  \
+    using ::perfetto::internal::TrackEventInternal;                        \
+    PERFETTO_DCHECK(!(flags & TRACE_EVENT_FLAG_COPY));                     \
+    /* First check the scope for instant events. */                        \
+    if ((phase) == TRACE_EVENT_PHASE_INSTANT) {                            \
+      /* Note: Avoids the need to set LegacyEvent::instant_event_scope. */ \
+      auto scope = (flags)&TRACE_EVENT_FLAG_SCOPE_MASK;                    \
+      switch (scope) {                                                     \
+        case TRACE_EVENT_SCOPE_GLOBAL:                                     \
+          PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(              \
+              phase, category, name, ::perfetto::Track::Global(0), flags,  \
+              ##__VA_ARGS__);                                              \
+          return;                                                          \
+        case TRACE_EVENT_SCOPE_PROCESS:                                    \
+          PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(              \
+              phase, category, name, ::perfetto::ProcessTrack::Current(),  \
+              flags, ##__VA_ARGS__);                                       \
+          return;                                                          \
+        default:                                                           \
+        case TRACE_EVENT_SCOPE_THREAD:                                     \
+          /* Fallthrough. */                                               \
+          break;                                                           \
+      }                                                                    \
+    }                                                                      \
+    /* If an event targets the current thread or another process, write    \
+     * it on the current thread's track. The process override case is      \
+     * handled through |pid_override| in WriteLegacyEvent. */              \
+    if (std::is_same<                                                      \
+            decltype(thread_id),                                           \
+            ::perfetto::legacy::PerfettoLegacyCurrentThreadId>::value ||   \
+        ((flags)&TRACE_EVENT_FLAG_HAS_PROCESS_ID)) {                       \
+      PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(                  \
+          phase, category, name, TrackEventInternal::kDefaultTrack, flags, \
+          ##__VA_ARGS__);                                                  \
+    } else {                                                               \
+      PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(                  \
+          phase, category, name,                                           \
+          ::perfetto::legacy::ConvertThreadId(thread_id), flags,           \
+          ##__VA_ARGS__);                                                  \
+    }                                                                      \
+  }()
+
+#define PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID(phase, category, name, flags, \
+                                               thread_id, id, ...)           \
+  [&]() {                                                                    \
+    using ::perfetto::internal::TrackEventInternal;                          \
+    PERFETTO_DCHECK(!(flags & TRACE_EVENT_FLAG_COPY));                       \
+    /* First check the scope for instant events. */                          \
+    if ((phase) == TRACE_EVENT_PHASE_INSTANT) {                              \
+      /* Note: Avoids the need to set LegacyEvent::instant_event_scope. */   \
+      auto scope = (flags)&TRACE_EVENT_FLAG_SCOPE_MASK;                      \
+      switch (scope) {                                                       \
+        case TRACE_EVENT_SCOPE_GLOBAL:                                       \
+          PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                   \
+              phase, category, name, ::perfetto::Track::Global(0), flags,    \
+              thread_id, id, ##__VA_ARGS__);                                 \
+          return;                                                            \
+        case TRACE_EVENT_SCOPE_PROCESS:                                      \
+          PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                   \
+              phase, category, name, ::perfetto::ProcessTrack::Current(),    \
+              flags, thread_id, id, ##__VA_ARGS__);                          \
+          return;                                                            \
+        default:                                                             \
+        case TRACE_EVENT_SCOPE_THREAD:                                       \
+          /* Fallthrough. */                                                 \
+          break;                                                             \
+      }                                                                      \
+    }                                                                        \
+    /* If an event targets the current thread or another process, write      \
+     * it on the current thread's track. The process override case is        \
+     * handled through |pid_override| in WriteLegacyEvent. */                \
+    if (std::is_same<                                                        \
+            decltype(thread_id),                                             \
+            ::perfetto::legacy::PerfettoLegacyCurrentThreadId>::value ||     \
+        ((flags)&TRACE_EVENT_FLAG_HAS_PROCESS_ID)) {                         \
+      PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                       \
+          phase, category, name, TrackEventInternal::kDefaultTrack, flags,   \
+          thread_id, id, ##__VA_ARGS__);                                     \
+    } else {                                                                 \
+      PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                       \
+          phase, category, name,                                             \
+          ::perfetto::legacy::ConvertThreadId(thread_id), flags, thread_id,  \
+          id, ##__VA_ARGS__);                                                \
+    }                                                                        \
+  }()
+
+#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...)           \
+  PERFETTO_INTERNAL_LEGACY_EVENT(                                             \
+      phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
+      ::perfetto::legacy::kCurrentThreadId, ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \
+  PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(                      \
+      category, ::perfetto::internal::DecayEventNameType(name), ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category, name, bind_id, \
+                                                  flags, ...)              \
+  PERFETTO_INTERNAL_SCOPED_LEGACY_TRACK_EVENT_WITH_ID(                     \
+      category, ::perfetto::internal::DecayEventNameType(name),            \
+      ::perfetto::internal::TrackEventInternal::kDefaultTrack, flags,      \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, bind_id, ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category, name,        \
+                                                timestamp, flags, ...)        \
+  PERFETTO_INTERNAL_LEGACY_EVENT(                                             \
+      phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
+      ::perfetto::legacy::kCurrentThreadId, timestamp, ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
+    phase, category, name, id, thread_id, timestamp, flags, ...)              \
+  PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID(                                     \
+      phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
+      thread_id, id, timestamp, ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags,    \
+                                         ...)                                 \
+  PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID(                                     \
+      phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
+      ::perfetto::legacy::kCurrentThreadId, id, ##__VA_ARGS__)
+
+#define INTERNAL_TRACE_EVENT_METADATA_ADD(category, name, ...)         \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_METADATA, category, name, \
+                           TRACE_EVENT_FLAG_NONE)
+
+// ----------------------------------------------------------------------------
+// Legacy tracing common API (adapted from trace_event_common.h).
+// ----------------------------------------------------------------------------
+
+#define TRACE_DISABLED_BY_DEFAULT(name) "disabled-by-default-" name
+
+// Scoped events.
+#define TRACE_EVENT0(category_group, name) \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
+#define TRACE_EVENT_WITH_FLOW0(category_group, name, bind_id, flow_flags)  \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
+                                            flow_flags)
+#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED(                              \
+      category_group, name, arg1_name,                          \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_WITH_FLOW1(category_group, name, bind_id, flow_flags, \
+                               arg1_name, arg1_val)                       \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(                              \
+      category_group, name, bind_id, flow_flags, arg1_name,               \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \
+                     arg2_val)                                             \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED(                                         \
+      category_group, name, arg1_name,                                     \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,             \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_WITH_FLOW2(category_group, name, bind_id, flow_flags, \
+                               arg1_name, arg1_val, arg2_name, arg2_val)  \
+  INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(                              \
+      category_group, name, bind_id, flow_flags, arg1_name,               \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,            \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Instant events.
+#define TRACE_EVENT_INSTANT0(category_group, name, scope)                   \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE | scope)
+#define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
+                           TRACE_EVENT_FLAG_NONE | scope, arg1_name,           \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
+                             arg2_name, arg2_val)                              \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
+                           TRACE_EVENT_FLAG_NONE | scope, arg1_name,           \
+                           ::perfetto::internal::PossiblyNull(arg1_val),       \
+                           arg2_name,                                          \
+                           ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_INSTANT0(category_group, name, scope)        \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, \
+                           ::perfetto::DynamicString{name}, scope)
+#define TRACE_EVENT_COPY_INSTANT1(category_group, name, scope, arg1_name, \
+                                  arg1_val)                               \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group,     \
+                           ::perfetto::DynamicString{name}, scope,        \
+                           ::perfetto::DynamicString{arg1_name},          \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_INSTANT2(category_group, name, scope, arg1_name, \
+                                  arg1_val, arg2_name, arg2_val)          \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group,     \
+                           ::perfetto::DynamicString{name}, scope,        \
+                           ::perfetto::DynamicString{arg1_name},          \
+                           ::perfetto::internal::PossiblyNull(arg1_val),  \
+                           ::perfetto::DynamicString{arg2_name},          \
+                           ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_INSTANT_WITH_FLAGS0(category_group, name, scope_and_flags) \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
+                           scope_and_flags)
+#define TRACE_EVENT_INSTANT_WITH_FLAGS1(category_group, name, scope_and_flags, \
+                                        arg1_name, arg1_val)                   \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
+                           scope_and_flags, arg1_name,                         \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+
+// Instant events with explicit timestamps.
+#define TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(category_group, name, scope,   \
+                                            timestamp)                     \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(TRACE_EVENT_PHASE_INSTANT,       \
+                                          category_group, name, timestamp, \
+                                          TRACE_EVENT_FLAG_NONE | scope)
+
+#define TRACE_EVENT_INSTANT_WITH_TIMESTAMP1(category_group, name, scope,  \
+                                            timestamp, arg_name, arg_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                \
+      TRACE_EVENT_PHASE_INSTANT, category_group, name, timestamp,         \
+      TRACE_EVENT_FLAG_NONE | scope, arg_name,                            \
+      ::perfetto::internal::PossiblyNull(arg_val))
+
+// Begin events.
+#define TRACE_EVENT_BEGIN0(category_group, name)                          \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_BEGIN1(category_group, name, arg1_name, arg1_val)     \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE, arg1_name,              \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_BEGIN2(category_group, name, arg1_name, arg1_val,       \
+                           arg2_name, arg2_val)                             \
+  INTERNAL_TRACE_EVENT_ADD(                                                 \
+      TRACE_EVENT_PHASE_BEGIN, category_group, name, TRACE_EVENT_FLAG_NONE, \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,   \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_BEGIN_WITH_FLAGS0(category_group, name, flags) \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, flags)
+#define TRACE_EVENT_BEGIN_WITH_FLAGS1(category_group, name, flags, arg1_name, \
+                                      arg1_val)                               \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name,     \
+                           flags, arg1_name,                                  \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_BEGIN2(category_group, name, arg1_name, arg1_val, \
+                                arg2_name, arg2_val)                       \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group,        \
+                           ::perfetto::DynamicString{name},                \
+                           TRACE_EVENT_FLAG_NONE,                          \
+                           ::perfetto::DynamicString{arg1_name},           \
+                           ::perfetto::internal::PossiblyNull(arg1_val),   \
+                           ::perfetto::DynamicString{arg2_name},           \
+                           ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Begin events with explicit timestamps.
+#define TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category_group, name, id, \
+                                                     thread_id, timestamp)     \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id,      \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(       \
+    category_group, name, id, thread_id, timestamp)              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(            \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,             \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp, \
+      TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP1(               \
+    category_group, name, id, thread_id, timestamp, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                     \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP2(               \
+    category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
+    arg2_name, arg2_val)                                                 \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                     \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
+      ::perfetto::internal::PossiblyNull(arg1_val),                      \
+      ::perfetto::DynamicString{arg2_name},                              \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// End events.
+#define TRACE_EVENT_END0(category_group, name)                          \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_END1(category_group, name, arg1_name, arg1_val)     \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE, arg1_name,            \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_END2(category_group, name, arg1_name, arg1_val, arg2_name, \
+                         arg2_val)                                             \
+  INTERNAL_TRACE_EVENT_ADD(                                                    \
+      TRACE_EVENT_PHASE_END, category_group, name, TRACE_EVENT_FLAG_NONE,      \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,      \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_END_WITH_FLAGS0(category_group, name, flags) \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags)
+#define TRACE_EVENT_END_WITH_FLAGS1(category_group, name, flags, arg1_name,    \
+                                    arg1_val)                                  \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags, \
+                           arg1_name,                                          \
+                           ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_END2(category_group, name, arg1_name, arg1_val,      \
+                              arg2_name, arg2_val)                            \
+  INTERNAL_TRACE_EVENT_ADD(                                                   \
+      TRACE_EVENT_PHASE_END, category_group, ::perfetto::DynamicString{name}, \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},            \
+      ::perfetto::internal::PossiblyNull(arg1_val),                           \
+      ::perfetto::DynamicString{arg2_name},                                   \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Mark events.
+#define TRACE_EVENT_MARK_WITH_TIMESTAMP0(category_group, name, timestamp)  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(TRACE_EVENT_PHASE_MARK,          \
+                                          category_group, name, timestamp, \
+                                          TRACE_EVENT_FLAG_NONE)
+
+#define TRACE_EVENT_MARK_WITH_TIMESTAMP1(category_group, name, timestamp, \
+                                         arg1_name, arg1_val)             \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                \
+      TRACE_EVENT_PHASE_MARK, category_group, name, timestamp,            \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                   \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+
+#define TRACE_EVENT_MARK_WITH_TIMESTAMP2(                                      \
+    category_group, name, timestamp, arg1_name, arg1_val, arg2_name, arg2_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                     \
+      TRACE_EVENT_PHASE_MARK, category_group, name, timestamp,                 \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                        \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,                 \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+#define TRACE_EVENT_COPY_MARK(category_group, name)                \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_MARK, category_group, \
+                           ::perfetto::DynamicString{name},        \
+                           TRACE_EVENT_FLAG_NONE)
+
+#define TRACE_EVENT_COPY_MARK1(category_group, name, arg1_name, arg1_val)      \
+  INTERNAL_TRACE_EVENT_ADD(                                                    \
+      TRACE_EVENT_PHASE_MARK, category_group, ::perfetto::DynamicString{name}, \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},             \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+
+#define TRACE_EVENT_COPY_MARK_WITH_TIMESTAMP(category_group, name, timestamp)  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                     \
+      TRACE_EVENT_PHASE_MARK, category_group, ::perfetto::DynamicString{name}, \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+
+// End events with explicit thread and timestamp.
+#define TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0(category_group, name, id, \
+                                                   thread_id, timestamp)     \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id,      \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0(         \
+    category_group, name, id, thread_id, timestamp)              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(            \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,               \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp, \
+      TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP1(                 \
+    category_group, name, id, thread_id, timestamp, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP2(                 \
+    category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
+    arg2_name, arg2_val)                                                 \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
+      ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
+      TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
+      ::perfetto::internal::PossiblyNull(arg1_val),                      \
+      ::perfetto::DynamicString{arg2_name},                              \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Counters.
+#define TRACE_COUNTER1(category_group, name, value)                         \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE, "value",                  \
+                           static_cast<int>(value))
+#define TRACE_COUNTER_WITH_FLAG1(category_group, name, flag, value)         \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
+                           flag, "value", static_cast<int>(value))
+#define TRACE_COPY_COUNTER1(category_group, name, value)              \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, \
+                           ::perfetto::DynamicString{name},           \
+                           TRACE_EVENT_FLAG_NONE, "value",            \
+                           static_cast<int>(value))
+#define TRACE_COUNTER2(category_group, name, value1_name, value1_val,       \
+                       value2_name, value2_val)                             \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
+                           TRACE_EVENT_FLAG_NONE, value1_name,              \
+                           static_cast<int>(value1_val), value2_name,       \
+                           static_cast<int>(value2_val))
+#define TRACE_COPY_COUNTER2(category_group, name, value1_name, value1_val, \
+                            value2_name, value2_val)                       \
+  INTERNAL_TRACE_EVENT_ADD(                                                \
+      TRACE_EVENT_PHASE_COUNTER, category_group,                           \
+      ::perfetto::DynamicString{name}, TRACE_EVENT_FLAG_NONE, value1_name, \
+      static_cast<int>(value1_val), value2_name, static_cast<int>(value2_val))
+
+// Counters with explicit timestamps.
+#define TRACE_COUNTER_WITH_TIMESTAMP1(category_group, name, timestamp, value) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                    \
+      TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp,             \
+      TRACE_EVENT_FLAG_NONE, "value", static_cast<int>(value))
+
+#define TRACE_COUNTER_WITH_TIMESTAMP2(category_group, name, timestamp,      \
+                                      value1_name, value1_val, value2_name, \
+                                      value2_val)                           \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                  \
+      TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp,           \
+      TRACE_EVENT_FLAG_NONE, value1_name, static_cast<int>(value1_val),     \
+      value2_name, static_cast<int>(value2_val))
+
+// Counters with ids.
+#define TRACE_COUNTER_ID1(category_group, name, id, value)                    \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
+                                   name, id, TRACE_EVENT_FLAG_NONE, "value",  \
+                                   static_cast<int>(value))
+#define TRACE_COPY_COUNTER_ID1(category_group, name, id, value)               \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
+                                   ::perfetto::DynamicString{name}, id,       \
+                                   TRACE_EVENT_FLAG_NONE, "value",            \
+                                   static_cast<int>(value))
+#define TRACE_COUNTER_ID2(category_group, name, id, value1_name, value1_val,  \
+                          value2_name, value2_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
+                                   name, id, TRACE_EVENT_FLAG_NONE,           \
+                                   value1_name, static_cast<int>(value1_val), \
+                                   value2_name, static_cast<int>(value2_val))
+#define TRACE_COPY_COUNTER_ID2(category_group, name, id, value1_name,          \
+                               value1_val, value2_name, value2_val)            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
+      TRACE_EVENT_PHASE_COUNTER, category_group,                               \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE, value1_name, \
+      static_cast<int>(value1_val), value2_name, static_cast<int>(value2_val))
+
+// Sampling profiler events.
+#define TRACE_EVENT_SAMPLE_WITH_ID1(category_group, name, id, arg1_name,       \
+                                    arg1_val)                                  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_SAMPLE, category_group,   \
+                                   name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \
+                                   arg1_val)
+
+// Legacy async events.
+#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
+                                   category_group, name, id,      \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
+                                 arg1_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                               \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
+                                 arg1_val, arg2_name, arg2_val)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                               \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,        \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                             \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
+                                      arg1_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                        \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                       \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,          \
+      ::perfetto::DynamicString{arg1_name},                                \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
+                                      arg1_val, arg2_name, arg2_val)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                        \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                       \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,          \
+      ::perfetto::DynamicString{arg1_name},                                \
+      ::perfetto::internal::PossiblyNull(arg1_val),                        \
+      ::perfetto::DynamicString{arg2_name},                                \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, flags) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN,            \
+                                   category_group, name, id, flags)
+
+// Legacy async events with explicit timestamps.
+#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, id, \
+                                                timestamp)                \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,            \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(                           \
+    category_group, name, id, timestamp, arg1_name, arg1_val)              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,             \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0(     \
+    category_group, name, id, timestamp, flags)                         \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \
+                                                       id, timestamp)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP2(category_group, name, id,      \
+                                                timestamp, arg1_name,          \
+                                                arg1_val, arg2_name, arg2_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,                 \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,     \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,      \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, id, \
+                                                     timestamp)                \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                           \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID,  \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0(     \
+    category_group, name, id, timestamp, flags)                \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(          \
+      TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
+
+// Legacy async step into events.
+#define TRACE_EVENT_ASYNC_STEP_INTO0(category_group, name, id, step)  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_INTO, \
+                                   category_group, name, id,          \
+                                   TRACE_EVENT_FLAG_NONE, "step", step)
+#define TRACE_EVENT_ASYNC_STEP_INTO1(category_group, name, id, step, \
+                                     arg1_name, arg1_val)            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
+      TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id,   \
+      TRACE_EVENT_FLAG_NONE, "step", step, arg1_name,                \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+
+// Legacy async step into events with timestamps.
+#define TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category_group, name, id, \
+                                                    step, timestamp)          \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id,            \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
+      "step", step)
+
+// Legacy async step past events.
+#define TRACE_EVENT_ASYNC_STEP_PAST0(category_group, name, id, step)  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_PAST, \
+                                   category_group, name, id,          \
+                                   TRACE_EVENT_FLAG_NONE, "step", step)
+#define TRACE_EVENT_ASYNC_STEP_PAST1(category_group, name, id, step, \
+                                     arg1_name, arg1_val)            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
+      TRACE_EVENT_PHASE_ASYNC_STEP_PAST, category_group, name, id,   \
+      TRACE_EVENT_FLAG_NONE, "step", step, arg1_name,                \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+
+// Legacy async end events.
+#define TRACE_EVENT_ASYNC_END0(category_group, name, id)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
+                                   category_group, name, id,    \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                           \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                       \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_ASYNC_END2(category_group, name, id, arg1_name, arg1_val, \
+                               arg2_name, arg2_val)                           \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                           \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                       \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,                \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_ASYNC_END0(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                           \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_ASYNC_END1(category_group, name, id, arg1_name, \
+                                    arg1_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,        \
+      ::perfetto::DynamicString{arg1_name},                              \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_ASYNC_END2(category_group, name, id, arg1_name, \
+                                    arg1_val, arg2_name, arg2_val)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,        \
+      ::perfetto::DynamicString{arg1_name},                              \
+      ::perfetto::internal::PossiblyNull(arg1_val),                      \
+      ::perfetto::DynamicString{arg2_name},                              \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_ASYNC_END_WITH_FLAGS0(category_group, name, id, flags) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,            \
+                                   category_group, name, id, flags)
+
+// Legacy async end events with explicit timestamps.
+#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id, \
+                                              timestamp)                \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,            \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP1(category_group, name, id,       \
+                                              timestamp, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP2(category_group, name, id,       \
+                                              timestamp, arg1_name, arg1_val, \
+                                              arg2_name, arg2_val)            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,     \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id,  \
+                                                   timestamp)                 \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group,                            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(category_group, name, \
+                                                        id, timestamp, flags) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
+
+// Async events.
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(category_group, name, id)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
+                                   category_group, name, id,               \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
+                                          arg1_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                        \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
+                                          arg1_val, arg2_name, arg2_val)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                        \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,                 \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, \
+                                                     flags)                    \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN,     \
+                                   category_group, name, id, flags)
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1(                  \
+    category_group, name, id, timestamp, arg1_name, arg1_val)              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,    \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
+
+// Async end events.
+#define TRACE_EVENT_NESTABLE_ASYNC_END0(category_group, name, id)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
+                                   category_group, name, id,             \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_END1(category_group, name, id, arg1_name, \
+                                        arg1_val)                            \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                          \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                      \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_END2(category_group, name, id, arg1_name, \
+                                        arg1_val, arg2_name, arg2_val)       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                          \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                      \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,               \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_FLAGS0(category_group, name, id, \
+                                                   flags)                    \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END,     \
+                                   category_group, name, id, flags)
+
+// Async instant events.
+#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT0(category_group, name, id)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, \
+                                   category_group, name, id,                 \
+                                   TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT1(category_group, name, id,     \
+                                            arg1_name, arg1_val)          \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                       \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                   \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT2(                              \
+    category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val)   \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                       \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
+      TRACE_EVENT_FLAG_NONE, arg1_name,                                   \
+      ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,            \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TTS2(                \
+    category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                     \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,           \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_ASYNC_TTS,  \
+      ::perfetto::DynamicString{arg1_name},                             \
+      ::perfetto::internal::PossiblyNull(arg1_val),                     \
+      ::perfetto::DynamicString{arg2_name},                             \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TTS2(                  \
+    category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                     \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group,             \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_ASYNC_TTS,  \
+      ::perfetto::DynamicString{arg1_name},                             \
+      ::perfetto::internal::PossiblyNull(arg1_val),                     \
+      ::perfetto::DynamicString{arg2_name},                             \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Async events with explicit timestamps.
+#define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, \
+                                                         id, timestamp)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \
+                                                       id, timestamp)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP1(                    \
+    category_group, name, id, timestamp, arg1_name, arg1_val)              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP2(                    \
+    category_group, name, id, timestamp, arg1_name, arg1_val, arg2_name,   \
+    arg2_val)                                                              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,  \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(     \
+    category_group, name, id, timestamp, flags)                       \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                 \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
+#define TRACE_EVENT_NESTABLE_ASYNC_INSTANT_WITH_TIMESTAMP0(               \
+    category_group, name, id, timestamp)                                  \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN0(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN1(category_group, name, id, \
+                                               arg1_name, arg1_val)      \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,        \
+      ::perfetto::DynamicString{arg1_name},                              \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN2(                         \
+    category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                     \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,           \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,       \
+      ::perfetto::DynamicString{arg1_name},                             \
+      ::perfetto::internal::PossiblyNull(arg1_val),                     \
+      ::perfetto::DynamicString{arg2_name},                             \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END0(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                    \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group,            \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(                \
+    category_group, name, id, timestamp)                                      \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,                 \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1(                \
+    category_group, name, id, timestamp, arg1_name, arg1_val)                 \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,                 \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
+      timestamp, TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name}, \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(                  \
+    category_group, name, id, timestamp)                                      \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group,                   \
+      ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
+      timestamp, TRACE_EVENT_FLAG_NONE)
+#define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP2(               \
+    category_group, name, id, timestamp, arg1_name, arg1_val, arg2_name,   \
+    arg2_val)                                                              \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      ::perfetto::DynamicString{arg1_name},                                \
+      ::perfetto::internal::PossiblyNull(arg1_val),                        \
+      ::perfetto::DynamicString{arg2_name},                                \
+      ::perfetto::internal::PossiblyNull(arg2_val))
+
+// Metadata events.
+#define TRACE_EVENT_METADATA1(category_group, name, arg1_name, arg1_val) \
+  INTERNAL_TRACE_EVENT_METADATA_ADD(                                     \
+      category_group, name, arg1_name,                                   \
+      ::perfetto::internal::PossiblyNull(arg1_val))
+
+// Clock sync events.
+#define TRACE_EVENT_CLOCK_SYNC_RECEIVER(sync_id)                           \
+  INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_CLOCK_SYNC, "__metadata",     \
+                           "clock_sync", TRACE_EVENT_FLAG_NONE, "sync_id", \
+                           sync_id)
+#define TRACE_EVENT_CLOCK_SYNC_ISSUER(sync_id, issue_ts, issue_end_ts)        \
+  INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                    \
+      TRACE_EVENT_PHASE_CLOCK_SYNC, "__metadata", "clock_sync", issue_end_ts, \
+      TRACE_EVENT_FLAG_NONE, "sync_id", sync_id, "issue_ts", issue_ts)
+
+// Object events.
+#define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_CREATE_OBJECT,  \
+                                   category_group, name, id,         \
+                                   TRACE_EVENT_FLAG_NONE)
+
+#define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, \
+                                            snapshot)                 \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
+      TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, id,    \
+      TRACE_EVENT_FLAG_NONE, "snapshot", snapshot)
+
+#define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID_AND_TIMESTAMP(                 \
+    category_group, name, id, timestamp, snapshot)                         \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
+      TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, id,         \
+      TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
+      "snapshot", snapshot)
+
+#define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
+  INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_DELETE_OBJECT,  \
+                                   category_group, name, id,         \
+                                   TRACE_EVENT_FLAG_NONE)
+
+// TODO(skyostil): Implement binary-efficient trace events.
+#define TRACE_EVENT_BINARY_EFFICIENT0 TRACE_EVENT0
+#define TRACE_EVENT_BINARY_EFFICIENT1 TRACE_EVENT1
+#define TRACE_EVENT_BINARY_EFFICIENT2 TRACE_EVENT2
+
+// Macro to efficiently determine if a given category group is enabled.
+#define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category, ret) \
+  do {                                                    \
+    *ret = TRACE_EVENT_CATEGORY_ENABLED(category);        \
+  } while (0)
+
+// Macro to efficiently determine, through polling, if a new trace has begun.
+#define TRACE_EVENT_IS_NEW_TRACE(ret)                                \
+  do {                                                               \
+    static int PERFETTO_UID(prev) = -1;                              \
+    int PERFETTO_UID(curr) =                                         \
+        ::perfetto::internal::TrackEventInternal::GetSessionCount(); \
+    if (PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsEnabled() &&   \
+        (PERFETTO_UID(prev) != PERFETTO_UID(curr))) {                \
+      *(ret) = true;                                                 \
+      PERFETTO_UID(prev) = PERFETTO_UID(curr);                       \
+    } else {                                                         \
+      *(ret) = false;                                                \
+    }                                                                \
+  } while (0)
+
+// ----------------------------------------------------------------------------
+// Legacy tracing API (adapted from trace_event.h).
+// ----------------------------------------------------------------------------
+
+// We can implement the following subset of the legacy tracing API without
+// involvement from the embedder. APIs such as TRACE_EVENT_API_ADD_TRACE_EVENT
+// are still up to the embedder to define.
+
+#define TRACE_STR_COPY(str) \
+  ::perfetto::DynamicString { ::perfetto::internal::PossiblyNull(str) }
+
+#define TRACE_ID_WITH_SCOPE(scope, ...) \
+  ::perfetto::internal::LegacyTraceId::WithScope(scope, ##__VA_ARGS__)
+
+// Use this for ids that are unique across processes. This allows different
+// processes to use the same id to refer to the same event.
+#define TRACE_ID_GLOBAL(id) ::perfetto::internal::LegacyTraceId::GlobalId(id)
+
+// Use this for ids that are unique within a single process. This allows
+// different processes to use the same id to refer to different events.
+#define TRACE_ID_LOCAL(id) ::perfetto::internal::LegacyTraceId::LocalId(id)
+
+// Returns a pointer to a uint8_t which indicates whether tracing is enabled for
+// the given category or not. A zero value means tracing is disabled and
+// non-zero indicates at least one tracing session for this category is active.
+// Note that callers should not make any assumptions at what each bit represents
+// in the status byte. Does not support dynamic categories.
+#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category)              \
+  reinterpret_cast<const uint8_t*>(                                       \
+      [&] {                                                               \
+        static_assert(                                                    \
+            !std::is_same<::perfetto::DynamicCategory,                    \
+                          decltype(category)>::value,                     \
+            "Enabled flag pointers are not supported for dynamic trace "  \
+            "categories.");                                               \
+      },                                                                  \
+      PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry         \
+          .GetCategoryState(                                              \
+              PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
+                  .Find(category, /*is_dynamic=*/false)))
+
+// Given a pointer returned by TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED,
+// yields a pointer to the name of the corresponding category group.
+#define TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(category_enabled_ptr)     \
+  PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry             \
+      .GetCategory(                                                       \
+          category_enabled_ptr -                                          \
+          reinterpret_cast<const uint8_t*>(                               \
+              PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
+                  .GetCategoryState(0u)))                                 \
+      ->name
+
+#endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
+
+#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_LEGACY_H_
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_H_
+#define INCLUDE_PERFETTO_TRACING_H_
+
+// This headers wraps all the headers necessary to use the public Perfetto
+// Tracing API. Embedders should preferably use this one header to avoid having
+// to figure out the various set of header required for each class.
+// The only exception to this should be large projects where build time is a
+// concern (e.g. chromium), which migh prefer sticking to strict IWYU.
+
+// gen_amalgamated expanded: #include "perfetto/base/time.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/console_interceptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_legacy.h"
+// gen_amalgamated expanded: #include "perfetto/tracing/track_event_state_tracker.h"
+
+#endif  // INCLUDE_PERFETTO_TRACING_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidEnergyConsumerDescriptor;
+class AndroidEnergyConsumer;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidEnergyConsumerDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kEnergyConsumersFieldNumber = 1,
+  };
+
+  AndroidEnergyConsumerDescriptor();
+  ~AndroidEnergyConsumerDescriptor() override;
+  AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept;
+  AndroidEnergyConsumerDescriptor& operator=(AndroidEnergyConsumerDescriptor&&);
+  AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&);
+  AndroidEnergyConsumerDescriptor& operator=(const AndroidEnergyConsumerDescriptor&);
+  bool operator==(const AndroidEnergyConsumerDescriptor&) const;
+  bool operator!=(const AndroidEnergyConsumerDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<AndroidEnergyConsumer>& energy_consumers() const { return energy_consumers_; }
+  std::vector<AndroidEnergyConsumer>* mutable_energy_consumers() { return &energy_consumers_; }
+  int energy_consumers_size() const;
+  void clear_energy_consumers();
+  AndroidEnergyConsumer* add_energy_consumers();
+
+ private:
+  std::vector<AndroidEnergyConsumer> energy_consumers_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT AndroidEnergyConsumer : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kEnergyConsumerIdFieldNumber = 1,
+    kOrdinalFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kNameFieldNumber = 4,
+  };
+
+  AndroidEnergyConsumer();
+  ~AndroidEnergyConsumer() override;
+  AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept;
+  AndroidEnergyConsumer& operator=(AndroidEnergyConsumer&&);
+  AndroidEnergyConsumer(const AndroidEnergyConsumer&);
+  AndroidEnergyConsumer& operator=(const AndroidEnergyConsumer&);
+  bool operator==(const AndroidEnergyConsumer&) const;
+  bool operator!=(const AndroidEnergyConsumer& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_energy_consumer_id() const { return _has_field_[1]; }
+  int32_t energy_consumer_id() const { return energy_consumer_id_; }
+  void set_energy_consumer_id(int32_t value) { energy_consumer_id_ = value; _has_field_.set(1); }
+
+  bool has_ordinal() const { return _has_field_[2]; }
+  int32_t ordinal() const { return ordinal_; }
+  void set_ordinal(int32_t value) { ordinal_ = value; _has_field_.set(2); }
+
+  bool has_type() const { return _has_field_[3]; }
+  const std::string& type() const { return type_; }
+  void set_type(const std::string& value) { type_ = value; _has_field_.set(3); }
+
+  bool has_name() const { return _has_field_[4]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(4); }
+
+ private:
+  int32_t energy_consumer_id_{};
+  int32_t ordinal_{};
+  std::string type_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/android_log_constants.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AndroidLogId : int;
+enum AndroidLogPriority : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AndroidLogId : int {
+  LID_DEFAULT = 0,
+  LID_RADIO = 1,
+  LID_EVENTS = 2,
+  LID_SYSTEM = 3,
+  LID_CRASH = 4,
+  LID_STATS = 5,
+  LID_SECURITY = 6,
+  LID_KERNEL = 7,
+};
+enum AndroidLogPriority : int {
+  PRIO_UNSPECIFIED = 0,
+  PRIO_UNUSED = 1,
+  PRIO_VERBOSE = 2,
+  PRIO_DEBUG = 3,
+  PRIO_INFO = 4,
+  PRIO_WARN = 5,
+  PRIO_ERROR = 6,
+  PRIO_FATAL = 7,
+};
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/builtin_clock.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum BuiltinClock : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum BuiltinClock : int {
+  BUILTIN_CLOCK_UNKNOWN = 0,
+  BUILTIN_CLOCK_REALTIME = 1,
+  BUILTIN_CLOCK_REALTIME_COARSE = 2,
+  BUILTIN_CLOCK_MONOTONIC = 3,
+  BUILTIN_CLOCK_MONOTONIC_COARSE = 4,
+  BUILTIN_CLOCK_MONOTONIC_RAW = 5,
+  BUILTIN_CLOCK_BOOTTIME = 6,
+  BUILTIN_CLOCK_MAX_ID = 63,
+};
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/commit_data_request.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class CommitDataRequest;
+class CommitDataRequest_ChunkToPatch;
+class CommitDataRequest_ChunkToPatch_Patch;
+class CommitDataRequest_ChunksToMove;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT CommitDataRequest : public ::protozero::CppMessageObj {
+ public:
+  using ChunksToMove = CommitDataRequest_ChunksToMove;
+  using ChunkToPatch = CommitDataRequest_ChunkToPatch;
+  enum FieldNumbers {
+    kChunksToMoveFieldNumber = 1,
+    kChunksToPatchFieldNumber = 2,
+    kFlushRequestIdFieldNumber = 3,
+  };
+
+  CommitDataRequest();
+  ~CommitDataRequest() override;
+  CommitDataRequest(CommitDataRequest&&) noexcept;
+  CommitDataRequest& operator=(CommitDataRequest&&);
+  CommitDataRequest(const CommitDataRequest&);
+  CommitDataRequest& operator=(const CommitDataRequest&);
+  bool operator==(const CommitDataRequest&) const;
+  bool operator!=(const CommitDataRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<CommitDataRequest_ChunksToMove>& chunks_to_move() const { return chunks_to_move_; }
+  std::vector<CommitDataRequest_ChunksToMove>* mutable_chunks_to_move() { return &chunks_to_move_; }
+  int chunks_to_move_size() const;
+  void clear_chunks_to_move();
+  CommitDataRequest_ChunksToMove* add_chunks_to_move();
+
+  const std::vector<CommitDataRequest_ChunkToPatch>& chunks_to_patch() const { return chunks_to_patch_; }
+  std::vector<CommitDataRequest_ChunkToPatch>* mutable_chunks_to_patch() { return &chunks_to_patch_; }
+  int chunks_to_patch_size() const;
+  void clear_chunks_to_patch();
+  CommitDataRequest_ChunkToPatch* add_chunks_to_patch();
+
+  bool has_flush_request_id() const { return _has_field_[3]; }
+  uint64_t flush_request_id() const { return flush_request_id_; }
+  void set_flush_request_id(uint64_t value) { flush_request_id_ = value; _has_field_.set(3); }
+
+ private:
+  std::vector<CommitDataRequest_ChunksToMove> chunks_to_move_;
+  std::vector<CommitDataRequest_ChunkToPatch> chunks_to_patch_;
+  uint64_t flush_request_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT CommitDataRequest_ChunkToPatch : public ::protozero::CppMessageObj {
+ public:
+  using Patch = CommitDataRequest_ChunkToPatch_Patch;
+  enum FieldNumbers {
+    kTargetBufferFieldNumber = 1,
+    kWriterIdFieldNumber = 2,
+    kChunkIdFieldNumber = 3,
+    kPatchesFieldNumber = 4,
+    kHasMorePatchesFieldNumber = 5,
+  };
+
+  CommitDataRequest_ChunkToPatch();
+  ~CommitDataRequest_ChunkToPatch() override;
+  CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept;
+  CommitDataRequest_ChunkToPatch& operator=(CommitDataRequest_ChunkToPatch&&);
+  CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&);
+  CommitDataRequest_ChunkToPatch& operator=(const CommitDataRequest_ChunkToPatch&);
+  bool operator==(const CommitDataRequest_ChunkToPatch&) const;
+  bool operator!=(const CommitDataRequest_ChunkToPatch& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_target_buffer() const { return _has_field_[1]; }
+  uint32_t target_buffer() const { return target_buffer_; }
+  void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(1); }
+
+  bool has_writer_id() const { return _has_field_[2]; }
+  uint32_t writer_id() const { return writer_id_; }
+  void set_writer_id(uint32_t value) { writer_id_ = value; _has_field_.set(2); }
+
+  bool has_chunk_id() const { return _has_field_[3]; }
+  uint32_t chunk_id() const { return chunk_id_; }
+  void set_chunk_id(uint32_t value) { chunk_id_ = value; _has_field_.set(3); }
+
+  const std::vector<CommitDataRequest_ChunkToPatch_Patch>& patches() const { return patches_; }
+  std::vector<CommitDataRequest_ChunkToPatch_Patch>* mutable_patches() { return &patches_; }
+  int patches_size() const;
+  void clear_patches();
+  CommitDataRequest_ChunkToPatch_Patch* add_patches();
+
+  bool has_has_more_patches() const { return _has_field_[5]; }
+  bool has_more_patches() const { return has_more_patches_; }
+  void set_has_more_patches(bool value) { has_more_patches_ = value; _has_field_.set(5); }
+
+ private:
+  uint32_t target_buffer_{};
+  uint32_t writer_id_{};
+  uint32_t chunk_id_{};
+  std::vector<CommitDataRequest_ChunkToPatch_Patch> patches_;
+  bool has_more_patches_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT CommitDataRequest_ChunkToPatch_Patch : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kOffsetFieldNumber = 1,
+    kDataFieldNumber = 2,
+  };
+
+  CommitDataRequest_ChunkToPatch_Patch();
+  ~CommitDataRequest_ChunkToPatch_Patch() override;
+  CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept;
+  CommitDataRequest_ChunkToPatch_Patch& operator=(CommitDataRequest_ChunkToPatch_Patch&&);
+  CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&);
+  CommitDataRequest_ChunkToPatch_Patch& operator=(const CommitDataRequest_ChunkToPatch_Patch&);
+  bool operator==(const CommitDataRequest_ChunkToPatch_Patch&) const;
+  bool operator!=(const CommitDataRequest_ChunkToPatch_Patch& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_offset() const { return _has_field_[1]; }
+  uint32_t offset() const { return offset_; }
+  void set_offset(uint32_t value) { offset_ = value; _has_field_.set(1); }
+
+  bool has_data() const { return _has_field_[2]; }
+  const std::string& data() const { return data_; }
+  void set_data(const std::string& value) { data_ = value; _has_field_.set(2); }
+  void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
+
+ private:
+  uint32_t offset_{};
+  std::string data_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT CommitDataRequest_ChunksToMove : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPageFieldNumber = 1,
+    kChunkFieldNumber = 2,
+    kTargetBufferFieldNumber = 3,
+    kDataFieldNumber = 4,
+  };
+
+  CommitDataRequest_ChunksToMove();
+  ~CommitDataRequest_ChunksToMove() override;
+  CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept;
+  CommitDataRequest_ChunksToMove& operator=(CommitDataRequest_ChunksToMove&&);
+  CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&);
+  CommitDataRequest_ChunksToMove& operator=(const CommitDataRequest_ChunksToMove&);
+  bool operator==(const CommitDataRequest_ChunksToMove&) const;
+  bool operator!=(const CommitDataRequest_ChunksToMove& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_page() const { return _has_field_[1]; }
+  uint32_t page() const { return page_; }
+  void set_page(uint32_t value) { page_ = value; _has_field_.set(1); }
+
+  bool has_chunk() const { return _has_field_[2]; }
+  uint32_t chunk() const { return chunk_; }
+  void set_chunk(uint32_t value) { chunk_ = value; _has_field_.set(2); }
+
+  bool has_target_buffer() const { return _has_field_[3]; }
+  uint32_t target_buffer() const { return target_buffer_; }
+  void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(3); }
+
+  bool has_data() const { return _has_field_[4]; }
+  const std::string& data() const { return data_; }
+  void set_data(const std::string& value) { data_ = value; _has_field_.set(4); }
+  void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(4); }
+
+ private:
+  uint32_t page_{};
+  uint32_t chunk_{};
+  uint32_t target_buffer_{};
+  std::string data_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class OneofOptions;
+class EnumValueDescriptorProto;
+class EnumDescriptorProto;
+class OneofDescriptorProto;
+class FieldDescriptorProto;
+class FieldOptions;
+class UninterpretedOption;
+class UninterpretedOption_NamePart;
+class DescriptorProto;
+class DescriptorProto_ReservedRange;
+class FileDescriptorProto;
+class FileDescriptorSet;
+enum FieldDescriptorProto_Type : int;
+enum FieldDescriptorProto_Label : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum FieldDescriptorProto_Type : int {
+  FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
+  FieldDescriptorProto_Type_TYPE_FLOAT = 2,
+  FieldDescriptorProto_Type_TYPE_INT64 = 3,
+  FieldDescriptorProto_Type_TYPE_UINT64 = 4,
+  FieldDescriptorProto_Type_TYPE_INT32 = 5,
+  FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
+  FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
+  FieldDescriptorProto_Type_TYPE_BOOL = 8,
+  FieldDescriptorProto_Type_TYPE_STRING = 9,
+  FieldDescriptorProto_Type_TYPE_GROUP = 10,
+  FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
+  FieldDescriptorProto_Type_TYPE_BYTES = 12,
+  FieldDescriptorProto_Type_TYPE_UINT32 = 13,
+  FieldDescriptorProto_Type_TYPE_ENUM = 14,
+  FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
+  FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
+  FieldDescriptorProto_Type_TYPE_SINT32 = 17,
+  FieldDescriptorProto_Type_TYPE_SINT64 = 18,
+};
+enum FieldDescriptorProto_Label : int {
+  FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
+  FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
+  FieldDescriptorProto_Label_LABEL_REPEATED = 3,
+};
+
+class PERFETTO_EXPORT_COMPONENT OneofOptions : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  OneofOptions();
+  ~OneofOptions() override;
+  OneofOptions(OneofOptions&&) noexcept;
+  OneofOptions& operator=(OneofOptions&&);
+  OneofOptions(const OneofOptions&);
+  OneofOptions& operator=(const OneofOptions&);
+  bool operator==(const OneofOptions&) const;
+  bool operator!=(const OneofOptions& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT EnumValueDescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kNumberFieldNumber = 2,
+  };
+
+  EnumValueDescriptorProto();
+  ~EnumValueDescriptorProto() override;
+  EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept;
+  EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&&);
+  EnumValueDescriptorProto(const EnumValueDescriptorProto&);
+  EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto&);
+  bool operator==(const EnumValueDescriptorProto&) const;
+  bool operator!=(const EnumValueDescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_number() const { return _has_field_[2]; }
+  int32_t number() const { return number_; }
+  void set_number(int32_t value) { number_ = value; _has_field_.set(2); }
+
+ private:
+  std::string name_{};
+  int32_t number_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT EnumDescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+    kReservedNameFieldNumber = 5,
+  };
+
+  EnumDescriptorProto();
+  ~EnumDescriptorProto() override;
+  EnumDescriptorProto(EnumDescriptorProto&&) noexcept;
+  EnumDescriptorProto& operator=(EnumDescriptorProto&&);
+  EnumDescriptorProto(const EnumDescriptorProto&);
+  EnumDescriptorProto& operator=(const EnumDescriptorProto&);
+  bool operator==(const EnumDescriptorProto&) const;
+  bool operator!=(const EnumDescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  const std::vector<EnumValueDescriptorProto>& value() const { return value_; }
+  std::vector<EnumValueDescriptorProto>* mutable_value() { return &value_; }
+  int value_size() const;
+  void clear_value();
+  EnumValueDescriptorProto* add_value();
+
+  const std::vector<std::string>& reserved_name() const { return reserved_name_; }
+  std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
+  int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
+  void clear_reserved_name() { reserved_name_.clear(); }
+  void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
+  std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
+
+ private:
+  std::string name_{};
+  std::vector<EnumValueDescriptorProto> value_;
+  std::vector<std::string> reserved_name_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT OneofDescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kOptionsFieldNumber = 2,
+  };
+
+  OneofDescriptorProto();
+  ~OneofDescriptorProto() override;
+  OneofDescriptorProto(OneofDescriptorProto&&) noexcept;
+  OneofDescriptorProto& operator=(OneofDescriptorProto&&);
+  OneofDescriptorProto(const OneofDescriptorProto&);
+  OneofDescriptorProto& operator=(const OneofDescriptorProto&);
+  bool operator==(const OneofDescriptorProto&) const;
+  bool operator!=(const OneofDescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_options() const { return _has_field_[2]; }
+  const OneofOptions& options() const { return *options_; }
+  OneofOptions* mutable_options() { _has_field_.set(2); return options_.get(); }
+
+ private:
+  std::string name_{};
+  ::protozero::CopyablePtr<OneofOptions> options_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FieldDescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  using Type = FieldDescriptorProto_Type;
+  static constexpr auto TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
+  static constexpr auto TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
+  static constexpr auto TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
+  static constexpr auto TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
+  static constexpr auto TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
+  static constexpr auto TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
+  static constexpr auto TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
+  static constexpr auto TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
+  static constexpr auto TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
+  static constexpr auto TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
+  static constexpr auto TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
+  static constexpr auto TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
+  static constexpr auto TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
+  static constexpr auto TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
+  static constexpr auto TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
+  static constexpr auto TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
+  static constexpr auto TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
+  static constexpr auto TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
+  static constexpr auto Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
+  static constexpr auto Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
+  using Label = FieldDescriptorProto_Label;
+  static constexpr auto LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+  static constexpr auto LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
+  static constexpr auto LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
+  static constexpr auto Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
+  static constexpr auto Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kNumberFieldNumber = 3,
+    kLabelFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kTypeNameFieldNumber = 6,
+    kExtendeeFieldNumber = 2,
+    kDefaultValueFieldNumber = 7,
+    kOptionsFieldNumber = 8,
+    kOneofIndexFieldNumber = 9,
+  };
+
+  FieldDescriptorProto();
+  ~FieldDescriptorProto() override;
+  FieldDescriptorProto(FieldDescriptorProto&&) noexcept;
+  FieldDescriptorProto& operator=(FieldDescriptorProto&&);
+  FieldDescriptorProto(const FieldDescriptorProto&);
+  FieldDescriptorProto& operator=(const FieldDescriptorProto&);
+  bool operator==(const FieldDescriptorProto&) const;
+  bool operator!=(const FieldDescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_number() const { return _has_field_[3]; }
+  int32_t number() const { return number_; }
+  void set_number(int32_t value) { number_ = value; _has_field_.set(3); }
+
+  bool has_label() const { return _has_field_[4]; }
+  FieldDescriptorProto_Label label() const { return label_; }
+  void set_label(FieldDescriptorProto_Label value) { label_ = value; _has_field_.set(4); }
+
+  bool has_type() const { return _has_field_[5]; }
+  FieldDescriptorProto_Type type() const { return type_; }
+  void set_type(FieldDescriptorProto_Type value) { type_ = value; _has_field_.set(5); }
+
+  bool has_type_name() const { return _has_field_[6]; }
+  const std::string& type_name() const { return type_name_; }
+  void set_type_name(const std::string& value) { type_name_ = value; _has_field_.set(6); }
+
+  bool has_extendee() const { return _has_field_[2]; }
+  const std::string& extendee() const { return extendee_; }
+  void set_extendee(const std::string& value) { extendee_ = value; _has_field_.set(2); }
+
+  bool has_default_value() const { return _has_field_[7]; }
+  const std::string& default_value() const { return default_value_; }
+  void set_default_value(const std::string& value) { default_value_ = value; _has_field_.set(7); }
+
+  bool has_options() const { return _has_field_[8]; }
+  const FieldOptions& options() const { return *options_; }
+  FieldOptions* mutable_options() { _has_field_.set(8); return options_.get(); }
+
+  bool has_oneof_index() const { return _has_field_[9]; }
+  int32_t oneof_index() const { return oneof_index_; }
+  void set_oneof_index(int32_t value) { oneof_index_ = value; _has_field_.set(9); }
+
+ private:
+  std::string name_{};
+  int32_t number_{};
+  FieldDescriptorProto_Label label_{};
+  FieldDescriptorProto_Type type_{};
+  std::string type_name_{};
+  std::string extendee_{};
+  std::string default_value_{};
+  ::protozero::CopyablePtr<FieldOptions> options_;
+  int32_t oneof_index_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<10> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FieldOptions : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPackedFieldNumber = 2,
+    kUninterpretedOptionFieldNumber = 999,
+  };
+
+  FieldOptions();
+  ~FieldOptions() override;
+  FieldOptions(FieldOptions&&) noexcept;
+  FieldOptions& operator=(FieldOptions&&);
+  FieldOptions(const FieldOptions&);
+  FieldOptions& operator=(const FieldOptions&);
+  bool operator==(const FieldOptions&) const;
+  bool operator!=(const FieldOptions& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_packed() const { return _has_field_[2]; }
+  bool packed() const { return packed_; }
+  void set_packed(bool value) { packed_ = value; _has_field_.set(2); }
+
+  const std::vector<UninterpretedOption>& uninterpreted_option() const { return uninterpreted_option_; }
+  std::vector<UninterpretedOption>* mutable_uninterpreted_option() { return &uninterpreted_option_; }
+  int uninterpreted_option_size() const;
+  void clear_uninterpreted_option();
+  UninterpretedOption* add_uninterpreted_option();
+
+ private:
+  bool packed_{};
+  std::vector<UninterpretedOption> uninterpreted_option_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<1000> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UninterpretedOption : public ::protozero::CppMessageObj {
+ public:
+  using NamePart = UninterpretedOption_NamePart;
+  enum FieldNumbers {
+    kNameFieldNumber = 2,
+    kIdentifierValueFieldNumber = 3,
+    kPositiveIntValueFieldNumber = 4,
+    kNegativeIntValueFieldNumber = 5,
+    kDoubleValueFieldNumber = 6,
+    kStringValueFieldNumber = 7,
+    kAggregateValueFieldNumber = 8,
+  };
+
+  UninterpretedOption();
+  ~UninterpretedOption() override;
+  UninterpretedOption(UninterpretedOption&&) noexcept;
+  UninterpretedOption& operator=(UninterpretedOption&&);
+  UninterpretedOption(const UninterpretedOption&);
+  UninterpretedOption& operator=(const UninterpretedOption&);
+  bool operator==(const UninterpretedOption&) const;
+  bool operator!=(const UninterpretedOption& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<UninterpretedOption_NamePart>& name() const { return name_; }
+  std::vector<UninterpretedOption_NamePart>* mutable_name() { return &name_; }
+  int name_size() const;
+  void clear_name();
+  UninterpretedOption_NamePart* add_name();
+
+  bool has_identifier_value() const { return _has_field_[3]; }
+  const std::string& identifier_value() const { return identifier_value_; }
+  void set_identifier_value(const std::string& value) { identifier_value_ = value; _has_field_.set(3); }
+
+  bool has_positive_int_value() const { return _has_field_[4]; }
+  uint64_t positive_int_value() const { return positive_int_value_; }
+  void set_positive_int_value(uint64_t value) { positive_int_value_ = value; _has_field_.set(4); }
+
+  bool has_negative_int_value() const { return _has_field_[5]; }
+  int64_t negative_int_value() const { return negative_int_value_; }
+  void set_negative_int_value(int64_t value) { negative_int_value_ = value; _has_field_.set(5); }
+
+  bool has_double_value() const { return _has_field_[6]; }
+  double double_value() const { return double_value_; }
+  void set_double_value(double value) { double_value_ = value; _has_field_.set(6); }
+
+  bool has_string_value() const { return _has_field_[7]; }
+  const std::string& string_value() const { return string_value_; }
+  void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(7); }
+  void set_string_value(const void* p, size_t s) { string_value_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(7); }
+
+  bool has_aggregate_value() const { return _has_field_[8]; }
+  const std::string& aggregate_value() const { return aggregate_value_; }
+  void set_aggregate_value(const std::string& value) { aggregate_value_ = value; _has_field_.set(8); }
+
+ private:
+  std::vector<UninterpretedOption_NamePart> name_;
+  std::string identifier_value_{};
+  uint64_t positive_int_value_{};
+  int64_t negative_int_value_{};
+  double double_value_{};
+  std::string string_value_{};
+  std::string aggregate_value_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UninterpretedOption_NamePart : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNamePartFieldNumber = 1,
+    kIsExtensionFieldNumber = 2,
+  };
+
+  UninterpretedOption_NamePart();
+  ~UninterpretedOption_NamePart() override;
+  UninterpretedOption_NamePart(UninterpretedOption_NamePart&&) noexcept;
+  UninterpretedOption_NamePart& operator=(UninterpretedOption_NamePart&&);
+  UninterpretedOption_NamePart(const UninterpretedOption_NamePart&);
+  UninterpretedOption_NamePart& operator=(const UninterpretedOption_NamePart&);
+  bool operator==(const UninterpretedOption_NamePart&) const;
+  bool operator!=(const UninterpretedOption_NamePart& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name_part() const { return _has_field_[1]; }
+  const std::string& name_part() const { return name_part_; }
+  void set_name_part(const std::string& value) { name_part_ = value; _has_field_.set(1); }
+
+  bool has_is_extension() const { return _has_field_[2]; }
+  bool is_extension() const { return is_extension_; }
+  void set_is_extension(bool value) { is_extension_ = value; _has_field_.set(2); }
+
+ private:
+  std::string name_part_{};
+  bool is_extension_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  using ReservedRange = DescriptorProto_ReservedRange;
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kFieldFieldNumber = 2,
+    kExtensionFieldNumber = 6,
+    kNestedTypeFieldNumber = 3,
+    kEnumTypeFieldNumber = 4,
+    kOneofDeclFieldNumber = 8,
+    kReservedRangeFieldNumber = 9,
+    kReservedNameFieldNumber = 10,
+  };
+
+  DescriptorProto();
+  ~DescriptorProto() override;
+  DescriptorProto(DescriptorProto&&) noexcept;
+  DescriptorProto& operator=(DescriptorProto&&);
+  DescriptorProto(const DescriptorProto&);
+  DescriptorProto& operator=(const DescriptorProto&);
+  bool operator==(const DescriptorProto&) const;
+  bool operator!=(const DescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  const std::vector<FieldDescriptorProto>& field() const { return field_; }
+  std::vector<FieldDescriptorProto>* mutable_field() { return &field_; }
+  int field_size() const;
+  void clear_field();
+  FieldDescriptorProto* add_field();
+
+  const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
+  std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
+  int extension_size() const;
+  void clear_extension();
+  FieldDescriptorProto* add_extension();
+
+  const std::vector<DescriptorProto>& nested_type() const { return nested_type_; }
+  std::vector<DescriptorProto>* mutable_nested_type() { return &nested_type_; }
+  int nested_type_size() const;
+  void clear_nested_type();
+  DescriptorProto* add_nested_type();
+
+  const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
+  std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
+  int enum_type_size() const;
+  void clear_enum_type();
+  EnumDescriptorProto* add_enum_type();
+
+  const std::vector<OneofDescriptorProto>& oneof_decl() const { return oneof_decl_; }
+  std::vector<OneofDescriptorProto>* mutable_oneof_decl() { return &oneof_decl_; }
+  int oneof_decl_size() const;
+  void clear_oneof_decl();
+  OneofDescriptorProto* add_oneof_decl();
+
+  const std::vector<DescriptorProto_ReservedRange>& reserved_range() const { return reserved_range_; }
+  std::vector<DescriptorProto_ReservedRange>* mutable_reserved_range() { return &reserved_range_; }
+  int reserved_range_size() const;
+  void clear_reserved_range();
+  DescriptorProto_ReservedRange* add_reserved_range();
+
+  const std::vector<std::string>& reserved_name() const { return reserved_name_; }
+  std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
+  int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
+  void clear_reserved_name() { reserved_name_.clear(); }
+  void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
+  std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
+
+ private:
+  std::string name_{};
+  std::vector<FieldDescriptorProto> field_;
+  std::vector<FieldDescriptorProto> extension_;
+  std::vector<DescriptorProto> nested_type_;
+  std::vector<EnumDescriptorProto> enum_type_;
+  std::vector<OneofDescriptorProto> oneof_decl_;
+  std::vector<DescriptorProto_ReservedRange> reserved_range_;
+  std::vector<std::string> reserved_name_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<11> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DescriptorProto_ReservedRange : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kStartFieldNumber = 1,
+    kEndFieldNumber = 2,
+  };
+
+  DescriptorProto_ReservedRange();
+  ~DescriptorProto_ReservedRange() override;
+  DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept;
+  DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&&);
+  DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&);
+  DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange&);
+  bool operator==(const DescriptorProto_ReservedRange&) const;
+  bool operator!=(const DescriptorProto_ReservedRange& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_start() const { return _has_field_[1]; }
+  int32_t start() const { return start_; }
+  void set_start(int32_t value) { start_ = value; _has_field_.set(1); }
+
+  bool has_end() const { return _has_field_[2]; }
+  int32_t end() const { return end_; }
+  void set_end(int32_t value) { end_ = value; _has_field_.set(2); }
+
+ private:
+  int32_t start_{};
+  int32_t end_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FileDescriptorProto : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kPackageFieldNumber = 2,
+    kDependencyFieldNumber = 3,
+    kPublicDependencyFieldNumber = 10,
+    kWeakDependencyFieldNumber = 11,
+    kMessageTypeFieldNumber = 4,
+    kEnumTypeFieldNumber = 5,
+    kExtensionFieldNumber = 7,
+  };
+
+  FileDescriptorProto();
+  ~FileDescriptorProto() override;
+  FileDescriptorProto(FileDescriptorProto&&) noexcept;
+  FileDescriptorProto& operator=(FileDescriptorProto&&);
+  FileDescriptorProto(const FileDescriptorProto&);
+  FileDescriptorProto& operator=(const FileDescriptorProto&);
+  bool operator==(const FileDescriptorProto&) const;
+  bool operator!=(const FileDescriptorProto& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_package() const { return _has_field_[2]; }
+  const std::string& package() const { return package_; }
+  void set_package(const std::string& value) { package_ = value; _has_field_.set(2); }
+
+  const std::vector<std::string>& dependency() const { return dependency_; }
+  std::vector<std::string>* mutable_dependency() { return &dependency_; }
+  int dependency_size() const { return static_cast<int>(dependency_.size()); }
+  void clear_dependency() { dependency_.clear(); }
+  void add_dependency(std::string value) { dependency_.emplace_back(value); }
+  std::string* add_dependency() { dependency_.emplace_back(); return &dependency_.back(); }
+
+  const std::vector<int32_t>& public_dependency() const { return public_dependency_; }
+  std::vector<int32_t>* mutable_public_dependency() { return &public_dependency_; }
+  int public_dependency_size() const { return static_cast<int>(public_dependency_.size()); }
+  void clear_public_dependency() { public_dependency_.clear(); }
+  void add_public_dependency(int32_t value) { public_dependency_.emplace_back(value); }
+  int32_t* add_public_dependency() { public_dependency_.emplace_back(); return &public_dependency_.back(); }
+
+  const std::vector<int32_t>& weak_dependency() const { return weak_dependency_; }
+  std::vector<int32_t>* mutable_weak_dependency() { return &weak_dependency_; }
+  int weak_dependency_size() const { return static_cast<int>(weak_dependency_.size()); }
+  void clear_weak_dependency() { weak_dependency_.clear(); }
+  void add_weak_dependency(int32_t value) { weak_dependency_.emplace_back(value); }
+  int32_t* add_weak_dependency() { weak_dependency_.emplace_back(); return &weak_dependency_.back(); }
+
+  const std::vector<DescriptorProto>& message_type() const { return message_type_; }
+  std::vector<DescriptorProto>* mutable_message_type() { return &message_type_; }
+  int message_type_size() const;
+  void clear_message_type();
+  DescriptorProto* add_message_type();
+
+  const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
+  std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
+  int enum_type_size() const;
+  void clear_enum_type();
+  EnumDescriptorProto* add_enum_type();
+
+  const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
+  std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
+  int extension_size() const;
+  void clear_extension();
+  FieldDescriptorProto* add_extension();
+
+ private:
+  std::string name_{};
+  std::string package_{};
+  std::vector<std::string> dependency_;
+  std::vector<int32_t> public_dependency_;
+  std::vector<int32_t> weak_dependency_;
+  std::vector<DescriptorProto> message_type_;
+  std::vector<EnumDescriptorProto> enum_type_;
+  std::vector<FieldDescriptorProto> extension_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<12> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FileDescriptorSet : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kFileFieldNumber = 1,
+  };
+
+  FileDescriptorSet();
+  ~FileDescriptorSet() override;
+  FileDescriptorSet(FileDescriptorSet&&) noexcept;
+  FileDescriptorSet& operator=(FileDescriptorSet&&);
+  FileDescriptorSet(const FileDescriptorSet&);
+  FileDescriptorSet& operator=(const FileDescriptorSet&);
+  bool operator==(const FileDescriptorSet&) const;
+  bool operator!=(const FileDescriptorSet& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<FileDescriptorProto>& file() const { return file_; }
+  std::vector<FileDescriptorProto>* mutable_file() { return &file_; }
+  int file_size() const;
+  void clear_file();
+  FileDescriptorProto* add_file();
+
+ private:
+  std::vector<FileDescriptorProto> file_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/ftrace_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_FTRACE_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_FTRACE_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class FtraceDescriptor;
+class FtraceDescriptor_AtraceCategory;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT FtraceDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using AtraceCategory = FtraceDescriptor_AtraceCategory;
+  enum FieldNumbers {
+    kAtraceCategoriesFieldNumber = 1,
+  };
+
+  FtraceDescriptor();
+  ~FtraceDescriptor() override;
+  FtraceDescriptor(FtraceDescriptor&&) noexcept;
+  FtraceDescriptor& operator=(FtraceDescriptor&&);
+  FtraceDescriptor(const FtraceDescriptor&);
+  FtraceDescriptor& operator=(const FtraceDescriptor&);
+  bool operator==(const FtraceDescriptor&) const;
+  bool operator!=(const FtraceDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<FtraceDescriptor_AtraceCategory>& atrace_categories() const { return atrace_categories_; }
+  std::vector<FtraceDescriptor_AtraceCategory>* mutable_atrace_categories() { return &atrace_categories_; }
+  int atrace_categories_size() const;
+  void clear_atrace_categories();
+  FtraceDescriptor_AtraceCategory* add_atrace_categories();
+
+ private:
+  std::vector<FtraceDescriptor_AtraceCategory> atrace_categories_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FtraceDescriptor_AtraceCategory : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kDescriptionFieldNumber = 2,
+  };
+
+  FtraceDescriptor_AtraceCategory();
+  ~FtraceDescriptor_AtraceCategory() override;
+  FtraceDescriptor_AtraceCategory(FtraceDescriptor_AtraceCategory&&) noexcept;
+  FtraceDescriptor_AtraceCategory& operator=(FtraceDescriptor_AtraceCategory&&);
+  FtraceDescriptor_AtraceCategory(const FtraceDescriptor_AtraceCategory&);
+  FtraceDescriptor_AtraceCategory& operator=(const FtraceDescriptor_AtraceCategory&);
+  bool operator==(const FtraceDescriptor_AtraceCategory&) const;
+  bool operator!=(const FtraceDescriptor_AtraceCategory& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_description() const { return _has_field_[2]; }
+  const std::string& description() const { return description_; }
+  void set_description(const std::string& value) { description_ = value; _has_field_.set(2); }
+
+ private:
+  std::string name_{};
+  std::string description_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_FTRACE_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/gpu_counter_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class GpuCounterDescriptor;
+class GpuCounterDescriptor_GpuCounterBlock;
+class GpuCounterDescriptor_GpuCounterSpec;
+enum GpuCounterDescriptor_GpuCounterGroup : int;
+enum GpuCounterDescriptor_MeasureUnit : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum GpuCounterDescriptor_GpuCounterGroup : int {
+  GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED = 0,
+  GpuCounterDescriptor_GpuCounterGroup_SYSTEM = 1,
+  GpuCounterDescriptor_GpuCounterGroup_VERTICES = 2,
+  GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS = 3,
+  GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES = 4,
+  GpuCounterDescriptor_GpuCounterGroup_MEMORY = 5,
+  GpuCounterDescriptor_GpuCounterGroup_COMPUTE = 6,
+};
+enum GpuCounterDescriptor_MeasureUnit : int {
+  GpuCounterDescriptor_MeasureUnit_NONE = 0,
+  GpuCounterDescriptor_MeasureUnit_BIT = 1,
+  GpuCounterDescriptor_MeasureUnit_KILOBIT = 2,
+  GpuCounterDescriptor_MeasureUnit_MEGABIT = 3,
+  GpuCounterDescriptor_MeasureUnit_GIGABIT = 4,
+  GpuCounterDescriptor_MeasureUnit_TERABIT = 5,
+  GpuCounterDescriptor_MeasureUnit_PETABIT = 6,
+  GpuCounterDescriptor_MeasureUnit_BYTE = 7,
+  GpuCounterDescriptor_MeasureUnit_KILOBYTE = 8,
+  GpuCounterDescriptor_MeasureUnit_MEGABYTE = 9,
+  GpuCounterDescriptor_MeasureUnit_GIGABYTE = 10,
+  GpuCounterDescriptor_MeasureUnit_TERABYTE = 11,
+  GpuCounterDescriptor_MeasureUnit_PETABYTE = 12,
+  GpuCounterDescriptor_MeasureUnit_HERTZ = 13,
+  GpuCounterDescriptor_MeasureUnit_KILOHERTZ = 14,
+  GpuCounterDescriptor_MeasureUnit_MEGAHERTZ = 15,
+  GpuCounterDescriptor_MeasureUnit_GIGAHERTZ = 16,
+  GpuCounterDescriptor_MeasureUnit_TERAHERTZ = 17,
+  GpuCounterDescriptor_MeasureUnit_PETAHERTZ = 18,
+  GpuCounterDescriptor_MeasureUnit_NANOSECOND = 19,
+  GpuCounterDescriptor_MeasureUnit_MICROSECOND = 20,
+  GpuCounterDescriptor_MeasureUnit_MILLISECOND = 21,
+  GpuCounterDescriptor_MeasureUnit_SECOND = 22,
+  GpuCounterDescriptor_MeasureUnit_MINUTE = 23,
+  GpuCounterDescriptor_MeasureUnit_HOUR = 24,
+  GpuCounterDescriptor_MeasureUnit_VERTEX = 25,
+  GpuCounterDescriptor_MeasureUnit_PIXEL = 26,
+  GpuCounterDescriptor_MeasureUnit_TRIANGLE = 27,
+  GpuCounterDescriptor_MeasureUnit_PRIMITIVE = 38,
+  GpuCounterDescriptor_MeasureUnit_FRAGMENT = 39,
+  GpuCounterDescriptor_MeasureUnit_MILLIWATT = 28,
+  GpuCounterDescriptor_MeasureUnit_WATT = 29,
+  GpuCounterDescriptor_MeasureUnit_KILOWATT = 30,
+  GpuCounterDescriptor_MeasureUnit_JOULE = 31,
+  GpuCounterDescriptor_MeasureUnit_VOLT = 32,
+  GpuCounterDescriptor_MeasureUnit_AMPERE = 33,
+  GpuCounterDescriptor_MeasureUnit_CELSIUS = 34,
+  GpuCounterDescriptor_MeasureUnit_FAHRENHEIT = 35,
+  GpuCounterDescriptor_MeasureUnit_KELVIN = 36,
+  GpuCounterDescriptor_MeasureUnit_PERCENT = 37,
+  GpuCounterDescriptor_MeasureUnit_INSTRUCTION = 40,
+};
+
+class PERFETTO_EXPORT_COMPONENT GpuCounterDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using GpuCounterSpec = GpuCounterDescriptor_GpuCounterSpec;
+  using GpuCounterBlock = GpuCounterDescriptor_GpuCounterBlock;
+  using GpuCounterGroup = GpuCounterDescriptor_GpuCounterGroup;
+  static constexpr auto UNCLASSIFIED = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
+  static constexpr auto SYSTEM = GpuCounterDescriptor_GpuCounterGroup_SYSTEM;
+  static constexpr auto VERTICES = GpuCounterDescriptor_GpuCounterGroup_VERTICES;
+  static constexpr auto FRAGMENTS = GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS;
+  static constexpr auto PRIMITIVES = GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES;
+  static constexpr auto MEMORY = GpuCounterDescriptor_GpuCounterGroup_MEMORY;
+  static constexpr auto COMPUTE = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
+  static constexpr auto GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
+  static constexpr auto GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
+  using MeasureUnit = GpuCounterDescriptor_MeasureUnit;
+  static constexpr auto NONE = GpuCounterDescriptor_MeasureUnit_NONE;
+  static constexpr auto BIT = GpuCounterDescriptor_MeasureUnit_BIT;
+  static constexpr auto KILOBIT = GpuCounterDescriptor_MeasureUnit_KILOBIT;
+  static constexpr auto MEGABIT = GpuCounterDescriptor_MeasureUnit_MEGABIT;
+  static constexpr auto GIGABIT = GpuCounterDescriptor_MeasureUnit_GIGABIT;
+  static constexpr auto TERABIT = GpuCounterDescriptor_MeasureUnit_TERABIT;
+  static constexpr auto PETABIT = GpuCounterDescriptor_MeasureUnit_PETABIT;
+  static constexpr auto BYTE = GpuCounterDescriptor_MeasureUnit_BYTE;
+  static constexpr auto KILOBYTE = GpuCounterDescriptor_MeasureUnit_KILOBYTE;
+  static constexpr auto MEGABYTE = GpuCounterDescriptor_MeasureUnit_MEGABYTE;
+  static constexpr auto GIGABYTE = GpuCounterDescriptor_MeasureUnit_GIGABYTE;
+  static constexpr auto TERABYTE = GpuCounterDescriptor_MeasureUnit_TERABYTE;
+  static constexpr auto PETABYTE = GpuCounterDescriptor_MeasureUnit_PETABYTE;
+  static constexpr auto HERTZ = GpuCounterDescriptor_MeasureUnit_HERTZ;
+  static constexpr auto KILOHERTZ = GpuCounterDescriptor_MeasureUnit_KILOHERTZ;
+  static constexpr auto MEGAHERTZ = GpuCounterDescriptor_MeasureUnit_MEGAHERTZ;
+  static constexpr auto GIGAHERTZ = GpuCounterDescriptor_MeasureUnit_GIGAHERTZ;
+  static constexpr auto TERAHERTZ = GpuCounterDescriptor_MeasureUnit_TERAHERTZ;
+  static constexpr auto PETAHERTZ = GpuCounterDescriptor_MeasureUnit_PETAHERTZ;
+  static constexpr auto NANOSECOND = GpuCounterDescriptor_MeasureUnit_NANOSECOND;
+  static constexpr auto MICROSECOND = GpuCounterDescriptor_MeasureUnit_MICROSECOND;
+  static constexpr auto MILLISECOND = GpuCounterDescriptor_MeasureUnit_MILLISECOND;
+  static constexpr auto SECOND = GpuCounterDescriptor_MeasureUnit_SECOND;
+  static constexpr auto MINUTE = GpuCounterDescriptor_MeasureUnit_MINUTE;
+  static constexpr auto HOUR = GpuCounterDescriptor_MeasureUnit_HOUR;
+  static constexpr auto VERTEX = GpuCounterDescriptor_MeasureUnit_VERTEX;
+  static constexpr auto PIXEL = GpuCounterDescriptor_MeasureUnit_PIXEL;
+  static constexpr auto TRIANGLE = GpuCounterDescriptor_MeasureUnit_TRIANGLE;
+  static constexpr auto PRIMITIVE = GpuCounterDescriptor_MeasureUnit_PRIMITIVE;
+  static constexpr auto FRAGMENT = GpuCounterDescriptor_MeasureUnit_FRAGMENT;
+  static constexpr auto MILLIWATT = GpuCounterDescriptor_MeasureUnit_MILLIWATT;
+  static constexpr auto WATT = GpuCounterDescriptor_MeasureUnit_WATT;
+  static constexpr auto KILOWATT = GpuCounterDescriptor_MeasureUnit_KILOWATT;
+  static constexpr auto JOULE = GpuCounterDescriptor_MeasureUnit_JOULE;
+  static constexpr auto VOLT = GpuCounterDescriptor_MeasureUnit_VOLT;
+  static constexpr auto AMPERE = GpuCounterDescriptor_MeasureUnit_AMPERE;
+  static constexpr auto CELSIUS = GpuCounterDescriptor_MeasureUnit_CELSIUS;
+  static constexpr auto FAHRENHEIT = GpuCounterDescriptor_MeasureUnit_FAHRENHEIT;
+  static constexpr auto KELVIN = GpuCounterDescriptor_MeasureUnit_KELVIN;
+  static constexpr auto PERCENT = GpuCounterDescriptor_MeasureUnit_PERCENT;
+  static constexpr auto INSTRUCTION = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
+  static constexpr auto MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit_NONE;
+  static constexpr auto MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
+  enum FieldNumbers {
+    kSpecsFieldNumber = 1,
+    kBlocksFieldNumber = 2,
+    kMinSamplingPeriodNsFieldNumber = 3,
+    kMaxSamplingPeriodNsFieldNumber = 4,
+    kSupportsInstrumentedSamplingFieldNumber = 5,
+  };
+
+  GpuCounterDescriptor();
+  ~GpuCounterDescriptor() override;
+  GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept;
+  GpuCounterDescriptor& operator=(GpuCounterDescriptor&&);
+  GpuCounterDescriptor(const GpuCounterDescriptor&);
+  GpuCounterDescriptor& operator=(const GpuCounterDescriptor&);
+  bool operator==(const GpuCounterDescriptor&) const;
+  bool operator!=(const GpuCounterDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<GpuCounterDescriptor_GpuCounterSpec>& specs() const { return specs_; }
+  std::vector<GpuCounterDescriptor_GpuCounterSpec>* mutable_specs() { return &specs_; }
+  int specs_size() const;
+  void clear_specs();
+  GpuCounterDescriptor_GpuCounterSpec* add_specs();
+
+  const std::vector<GpuCounterDescriptor_GpuCounterBlock>& blocks() const { return blocks_; }
+  std::vector<GpuCounterDescriptor_GpuCounterBlock>* mutable_blocks() { return &blocks_; }
+  int blocks_size() const;
+  void clear_blocks();
+  GpuCounterDescriptor_GpuCounterBlock* add_blocks();
+
+  bool has_min_sampling_period_ns() const { return _has_field_[3]; }
+  uint64_t min_sampling_period_ns() const { return min_sampling_period_ns_; }
+  void set_min_sampling_period_ns(uint64_t value) { min_sampling_period_ns_ = value; _has_field_.set(3); }
+
+  bool has_max_sampling_period_ns() const { return _has_field_[4]; }
+  uint64_t max_sampling_period_ns() const { return max_sampling_period_ns_; }
+  void set_max_sampling_period_ns(uint64_t value) { max_sampling_period_ns_ = value; _has_field_.set(4); }
+
+  bool has_supports_instrumented_sampling() const { return _has_field_[5]; }
+  bool supports_instrumented_sampling() const { return supports_instrumented_sampling_; }
+  void set_supports_instrumented_sampling(bool value) { supports_instrumented_sampling_ = value; _has_field_.set(5); }
+
+ private:
+  std::vector<GpuCounterDescriptor_GpuCounterSpec> specs_;
+  std::vector<GpuCounterDescriptor_GpuCounterBlock> blocks_;
+  uint64_t min_sampling_period_ns_{};
+  uint64_t max_sampling_period_ns_{};
+  bool supports_instrumented_sampling_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GpuCounterDescriptor_GpuCounterBlock : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kBlockIdFieldNumber = 1,
+    kBlockCapacityFieldNumber = 2,
+    kNameFieldNumber = 3,
+    kDescriptionFieldNumber = 4,
+    kCounterIdsFieldNumber = 5,
+  };
+
+  GpuCounterDescriptor_GpuCounterBlock();
+  ~GpuCounterDescriptor_GpuCounterBlock() override;
+  GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept;
+  GpuCounterDescriptor_GpuCounterBlock& operator=(GpuCounterDescriptor_GpuCounterBlock&&);
+  GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&);
+  GpuCounterDescriptor_GpuCounterBlock& operator=(const GpuCounterDescriptor_GpuCounterBlock&);
+  bool operator==(const GpuCounterDescriptor_GpuCounterBlock&) const;
+  bool operator!=(const GpuCounterDescriptor_GpuCounterBlock& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_block_id() const { return _has_field_[1]; }
+  uint32_t block_id() const { return block_id_; }
+  void set_block_id(uint32_t value) { block_id_ = value; _has_field_.set(1); }
+
+  bool has_block_capacity() const { return _has_field_[2]; }
+  uint32_t block_capacity() const { return block_capacity_; }
+  void set_block_capacity(uint32_t value) { block_capacity_ = value; _has_field_.set(2); }
+
+  bool has_name() const { return _has_field_[3]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(3); }
+
+  bool has_description() const { return _has_field_[4]; }
+  const std::string& description() const { return description_; }
+  void set_description(const std::string& value) { description_ = value; _has_field_.set(4); }
+
+  const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
+  std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
+  int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
+  void clear_counter_ids() { counter_ids_.clear(); }
+  void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
+  uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
+
+ private:
+  uint32_t block_id_{};
+  uint32_t block_capacity_{};
+  std::string name_{};
+  std::string description_{};
+  std::vector<uint32_t> counter_ids_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GpuCounterDescriptor_GpuCounterSpec : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kCounterIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kDescriptionFieldNumber = 3,
+    kIntPeakValueFieldNumber = 5,
+    kDoublePeakValueFieldNumber = 6,
+    kNumeratorUnitsFieldNumber = 7,
+    kDenominatorUnitsFieldNumber = 8,
+    kSelectByDefaultFieldNumber = 9,
+    kGroupsFieldNumber = 10,
+  };
+
+  GpuCounterDescriptor_GpuCounterSpec();
+  ~GpuCounterDescriptor_GpuCounterSpec() override;
+  GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept;
+  GpuCounterDescriptor_GpuCounterSpec& operator=(GpuCounterDescriptor_GpuCounterSpec&&);
+  GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&);
+  GpuCounterDescriptor_GpuCounterSpec& operator=(const GpuCounterDescriptor_GpuCounterSpec&);
+  bool operator==(const GpuCounterDescriptor_GpuCounterSpec&) const;
+  bool operator!=(const GpuCounterDescriptor_GpuCounterSpec& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_counter_id() const { return _has_field_[1]; }
+  uint32_t counter_id() const { return counter_id_; }
+  void set_counter_id(uint32_t value) { counter_id_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+  bool has_description() const { return _has_field_[3]; }
+  const std::string& description() const { return description_; }
+  void set_description(const std::string& value) { description_ = value; _has_field_.set(3); }
+
+  bool has_int_peak_value() const { return _has_field_[5]; }
+  int64_t int_peak_value() const { return int_peak_value_; }
+  void set_int_peak_value(int64_t value) { int_peak_value_ = value; _has_field_.set(5); }
+
+  bool has_double_peak_value() const { return _has_field_[6]; }
+  double double_peak_value() const { return double_peak_value_; }
+  void set_double_peak_value(double value) { double_peak_value_ = value; _has_field_.set(6); }
+
+  const std::vector<GpuCounterDescriptor_MeasureUnit>& numerator_units() const { return numerator_units_; }
+  std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_numerator_units() { return &numerator_units_; }
+  int numerator_units_size() const { return static_cast<int>(numerator_units_.size()); }
+  void clear_numerator_units() { numerator_units_.clear(); }
+  void add_numerator_units(GpuCounterDescriptor_MeasureUnit value) { numerator_units_.emplace_back(value); }
+  GpuCounterDescriptor_MeasureUnit* add_numerator_units() { numerator_units_.emplace_back(); return &numerator_units_.back(); }
+
+  const std::vector<GpuCounterDescriptor_MeasureUnit>& denominator_units() const { return denominator_units_; }
+  std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_denominator_units() { return &denominator_units_; }
+  int denominator_units_size() const { return static_cast<int>(denominator_units_.size()); }
+  void clear_denominator_units() { denominator_units_.clear(); }
+  void add_denominator_units(GpuCounterDescriptor_MeasureUnit value) { denominator_units_.emplace_back(value); }
+  GpuCounterDescriptor_MeasureUnit* add_denominator_units() { denominator_units_.emplace_back(); return &denominator_units_.back(); }
+
+  bool has_select_by_default() const { return _has_field_[9]; }
+  bool select_by_default() const { return select_by_default_; }
+  void set_select_by_default(bool value) { select_by_default_ = value; _has_field_.set(9); }
+
+  const std::vector<GpuCounterDescriptor_GpuCounterGroup>& groups() const { return groups_; }
+  std::vector<GpuCounterDescriptor_GpuCounterGroup>* mutable_groups() { return &groups_; }
+  int groups_size() const { return static_cast<int>(groups_.size()); }
+  void clear_groups() { groups_.clear(); }
+  void add_groups(GpuCounterDescriptor_GpuCounterGroup value) { groups_.emplace_back(value); }
+  GpuCounterDescriptor_GpuCounterGroup* add_groups() { groups_.emplace_back(); return &groups_.back(); }
+
+ private:
+  uint32_t counter_id_{};
+  std::string name_{};
+  std::string description_{};
+  int64_t int_peak_value_{};
+  double double_peak_value_{};
+  std::vector<GpuCounterDescriptor_MeasureUnit> numerator_units_;
+  std::vector<GpuCounterDescriptor_MeasureUnit> denominator_units_;
+  bool select_by_default_{};
+  std::vector<GpuCounterDescriptor_GpuCounterGroup> groups_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<11> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/interceptor_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class InterceptorDescriptor;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT InterceptorDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+  };
+
+  InterceptorDescriptor();
+  ~InterceptorDescriptor() override;
+  InterceptorDescriptor(InterceptorDescriptor&&) noexcept;
+  InterceptorDescriptor& operator=(InterceptorDescriptor&&);
+  InterceptorDescriptor(const InterceptorDescriptor&);
+  InterceptorDescriptor& operator=(const InterceptorDescriptor&);
+  bool operator==(const InterceptorDescriptor&) const;
+  bool operator!=(const InterceptorDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+ private:
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/observable_events.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ObservableEvents;
+class ObservableEvents_CloneTriggerHit;
+class ObservableEvents_DataSourceInstanceStateChange;
+enum ObservableEvents_Type : int;
+enum ObservableEvents_DataSourceInstanceState : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ObservableEvents_Type : int {
+  ObservableEvents_Type_TYPE_UNSPECIFIED = 0,
+  ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES = 1,
+  ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED = 2,
+  ObservableEvents_Type_TYPE_CLONE_TRIGGER_HIT = 4,
+};
+enum ObservableEvents_DataSourceInstanceState : int {
+  ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
+  ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT ObservableEvents : public ::protozero::CppMessageObj {
+ public:
+  using DataSourceInstanceStateChange = ObservableEvents_DataSourceInstanceStateChange;
+  using CloneTriggerHit = ObservableEvents_CloneTriggerHit;
+  using Type = ObservableEvents_Type;
+  static constexpr auto TYPE_UNSPECIFIED = ObservableEvents_Type_TYPE_UNSPECIFIED;
+  static constexpr auto TYPE_DATA_SOURCES_INSTANCES = ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES;
+  static constexpr auto TYPE_ALL_DATA_SOURCES_STARTED = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
+  static constexpr auto TYPE_CLONE_TRIGGER_HIT = ObservableEvents_Type_TYPE_CLONE_TRIGGER_HIT;
+  static constexpr auto Type_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
+  static constexpr auto Type_MAX = ObservableEvents_Type_TYPE_CLONE_TRIGGER_HIT;
+  using DataSourceInstanceState = ObservableEvents_DataSourceInstanceState;
+  static constexpr auto DATA_SOURCE_INSTANCE_STATE_STOPPED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
+  static constexpr auto DATA_SOURCE_INSTANCE_STATE_STARTED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
+  static constexpr auto DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
+  static constexpr auto DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
+  enum FieldNumbers {
+    kInstanceStateChangesFieldNumber = 1,
+    kAllDataSourcesStartedFieldNumber = 2,
+    kCloneTriggerHitFieldNumber = 3,
+  };
+
+  ObservableEvents();
+  ~ObservableEvents() override;
+  ObservableEvents(ObservableEvents&&) noexcept;
+  ObservableEvents& operator=(ObservableEvents&&);
+  ObservableEvents(const ObservableEvents&);
+  ObservableEvents& operator=(const ObservableEvents&);
+  bool operator==(const ObservableEvents&) const;
+  bool operator!=(const ObservableEvents& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ObservableEvents_DataSourceInstanceStateChange>& instance_state_changes() const { return instance_state_changes_; }
+  std::vector<ObservableEvents_DataSourceInstanceStateChange>* mutable_instance_state_changes() { return &instance_state_changes_; }
+  int instance_state_changes_size() const;
+  void clear_instance_state_changes();
+  ObservableEvents_DataSourceInstanceStateChange* add_instance_state_changes();
+
+  bool has_all_data_sources_started() const { return _has_field_[2]; }
+  bool all_data_sources_started() const { return all_data_sources_started_; }
+  void set_all_data_sources_started(bool value) { all_data_sources_started_ = value; _has_field_.set(2); }
+
+  bool has_clone_trigger_hit() const { return _has_field_[3]; }
+  const ObservableEvents_CloneTriggerHit& clone_trigger_hit() const { return *clone_trigger_hit_; }
+  ObservableEvents_CloneTriggerHit* mutable_clone_trigger_hit() { _has_field_.set(3); return clone_trigger_hit_.get(); }
+
+ private:
+  std::vector<ObservableEvents_DataSourceInstanceStateChange> instance_state_changes_;
+  bool all_data_sources_started_{};
+  ::protozero::CopyablePtr<ObservableEvents_CloneTriggerHit> clone_trigger_hit_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ObservableEvents_CloneTriggerHit : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTracingSessionIdFieldNumber = 1,
+  };
+
+  ObservableEvents_CloneTriggerHit();
+  ~ObservableEvents_CloneTriggerHit() override;
+  ObservableEvents_CloneTriggerHit(ObservableEvents_CloneTriggerHit&&) noexcept;
+  ObservableEvents_CloneTriggerHit& operator=(ObservableEvents_CloneTriggerHit&&);
+  ObservableEvents_CloneTriggerHit(const ObservableEvents_CloneTriggerHit&);
+  ObservableEvents_CloneTriggerHit& operator=(const ObservableEvents_CloneTriggerHit&);
+  bool operator==(const ObservableEvents_CloneTriggerHit&) const;
+  bool operator!=(const ObservableEvents_CloneTriggerHit& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_tracing_session_id() const { return _has_field_[1]; }
+  int64_t tracing_session_id() const { return tracing_session_id_; }
+  void set_tracing_session_id(int64_t value) { tracing_session_id_ = value; _has_field_.set(1); }
+
+ private:
+  int64_t tracing_session_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ObservableEvents_DataSourceInstanceStateChange : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kProducerNameFieldNumber = 1,
+    kDataSourceNameFieldNumber = 2,
+    kStateFieldNumber = 3,
+  };
+
+  ObservableEvents_DataSourceInstanceStateChange();
+  ~ObservableEvents_DataSourceInstanceStateChange() override;
+  ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept;
+  ObservableEvents_DataSourceInstanceStateChange& operator=(ObservableEvents_DataSourceInstanceStateChange&&);
+  ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&);
+  ObservableEvents_DataSourceInstanceStateChange& operator=(const ObservableEvents_DataSourceInstanceStateChange&);
+  bool operator==(const ObservableEvents_DataSourceInstanceStateChange&) const;
+  bool operator!=(const ObservableEvents_DataSourceInstanceStateChange& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_producer_name() const { return _has_field_[1]; }
+  const std::string& producer_name() const { return producer_name_; }
+  void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(1); }
+
+  bool has_data_source_name() const { return _has_field_[2]; }
+  const std::string& data_source_name() const { return data_source_name_; }
+  void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(2); }
+
+  bool has_state() const { return _has_field_[3]; }
+  ObservableEvents_DataSourceInstanceState state() const { return state_; }
+  void set_state(ObservableEvents_DataSourceInstanceState value) { state_ = value; _has_field_.set(3); }
+
+ private:
+  std::string producer_name_{};
+  std::string data_source_name_{};
+  ObservableEvents_DataSourceInstanceState state_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/perf_events.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class PerfEvents;
+class PerfEvents_RawEvent;
+class PerfEvents_Tracepoint;
+class PerfEvents_Timebase;
+enum PerfEvents_Counter : int;
+enum PerfEvents_PerfClock : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum PerfEvents_Counter : int {
+  PerfEvents_Counter_UNKNOWN_COUNTER = 0,
+  PerfEvents_Counter_SW_CPU_CLOCK = 1,
+  PerfEvents_Counter_SW_PAGE_FAULTS = 2,
+  PerfEvents_Counter_SW_TASK_CLOCK = 3,
+  PerfEvents_Counter_SW_CONTEXT_SWITCHES = 4,
+  PerfEvents_Counter_SW_CPU_MIGRATIONS = 5,
+  PerfEvents_Counter_SW_PAGE_FAULTS_MIN = 6,
+  PerfEvents_Counter_SW_PAGE_FAULTS_MAJ = 7,
+  PerfEvents_Counter_SW_ALIGNMENT_FAULTS = 8,
+  PerfEvents_Counter_SW_EMULATION_FAULTS = 9,
+  PerfEvents_Counter_SW_DUMMY = 20,
+  PerfEvents_Counter_HW_CPU_CYCLES = 10,
+  PerfEvents_Counter_HW_INSTRUCTIONS = 11,
+  PerfEvents_Counter_HW_CACHE_REFERENCES = 12,
+  PerfEvents_Counter_HW_CACHE_MISSES = 13,
+  PerfEvents_Counter_HW_BRANCH_INSTRUCTIONS = 14,
+  PerfEvents_Counter_HW_BRANCH_MISSES = 15,
+  PerfEvents_Counter_HW_BUS_CYCLES = 16,
+  PerfEvents_Counter_HW_STALLED_CYCLES_FRONTEND = 17,
+  PerfEvents_Counter_HW_STALLED_CYCLES_BACKEND = 18,
+  PerfEvents_Counter_HW_REF_CPU_CYCLES = 19,
+};
+enum PerfEvents_PerfClock : int {
+  PerfEvents_PerfClock_UNKNOWN_PERF_CLOCK = 0,
+  PerfEvents_PerfClock_PERF_CLOCK_REALTIME = 1,
+  PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC = 2,
+  PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC_RAW = 3,
+  PerfEvents_PerfClock_PERF_CLOCK_BOOTTIME = 4,
+};
+
+class PERFETTO_EXPORT_COMPONENT PerfEvents : public ::protozero::CppMessageObj {
+ public:
+  using Timebase = PerfEvents_Timebase;
+  using Tracepoint = PerfEvents_Tracepoint;
+  using RawEvent = PerfEvents_RawEvent;
+  using Counter = PerfEvents_Counter;
+  static constexpr auto UNKNOWN_COUNTER = PerfEvents_Counter_UNKNOWN_COUNTER;
+  static constexpr auto SW_CPU_CLOCK = PerfEvents_Counter_SW_CPU_CLOCK;
+  static constexpr auto SW_PAGE_FAULTS = PerfEvents_Counter_SW_PAGE_FAULTS;
+  static constexpr auto SW_TASK_CLOCK = PerfEvents_Counter_SW_TASK_CLOCK;
+  static constexpr auto SW_CONTEXT_SWITCHES = PerfEvents_Counter_SW_CONTEXT_SWITCHES;
+  static constexpr auto SW_CPU_MIGRATIONS = PerfEvents_Counter_SW_CPU_MIGRATIONS;
+  static constexpr auto SW_PAGE_FAULTS_MIN = PerfEvents_Counter_SW_PAGE_FAULTS_MIN;
+  static constexpr auto SW_PAGE_FAULTS_MAJ = PerfEvents_Counter_SW_PAGE_FAULTS_MAJ;
+  static constexpr auto SW_ALIGNMENT_FAULTS = PerfEvents_Counter_SW_ALIGNMENT_FAULTS;
+  static constexpr auto SW_EMULATION_FAULTS = PerfEvents_Counter_SW_EMULATION_FAULTS;
+  static constexpr auto SW_DUMMY = PerfEvents_Counter_SW_DUMMY;
+  static constexpr auto HW_CPU_CYCLES = PerfEvents_Counter_HW_CPU_CYCLES;
+  static constexpr auto HW_INSTRUCTIONS = PerfEvents_Counter_HW_INSTRUCTIONS;
+  static constexpr auto HW_CACHE_REFERENCES = PerfEvents_Counter_HW_CACHE_REFERENCES;
+  static constexpr auto HW_CACHE_MISSES = PerfEvents_Counter_HW_CACHE_MISSES;
+  static constexpr auto HW_BRANCH_INSTRUCTIONS = PerfEvents_Counter_HW_BRANCH_INSTRUCTIONS;
+  static constexpr auto HW_BRANCH_MISSES = PerfEvents_Counter_HW_BRANCH_MISSES;
+  static constexpr auto HW_BUS_CYCLES = PerfEvents_Counter_HW_BUS_CYCLES;
+  static constexpr auto HW_STALLED_CYCLES_FRONTEND = PerfEvents_Counter_HW_STALLED_CYCLES_FRONTEND;
+  static constexpr auto HW_STALLED_CYCLES_BACKEND = PerfEvents_Counter_HW_STALLED_CYCLES_BACKEND;
+  static constexpr auto HW_REF_CPU_CYCLES = PerfEvents_Counter_HW_REF_CPU_CYCLES;
+  static constexpr auto Counter_MIN = PerfEvents_Counter_UNKNOWN_COUNTER;
+  static constexpr auto Counter_MAX = PerfEvents_Counter_SW_DUMMY;
+  using PerfClock = PerfEvents_PerfClock;
+  static constexpr auto UNKNOWN_PERF_CLOCK = PerfEvents_PerfClock_UNKNOWN_PERF_CLOCK;
+  static constexpr auto PERF_CLOCK_REALTIME = PerfEvents_PerfClock_PERF_CLOCK_REALTIME;
+  static constexpr auto PERF_CLOCK_MONOTONIC = PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC;
+  static constexpr auto PERF_CLOCK_MONOTONIC_RAW = PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC_RAW;
+  static constexpr auto PERF_CLOCK_BOOTTIME = PerfEvents_PerfClock_PERF_CLOCK_BOOTTIME;
+  static constexpr auto PerfClock_MIN = PerfEvents_PerfClock_UNKNOWN_PERF_CLOCK;
+  static constexpr auto PerfClock_MAX = PerfEvents_PerfClock_PERF_CLOCK_BOOTTIME;
+  enum FieldNumbers {
+  };
+
+  PerfEvents();
+  ~PerfEvents() override;
+  PerfEvents(PerfEvents&&) noexcept;
+  PerfEvents& operator=(PerfEvents&&);
+  PerfEvents(const PerfEvents&);
+  PerfEvents& operator=(const PerfEvents&);
+  bool operator==(const PerfEvents&) const;
+  bool operator!=(const PerfEvents& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT PerfEvents_RawEvent : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTypeFieldNumber = 1,
+    kConfigFieldNumber = 2,
+    kConfig1FieldNumber = 3,
+    kConfig2FieldNumber = 4,
+  };
+
+  PerfEvents_RawEvent();
+  ~PerfEvents_RawEvent() override;
+  PerfEvents_RawEvent(PerfEvents_RawEvent&&) noexcept;
+  PerfEvents_RawEvent& operator=(PerfEvents_RawEvent&&);
+  PerfEvents_RawEvent(const PerfEvents_RawEvent&);
+  PerfEvents_RawEvent& operator=(const PerfEvents_RawEvent&);
+  bool operator==(const PerfEvents_RawEvent&) const;
+  bool operator!=(const PerfEvents_RawEvent& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_type() const { return _has_field_[1]; }
+  uint32_t type() const { return type_; }
+  void set_type(uint32_t value) { type_ = value; _has_field_.set(1); }
+
+  bool has_config() const { return _has_field_[2]; }
+  uint64_t config() const { return config_; }
+  void set_config(uint64_t value) { config_ = value; _has_field_.set(2); }
+
+  bool has_config1() const { return _has_field_[3]; }
+  uint64_t config1() const { return config1_; }
+  void set_config1(uint64_t value) { config1_ = value; _has_field_.set(3); }
+
+  bool has_config2() const { return _has_field_[4]; }
+  uint64_t config2() const { return config2_; }
+  void set_config2(uint64_t value) { config2_ = value; _has_field_.set(4); }
+
+ private:
+  uint32_t type_{};
+  uint64_t config_{};
+  uint64_t config1_{};
+  uint64_t config2_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT PerfEvents_Tracepoint : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kFilterFieldNumber = 2,
+  };
+
+  PerfEvents_Tracepoint();
+  ~PerfEvents_Tracepoint() override;
+  PerfEvents_Tracepoint(PerfEvents_Tracepoint&&) noexcept;
+  PerfEvents_Tracepoint& operator=(PerfEvents_Tracepoint&&);
+  PerfEvents_Tracepoint(const PerfEvents_Tracepoint&);
+  PerfEvents_Tracepoint& operator=(const PerfEvents_Tracepoint&);
+  bool operator==(const PerfEvents_Tracepoint&) const;
+  bool operator!=(const PerfEvents_Tracepoint& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_filter() const { return _has_field_[2]; }
+  const std::string& filter() const { return filter_; }
+  void set_filter(const std::string& value) { filter_ = value; _has_field_.set(2); }
+
+ private:
+  std::string name_{};
+  std::string filter_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT PerfEvents_Timebase : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kFrequencyFieldNumber = 2,
+    kPeriodFieldNumber = 1,
+    kCounterFieldNumber = 4,
+    kTracepointFieldNumber = 3,
+    kRawEventFieldNumber = 5,
+    kTimestampClockFieldNumber = 11,
+    kNameFieldNumber = 10,
+  };
+
+  PerfEvents_Timebase();
+  ~PerfEvents_Timebase() override;
+  PerfEvents_Timebase(PerfEvents_Timebase&&) noexcept;
+  PerfEvents_Timebase& operator=(PerfEvents_Timebase&&);
+  PerfEvents_Timebase(const PerfEvents_Timebase&);
+  PerfEvents_Timebase& operator=(const PerfEvents_Timebase&);
+  bool operator==(const PerfEvents_Timebase&) const;
+  bool operator!=(const PerfEvents_Timebase& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_frequency() const { return _has_field_[2]; }
+  uint64_t frequency() const { return frequency_; }
+  void set_frequency(uint64_t value) { frequency_ = value; _has_field_.set(2); }
+
+  bool has_period() const { return _has_field_[1]; }
+  uint64_t period() const { return period_; }
+  void set_period(uint64_t value) { period_ = value; _has_field_.set(1); }
+
+  bool has_counter() const { return _has_field_[4]; }
+  PerfEvents_Counter counter() const { return counter_; }
+  void set_counter(PerfEvents_Counter value) { counter_ = value; _has_field_.set(4); }
+
+  bool has_tracepoint() const { return _has_field_[3]; }
+  const PerfEvents_Tracepoint& tracepoint() const { return *tracepoint_; }
+  PerfEvents_Tracepoint* mutable_tracepoint() { _has_field_.set(3); return tracepoint_.get(); }
+
+  bool has_raw_event() const { return _has_field_[5]; }
+  const PerfEvents_RawEvent& raw_event() const { return *raw_event_; }
+  PerfEvents_RawEvent* mutable_raw_event() { _has_field_.set(5); return raw_event_.get(); }
+
+  bool has_timestamp_clock() const { return _has_field_[11]; }
+  PerfEvents_PerfClock timestamp_clock() const { return timestamp_clock_; }
+  void set_timestamp_clock(PerfEvents_PerfClock value) { timestamp_clock_ = value; _has_field_.set(11); }
+
+  bool has_name() const { return _has_field_[10]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(10); }
+
+ private:
+  uint64_t frequency_{};
+  uint64_t period_{};
+  PerfEvents_Counter counter_{};
+  ::protozero::CopyablePtr<PerfEvents_Tracepoint> tracepoint_;
+  ::protozero::CopyablePtr<PerfEvents_RawEvent> raw_event_;
+  PerfEvents_PerfClock timestamp_clock_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<12> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/sys_stats_counters.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum MeminfoCounters : int;
+enum VmstatCounters : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum MeminfoCounters : int {
+  MEMINFO_UNSPECIFIED = 0,
+  MEMINFO_MEM_TOTAL = 1,
+  MEMINFO_MEM_FREE = 2,
+  MEMINFO_MEM_AVAILABLE = 3,
+  MEMINFO_BUFFERS = 4,
+  MEMINFO_CACHED = 5,
+  MEMINFO_SWAP_CACHED = 6,
+  MEMINFO_ACTIVE = 7,
+  MEMINFO_INACTIVE = 8,
+  MEMINFO_ACTIVE_ANON = 9,
+  MEMINFO_INACTIVE_ANON = 10,
+  MEMINFO_ACTIVE_FILE = 11,
+  MEMINFO_INACTIVE_FILE = 12,
+  MEMINFO_UNEVICTABLE = 13,
+  MEMINFO_MLOCKED = 14,
+  MEMINFO_SWAP_TOTAL = 15,
+  MEMINFO_SWAP_FREE = 16,
+  MEMINFO_DIRTY = 17,
+  MEMINFO_WRITEBACK = 18,
+  MEMINFO_ANON_PAGES = 19,
+  MEMINFO_MAPPED = 20,
+  MEMINFO_SHMEM = 21,
+  MEMINFO_SLAB = 22,
+  MEMINFO_SLAB_RECLAIMABLE = 23,
+  MEMINFO_SLAB_UNRECLAIMABLE = 24,
+  MEMINFO_KERNEL_STACK = 25,
+  MEMINFO_PAGE_TABLES = 26,
+  MEMINFO_COMMIT_LIMIT = 27,
+  MEMINFO_COMMITED_AS = 28,
+  MEMINFO_VMALLOC_TOTAL = 29,
+  MEMINFO_VMALLOC_USED = 30,
+  MEMINFO_VMALLOC_CHUNK = 31,
+  MEMINFO_CMA_TOTAL = 32,
+  MEMINFO_CMA_FREE = 33,
+};
+enum VmstatCounters : int {
+  VMSTAT_UNSPECIFIED = 0,
+  VMSTAT_NR_FREE_PAGES = 1,
+  VMSTAT_NR_ALLOC_BATCH = 2,
+  VMSTAT_NR_INACTIVE_ANON = 3,
+  VMSTAT_NR_ACTIVE_ANON = 4,
+  VMSTAT_NR_INACTIVE_FILE = 5,
+  VMSTAT_NR_ACTIVE_FILE = 6,
+  VMSTAT_NR_UNEVICTABLE = 7,
+  VMSTAT_NR_MLOCK = 8,
+  VMSTAT_NR_ANON_PAGES = 9,
+  VMSTAT_NR_MAPPED = 10,
+  VMSTAT_NR_FILE_PAGES = 11,
+  VMSTAT_NR_DIRTY = 12,
+  VMSTAT_NR_WRITEBACK = 13,
+  VMSTAT_NR_SLAB_RECLAIMABLE = 14,
+  VMSTAT_NR_SLAB_UNRECLAIMABLE = 15,
+  VMSTAT_NR_PAGE_TABLE_PAGES = 16,
+  VMSTAT_NR_KERNEL_STACK = 17,
+  VMSTAT_NR_OVERHEAD = 18,
+  VMSTAT_NR_UNSTABLE = 19,
+  VMSTAT_NR_BOUNCE = 20,
+  VMSTAT_NR_VMSCAN_WRITE = 21,
+  VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22,
+  VMSTAT_NR_WRITEBACK_TEMP = 23,
+  VMSTAT_NR_ISOLATED_ANON = 24,
+  VMSTAT_NR_ISOLATED_FILE = 25,
+  VMSTAT_NR_SHMEM = 26,
+  VMSTAT_NR_DIRTIED = 27,
+  VMSTAT_NR_WRITTEN = 28,
+  VMSTAT_NR_PAGES_SCANNED = 29,
+  VMSTAT_WORKINGSET_REFAULT = 30,
+  VMSTAT_WORKINGSET_ACTIVATE = 31,
+  VMSTAT_WORKINGSET_NODERECLAIM = 32,
+  VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33,
+  VMSTAT_NR_FREE_CMA = 34,
+  VMSTAT_NR_SWAPCACHE = 35,
+  VMSTAT_NR_DIRTY_THRESHOLD = 36,
+  VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37,
+  VMSTAT_PGPGIN = 38,
+  VMSTAT_PGPGOUT = 39,
+  VMSTAT_PGPGOUTCLEAN = 40,
+  VMSTAT_PSWPIN = 41,
+  VMSTAT_PSWPOUT = 42,
+  VMSTAT_PGALLOC_DMA = 43,
+  VMSTAT_PGALLOC_NORMAL = 44,
+  VMSTAT_PGALLOC_MOVABLE = 45,
+  VMSTAT_PGFREE = 46,
+  VMSTAT_PGACTIVATE = 47,
+  VMSTAT_PGDEACTIVATE = 48,
+  VMSTAT_PGFAULT = 49,
+  VMSTAT_PGMAJFAULT = 50,
+  VMSTAT_PGREFILL_DMA = 51,
+  VMSTAT_PGREFILL_NORMAL = 52,
+  VMSTAT_PGREFILL_MOVABLE = 53,
+  VMSTAT_PGSTEAL_KSWAPD_DMA = 54,
+  VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55,
+  VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56,
+  VMSTAT_PGSTEAL_DIRECT_DMA = 57,
+  VMSTAT_PGSTEAL_DIRECT_NORMAL = 58,
+  VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59,
+  VMSTAT_PGSCAN_KSWAPD_DMA = 60,
+  VMSTAT_PGSCAN_KSWAPD_NORMAL = 61,
+  VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62,
+  VMSTAT_PGSCAN_DIRECT_DMA = 63,
+  VMSTAT_PGSCAN_DIRECT_NORMAL = 64,
+  VMSTAT_PGSCAN_DIRECT_MOVABLE = 65,
+  VMSTAT_PGSCAN_DIRECT_THROTTLE = 66,
+  VMSTAT_PGINODESTEAL = 67,
+  VMSTAT_SLABS_SCANNED = 68,
+  VMSTAT_KSWAPD_INODESTEAL = 69,
+  VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70,
+  VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71,
+  VMSTAT_PAGEOUTRUN = 72,
+  VMSTAT_ALLOCSTALL = 73,
+  VMSTAT_PGROTATED = 74,
+  VMSTAT_DROP_PAGECACHE = 75,
+  VMSTAT_DROP_SLAB = 76,
+  VMSTAT_PGMIGRATE_SUCCESS = 77,
+  VMSTAT_PGMIGRATE_FAIL = 78,
+  VMSTAT_COMPACT_MIGRATE_SCANNED = 79,
+  VMSTAT_COMPACT_FREE_SCANNED = 80,
+  VMSTAT_COMPACT_ISOLATED = 81,
+  VMSTAT_COMPACT_STALL = 82,
+  VMSTAT_COMPACT_FAIL = 83,
+  VMSTAT_COMPACT_SUCCESS = 84,
+  VMSTAT_COMPACT_DAEMON_WAKE = 85,
+  VMSTAT_UNEVICTABLE_PGS_CULLED = 86,
+  VMSTAT_UNEVICTABLE_PGS_SCANNED = 87,
+  VMSTAT_UNEVICTABLE_PGS_RESCUED = 88,
+  VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89,
+  VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90,
+  VMSTAT_UNEVICTABLE_PGS_CLEARED = 91,
+  VMSTAT_UNEVICTABLE_PGS_STRANDED = 92,
+  VMSTAT_NR_ZSPAGES = 93,
+  VMSTAT_NR_ION_HEAP = 94,
+  VMSTAT_NR_GPU_HEAP = 95,
+  VMSTAT_ALLOCSTALL_DMA = 96,
+  VMSTAT_ALLOCSTALL_MOVABLE = 97,
+  VMSTAT_ALLOCSTALL_NORMAL = 98,
+  VMSTAT_COMPACT_DAEMON_FREE_SCANNED = 99,
+  VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED = 100,
+  VMSTAT_NR_FASTRPC = 101,
+  VMSTAT_NR_INDIRECTLY_RECLAIMABLE = 102,
+  VMSTAT_NR_ION_HEAP_POOL = 103,
+  VMSTAT_NR_KERNEL_MISC_RECLAIMABLE = 104,
+  VMSTAT_NR_SHADOW_CALL_STACK_BYTES = 105,
+  VMSTAT_NR_SHMEM_HUGEPAGES = 106,
+  VMSTAT_NR_SHMEM_PMDMAPPED = 107,
+  VMSTAT_NR_UNRECLAIMABLE_PAGES = 108,
+  VMSTAT_NR_ZONE_ACTIVE_ANON = 109,
+  VMSTAT_NR_ZONE_ACTIVE_FILE = 110,
+  VMSTAT_NR_ZONE_INACTIVE_ANON = 111,
+  VMSTAT_NR_ZONE_INACTIVE_FILE = 112,
+  VMSTAT_NR_ZONE_UNEVICTABLE = 113,
+  VMSTAT_NR_ZONE_WRITE_PENDING = 114,
+  VMSTAT_OOM_KILL = 115,
+  VMSTAT_PGLAZYFREE = 116,
+  VMSTAT_PGLAZYFREED = 117,
+  VMSTAT_PGREFILL = 118,
+  VMSTAT_PGSCAN_DIRECT = 119,
+  VMSTAT_PGSCAN_KSWAPD = 120,
+  VMSTAT_PGSKIP_DMA = 121,
+  VMSTAT_PGSKIP_MOVABLE = 122,
+  VMSTAT_PGSKIP_NORMAL = 123,
+  VMSTAT_PGSTEAL_DIRECT = 124,
+  VMSTAT_PGSTEAL_KSWAPD = 125,
+  VMSTAT_SWAP_RA = 126,
+  VMSTAT_SWAP_RA_HIT = 127,
+  VMSTAT_WORKINGSET_RESTORE = 128,
+};
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TraceStats;
+class TraceStats_FilterStats;
+class TraceStats_WriterStats;
+class TraceStats_BufferStats;
+enum TraceStats_FinalFlushOutcome : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum TraceStats_FinalFlushOutcome : int {
+  TraceStats_FinalFlushOutcome_FINAL_FLUSH_UNSPECIFIED = 0,
+  TraceStats_FinalFlushOutcome_FINAL_FLUSH_SUCCEEDED = 1,
+  TraceStats_FinalFlushOutcome_FINAL_FLUSH_FAILED = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT TraceStats : public ::protozero::CppMessageObj {
+ public:
+  using BufferStats = TraceStats_BufferStats;
+  using WriterStats = TraceStats_WriterStats;
+  using FilterStats = TraceStats_FilterStats;
+  using FinalFlushOutcome = TraceStats_FinalFlushOutcome;
+  static constexpr auto FINAL_FLUSH_UNSPECIFIED = TraceStats_FinalFlushOutcome_FINAL_FLUSH_UNSPECIFIED;
+  static constexpr auto FINAL_FLUSH_SUCCEEDED = TraceStats_FinalFlushOutcome_FINAL_FLUSH_SUCCEEDED;
+  static constexpr auto FINAL_FLUSH_FAILED = TraceStats_FinalFlushOutcome_FINAL_FLUSH_FAILED;
+  static constexpr auto FinalFlushOutcome_MIN = TraceStats_FinalFlushOutcome_FINAL_FLUSH_UNSPECIFIED;
+  static constexpr auto FinalFlushOutcome_MAX = TraceStats_FinalFlushOutcome_FINAL_FLUSH_FAILED;
+  enum FieldNumbers {
+    kBufferStatsFieldNumber = 1,
+    kChunkPayloadHistogramDefFieldNumber = 17,
+    kWriterStatsFieldNumber = 18,
+    kProducersConnectedFieldNumber = 2,
+    kProducersSeenFieldNumber = 3,
+    kDataSourcesRegisteredFieldNumber = 4,
+    kDataSourcesSeenFieldNumber = 5,
+    kTracingSessionsFieldNumber = 6,
+    kTotalBuffersFieldNumber = 7,
+    kChunksDiscardedFieldNumber = 8,
+    kPatchesDiscardedFieldNumber = 9,
+    kInvalidPacketsFieldNumber = 10,
+    kFilterStatsFieldNumber = 11,
+    kFlushesRequestedFieldNumber = 12,
+    kFlushesSucceededFieldNumber = 13,
+    kFlushesFailedFieldNumber = 14,
+    kFinalFlushOutcomeFieldNumber = 15,
+  };
+
+  TraceStats();
+  ~TraceStats() override;
+  TraceStats(TraceStats&&) noexcept;
+  TraceStats& operator=(TraceStats&&);
+  TraceStats(const TraceStats&);
+  TraceStats& operator=(const TraceStats&);
+  bool operator==(const TraceStats&) const;
+  bool operator!=(const TraceStats& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TraceStats_BufferStats>& buffer_stats() const { return buffer_stats_; }
+  std::vector<TraceStats_BufferStats>* mutable_buffer_stats() { return &buffer_stats_; }
+  int buffer_stats_size() const;
+  void clear_buffer_stats();
+  TraceStats_BufferStats* add_buffer_stats();
+
+  const std::vector<int64_t>& chunk_payload_histogram_def() const { return chunk_payload_histogram_def_; }
+  std::vector<int64_t>* mutable_chunk_payload_histogram_def() { return &chunk_payload_histogram_def_; }
+  int chunk_payload_histogram_def_size() const { return static_cast<int>(chunk_payload_histogram_def_.size()); }
+  void clear_chunk_payload_histogram_def() { chunk_payload_histogram_def_.clear(); }
+  void add_chunk_payload_histogram_def(int64_t value) { chunk_payload_histogram_def_.emplace_back(value); }
+  int64_t* add_chunk_payload_histogram_def() { chunk_payload_histogram_def_.emplace_back(); return &chunk_payload_histogram_def_.back(); }
+
+  const std::vector<TraceStats_WriterStats>& writer_stats() const { return writer_stats_; }
+  std::vector<TraceStats_WriterStats>* mutable_writer_stats() { return &writer_stats_; }
+  int writer_stats_size() const;
+  void clear_writer_stats();
+  TraceStats_WriterStats* add_writer_stats();
+
+  bool has_producers_connected() const { return _has_field_[2]; }
+  uint32_t producers_connected() const { return producers_connected_; }
+  void set_producers_connected(uint32_t value) { producers_connected_ = value; _has_field_.set(2); }
+
+  bool has_producers_seen() const { return _has_field_[3]; }
+  uint64_t producers_seen() const { return producers_seen_; }
+  void set_producers_seen(uint64_t value) { producers_seen_ = value; _has_field_.set(3); }
+
+  bool has_data_sources_registered() const { return _has_field_[4]; }
+  uint32_t data_sources_registered() const { return data_sources_registered_; }
+  void set_data_sources_registered(uint32_t value) { data_sources_registered_ = value; _has_field_.set(4); }
+
+  bool has_data_sources_seen() const { return _has_field_[5]; }
+  uint64_t data_sources_seen() const { return data_sources_seen_; }
+  void set_data_sources_seen(uint64_t value) { data_sources_seen_ = value; _has_field_.set(5); }
+
+  bool has_tracing_sessions() const { return _has_field_[6]; }
+  uint32_t tracing_sessions() const { return tracing_sessions_; }
+  void set_tracing_sessions(uint32_t value) { tracing_sessions_ = value; _has_field_.set(6); }
+
+  bool has_total_buffers() const { return _has_field_[7]; }
+  uint32_t total_buffers() const { return total_buffers_; }
+  void set_total_buffers(uint32_t value) { total_buffers_ = value; _has_field_.set(7); }
+
+  bool has_chunks_discarded() const { return _has_field_[8]; }
+  uint64_t chunks_discarded() const { return chunks_discarded_; }
+  void set_chunks_discarded(uint64_t value) { chunks_discarded_ = value; _has_field_.set(8); }
+
+  bool has_patches_discarded() const { return _has_field_[9]; }
+  uint64_t patches_discarded() const { return patches_discarded_; }
+  void set_patches_discarded(uint64_t value) { patches_discarded_ = value; _has_field_.set(9); }
+
+  bool has_invalid_packets() const { return _has_field_[10]; }
+  uint64_t invalid_packets() const { return invalid_packets_; }
+  void set_invalid_packets(uint64_t value) { invalid_packets_ = value; _has_field_.set(10); }
+
+  bool has_filter_stats() const { return _has_field_[11]; }
+  const TraceStats_FilterStats& filter_stats() const { return *filter_stats_; }
+  TraceStats_FilterStats* mutable_filter_stats() { _has_field_.set(11); return filter_stats_.get(); }
+
+  bool has_flushes_requested() const { return _has_field_[12]; }
+  uint64_t flushes_requested() const { return flushes_requested_; }
+  void set_flushes_requested(uint64_t value) { flushes_requested_ = value; _has_field_.set(12); }
+
+  bool has_flushes_succeeded() const { return _has_field_[13]; }
+  uint64_t flushes_succeeded() const { return flushes_succeeded_; }
+  void set_flushes_succeeded(uint64_t value) { flushes_succeeded_ = value; _has_field_.set(13); }
+
+  bool has_flushes_failed() const { return _has_field_[14]; }
+  uint64_t flushes_failed() const { return flushes_failed_; }
+  void set_flushes_failed(uint64_t value) { flushes_failed_ = value; _has_field_.set(14); }
+
+  bool has_final_flush_outcome() const { return _has_field_[15]; }
+  TraceStats_FinalFlushOutcome final_flush_outcome() const { return final_flush_outcome_; }
+  void set_final_flush_outcome(TraceStats_FinalFlushOutcome value) { final_flush_outcome_ = value; _has_field_.set(15); }
+
+ private:
+  std::vector<TraceStats_BufferStats> buffer_stats_;
+  std::vector<int64_t> chunk_payload_histogram_def_;
+  std::vector<TraceStats_WriterStats> writer_stats_;
+  uint32_t producers_connected_{};
+  uint64_t producers_seen_{};
+  uint32_t data_sources_registered_{};
+  uint64_t data_sources_seen_{};
+  uint32_t tracing_sessions_{};
+  uint32_t total_buffers_{};
+  uint64_t chunks_discarded_{};
+  uint64_t patches_discarded_{};
+  uint64_t invalid_packets_{};
+  ::protozero::CopyablePtr<TraceStats_FilterStats> filter_stats_;
+  uint64_t flushes_requested_{};
+  uint64_t flushes_succeeded_{};
+  uint64_t flushes_failed_{};
+  TraceStats_FinalFlushOutcome final_flush_outcome_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<19> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceStats_FilterStats : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kInputPacketsFieldNumber = 1,
+    kInputBytesFieldNumber = 2,
+    kOutputBytesFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+    kTimeTakenNsFieldNumber = 5,
+    kBytesDiscardedPerBufferFieldNumber = 20,
+  };
+
+  TraceStats_FilterStats();
+  ~TraceStats_FilterStats() override;
+  TraceStats_FilterStats(TraceStats_FilterStats&&) noexcept;
+  TraceStats_FilterStats& operator=(TraceStats_FilterStats&&);
+  TraceStats_FilterStats(const TraceStats_FilterStats&);
+  TraceStats_FilterStats& operator=(const TraceStats_FilterStats&);
+  bool operator==(const TraceStats_FilterStats&) const;
+  bool operator!=(const TraceStats_FilterStats& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_input_packets() const { return _has_field_[1]; }
+  uint64_t input_packets() const { return input_packets_; }
+  void set_input_packets(uint64_t value) { input_packets_ = value; _has_field_.set(1); }
+
+  bool has_input_bytes() const { return _has_field_[2]; }
+  uint64_t input_bytes() const { return input_bytes_; }
+  void set_input_bytes(uint64_t value) { input_bytes_ = value; _has_field_.set(2); }
+
+  bool has_output_bytes() const { return _has_field_[3]; }
+  uint64_t output_bytes() const { return output_bytes_; }
+  void set_output_bytes(uint64_t value) { output_bytes_ = value; _has_field_.set(3); }
+
+  bool has_errors() const { return _has_field_[4]; }
+  uint64_t errors() const { return errors_; }
+  void set_errors(uint64_t value) { errors_ = value; _has_field_.set(4); }
+
+  bool has_time_taken_ns() const { return _has_field_[5]; }
+  uint64_t time_taken_ns() const { return time_taken_ns_; }
+  void set_time_taken_ns(uint64_t value) { time_taken_ns_ = value; _has_field_.set(5); }
+
+  const std::vector<uint64_t>& bytes_discarded_per_buffer() const { return bytes_discarded_per_buffer_; }
+  std::vector<uint64_t>* mutable_bytes_discarded_per_buffer() { return &bytes_discarded_per_buffer_; }
+  int bytes_discarded_per_buffer_size() const { return static_cast<int>(bytes_discarded_per_buffer_.size()); }
+  void clear_bytes_discarded_per_buffer() { bytes_discarded_per_buffer_.clear(); }
+  void add_bytes_discarded_per_buffer(uint64_t value) { bytes_discarded_per_buffer_.emplace_back(value); }
+  uint64_t* add_bytes_discarded_per_buffer() { bytes_discarded_per_buffer_.emplace_back(); return &bytes_discarded_per_buffer_.back(); }
+
+ private:
+  uint64_t input_packets_{};
+  uint64_t input_bytes_{};
+  uint64_t output_bytes_{};
+  uint64_t errors_{};
+  uint64_t time_taken_ns_{};
+  std::vector<uint64_t> bytes_discarded_per_buffer_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<21> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceStats_WriterStats : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSequenceIdFieldNumber = 1,
+    kBufferFieldNumber = 4,
+    kChunkPayloadHistogramCountsFieldNumber = 2,
+    kChunkPayloadHistogramSumFieldNumber = 3,
+  };
+
+  TraceStats_WriterStats();
+  ~TraceStats_WriterStats() override;
+  TraceStats_WriterStats(TraceStats_WriterStats&&) noexcept;
+  TraceStats_WriterStats& operator=(TraceStats_WriterStats&&);
+  TraceStats_WriterStats(const TraceStats_WriterStats&);
+  TraceStats_WriterStats& operator=(const TraceStats_WriterStats&);
+  bool operator==(const TraceStats_WriterStats&) const;
+  bool operator!=(const TraceStats_WriterStats& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_sequence_id() const { return _has_field_[1]; }
+  uint64_t sequence_id() const { return sequence_id_; }
+  void set_sequence_id(uint64_t value) { sequence_id_ = value; _has_field_.set(1); }
+
+  bool has_buffer() const { return _has_field_[4]; }
+  uint32_t buffer() const { return buffer_; }
+  void set_buffer(uint32_t value) { buffer_ = value; _has_field_.set(4); }
+
+  const std::vector<uint64_t>& chunk_payload_histogram_counts() const { return chunk_payload_histogram_counts_; }
+  std::vector<uint64_t>* mutable_chunk_payload_histogram_counts() { return &chunk_payload_histogram_counts_; }
+  int chunk_payload_histogram_counts_size() const { return static_cast<int>(chunk_payload_histogram_counts_.size()); }
+  void clear_chunk_payload_histogram_counts() { chunk_payload_histogram_counts_.clear(); }
+  void add_chunk_payload_histogram_counts(uint64_t value) { chunk_payload_histogram_counts_.emplace_back(value); }
+  uint64_t* add_chunk_payload_histogram_counts() { chunk_payload_histogram_counts_.emplace_back(); return &chunk_payload_histogram_counts_.back(); }
+
+  const std::vector<int64_t>& chunk_payload_histogram_sum() const { return chunk_payload_histogram_sum_; }
+  std::vector<int64_t>* mutable_chunk_payload_histogram_sum() { return &chunk_payload_histogram_sum_; }
+  int chunk_payload_histogram_sum_size() const { return static_cast<int>(chunk_payload_histogram_sum_.size()); }
+  void clear_chunk_payload_histogram_sum() { chunk_payload_histogram_sum_.clear(); }
+  void add_chunk_payload_histogram_sum(int64_t value) { chunk_payload_histogram_sum_.emplace_back(value); }
+  int64_t* add_chunk_payload_histogram_sum() { chunk_payload_histogram_sum_.emplace_back(); return &chunk_payload_histogram_sum_.back(); }
+
+ private:
+  uint64_t sequence_id_{};
+  uint32_t buffer_{};
+  std::vector<uint64_t> chunk_payload_histogram_counts_;
+  std::vector<int64_t> chunk_payload_histogram_sum_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TraceStats_BufferStats : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kBufferSizeFieldNumber = 12,
+    kBytesWrittenFieldNumber = 1,
+    kBytesOverwrittenFieldNumber = 13,
+    kBytesReadFieldNumber = 14,
+    kPaddingBytesWrittenFieldNumber = 15,
+    kPaddingBytesClearedFieldNumber = 16,
+    kChunksWrittenFieldNumber = 2,
+    kChunksRewrittenFieldNumber = 10,
+    kChunksOverwrittenFieldNumber = 3,
+    kChunksDiscardedFieldNumber = 18,
+    kChunksReadFieldNumber = 17,
+    kChunksCommittedOutOfOrderFieldNumber = 11,
+    kWriteWrapCountFieldNumber = 4,
+    kPatchesSucceededFieldNumber = 5,
+    kPatchesFailedFieldNumber = 6,
+    kReadaheadsSucceededFieldNumber = 7,
+    kReadaheadsFailedFieldNumber = 8,
+    kAbiViolationsFieldNumber = 9,
+    kTraceWriterPacketLossFieldNumber = 19,
+  };
+
+  TraceStats_BufferStats();
+  ~TraceStats_BufferStats() override;
+  TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept;
+  TraceStats_BufferStats& operator=(TraceStats_BufferStats&&);
+  TraceStats_BufferStats(const TraceStats_BufferStats&);
+  TraceStats_BufferStats& operator=(const TraceStats_BufferStats&);
+  bool operator==(const TraceStats_BufferStats&) const;
+  bool operator!=(const TraceStats_BufferStats& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_buffer_size() const { return _has_field_[12]; }
+  uint64_t buffer_size() const { return buffer_size_; }
+  void set_buffer_size(uint64_t value) { buffer_size_ = value; _has_field_.set(12); }
+
+  bool has_bytes_written() const { return _has_field_[1]; }
+  uint64_t bytes_written() const { return bytes_written_; }
+  void set_bytes_written(uint64_t value) { bytes_written_ = value; _has_field_.set(1); }
+
+  bool has_bytes_overwritten() const { return _has_field_[13]; }
+  uint64_t bytes_overwritten() const { return bytes_overwritten_; }
+  void set_bytes_overwritten(uint64_t value) { bytes_overwritten_ = value; _has_field_.set(13); }
+
+  bool has_bytes_read() const { return _has_field_[14]; }
+  uint64_t bytes_read() const { return bytes_read_; }
+  void set_bytes_read(uint64_t value) { bytes_read_ = value; _has_field_.set(14); }
+
+  bool has_padding_bytes_written() const { return _has_field_[15]; }
+  uint64_t padding_bytes_written() const { return padding_bytes_written_; }
+  void set_padding_bytes_written(uint64_t value) { padding_bytes_written_ = value; _has_field_.set(15); }
+
+  bool has_padding_bytes_cleared() const { return _has_field_[16]; }
+  uint64_t padding_bytes_cleared() const { return padding_bytes_cleared_; }
+  void set_padding_bytes_cleared(uint64_t value) { padding_bytes_cleared_ = value; _has_field_.set(16); }
+
+  bool has_chunks_written() const { return _has_field_[2]; }
+  uint64_t chunks_written() const { return chunks_written_; }
+  void set_chunks_written(uint64_t value) { chunks_written_ = value; _has_field_.set(2); }
+
+  bool has_chunks_rewritten() const { return _has_field_[10]; }
+  uint64_t chunks_rewritten() const { return chunks_rewritten_; }
+  void set_chunks_rewritten(uint64_t value) { chunks_rewritten_ = value; _has_field_.set(10); }
+
+  bool has_chunks_overwritten() const { return _has_field_[3]; }
+  uint64_t chunks_overwritten() const { return chunks_overwritten_; }
+  void set_chunks_overwritten(uint64_t value) { chunks_overwritten_ = value; _has_field_.set(3); }
+
+  bool has_chunks_discarded() const { return _has_field_[18]; }
+  uint64_t chunks_discarded() const { return chunks_discarded_; }
+  void set_chunks_discarded(uint64_t value) { chunks_discarded_ = value; _has_field_.set(18); }
+
+  bool has_chunks_read() const { return _has_field_[17]; }
+  uint64_t chunks_read() const { return chunks_read_; }
+  void set_chunks_read(uint64_t value) { chunks_read_ = value; _has_field_.set(17); }
+
+  bool has_chunks_committed_out_of_order() const { return _has_field_[11]; }
+  uint64_t chunks_committed_out_of_order() const { return chunks_committed_out_of_order_; }
+  void set_chunks_committed_out_of_order(uint64_t value) { chunks_committed_out_of_order_ = value; _has_field_.set(11); }
+
+  bool has_write_wrap_count() const { return _has_field_[4]; }
+  uint64_t write_wrap_count() const { return write_wrap_count_; }
+  void set_write_wrap_count(uint64_t value) { write_wrap_count_ = value; _has_field_.set(4); }
+
+  bool has_patches_succeeded() const { return _has_field_[5]; }
+  uint64_t patches_succeeded() const { return patches_succeeded_; }
+  void set_patches_succeeded(uint64_t value) { patches_succeeded_ = value; _has_field_.set(5); }
+
+  bool has_patches_failed() const { return _has_field_[6]; }
+  uint64_t patches_failed() const { return patches_failed_; }
+  void set_patches_failed(uint64_t value) { patches_failed_ = value; _has_field_.set(6); }
+
+  bool has_readaheads_succeeded() const { return _has_field_[7]; }
+  uint64_t readaheads_succeeded() const { return readaheads_succeeded_; }
+  void set_readaheads_succeeded(uint64_t value) { readaheads_succeeded_ = value; _has_field_.set(7); }
+
+  bool has_readaheads_failed() const { return _has_field_[8]; }
+  uint64_t readaheads_failed() const { return readaheads_failed_; }
+  void set_readaheads_failed(uint64_t value) { readaheads_failed_ = value; _has_field_.set(8); }
+
+  bool has_abi_violations() const { return _has_field_[9]; }
+  uint64_t abi_violations() const { return abi_violations_; }
+  void set_abi_violations(uint64_t value) { abi_violations_ = value; _has_field_.set(9); }
+
+  bool has_trace_writer_packet_loss() const { return _has_field_[19]; }
+  uint64_t trace_writer_packet_loss() const { return trace_writer_packet_loss_; }
+  void set_trace_writer_packet_loss(uint64_t value) { trace_writer_packet_loss_ = value; _has_field_.set(19); }
+
+ private:
+  uint64_t buffer_size_{};
+  uint64_t bytes_written_{};
+  uint64_t bytes_overwritten_{};
+  uint64_t bytes_read_{};
+  uint64_t padding_bytes_written_{};
+  uint64_t padding_bytes_cleared_{};
+  uint64_t chunks_written_{};
+  uint64_t chunks_rewritten_{};
+  uint64_t chunks_overwritten_{};
+  uint64_t chunks_discarded_{};
+  uint64_t chunks_read_{};
+  uint64_t chunks_committed_out_of_order_{};
+  uint64_t write_wrap_count_{};
+  uint64_t patches_succeeded_{};
+  uint64_t patches_failed_{};
+  uint64_t readaheads_succeeded_{};
+  uint64_t readaheads_failed_{};
+  uint64_t abi_violations_{};
+  uint64_t trace_writer_packet_loss_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<20> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_capabilities.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TracingServiceCapabilities;
+enum ObservableEvents_Type : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TracingServiceCapabilities : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kHasQueryCapabilitiesFieldNumber = 1,
+    kObservableEventsFieldNumber = 2,
+    kHasTraceConfigOutputPathFieldNumber = 3,
+    kHasCloneSessionFieldNumber = 4,
+  };
+
+  TracingServiceCapabilities();
+  ~TracingServiceCapabilities() override;
+  TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept;
+  TracingServiceCapabilities& operator=(TracingServiceCapabilities&&);
+  TracingServiceCapabilities(const TracingServiceCapabilities&);
+  TracingServiceCapabilities& operator=(const TracingServiceCapabilities&);
+  bool operator==(const TracingServiceCapabilities&) const;
+  bool operator!=(const TracingServiceCapabilities& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_has_query_capabilities() const { return _has_field_[1]; }
+  bool has_query_capabilities() const { return has_query_capabilities_; }
+  void set_has_query_capabilities(bool value) { has_query_capabilities_ = value; _has_field_.set(1); }
+
+  const std::vector<ObservableEvents_Type>& observable_events() const { return observable_events_; }
+  std::vector<ObservableEvents_Type>* mutable_observable_events() { return &observable_events_; }
+  int observable_events_size() const { return static_cast<int>(observable_events_.size()); }
+  void clear_observable_events() { observable_events_.clear(); }
+  void add_observable_events(ObservableEvents_Type value) { observable_events_.emplace_back(value); }
+  ObservableEvents_Type* add_observable_events() { observable_events_.emplace_back(); return &observable_events_.back(); }
+
+  bool has_has_trace_config_output_path() const { return _has_field_[3]; }
+  bool has_trace_config_output_path() const { return has_trace_config_output_path_; }
+  void set_has_trace_config_output_path(bool value) { has_trace_config_output_path_ = value; _has_field_.set(3); }
+
+  bool has_has_clone_session() const { return _has_field_[4]; }
+  bool has_clone_session() const { return has_clone_session_; }
+  void set_has_clone_session(bool value) { has_clone_session_ = value; _has_field_.set(4); }
+
+ private:
+  bool has_query_capabilities_{};
+  std::vector<ObservableEvents_Type> observable_events_;
+  bool has_trace_config_output_path_{};
+  bool has_clone_session_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_state.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TracingServiceState;
+class TracingServiceState_TracingSession;
+class TracingServiceState_DataSource;
+class DataSourceDescriptor;
+class TracingServiceState_Producer;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TracingServiceState : public ::protozero::CppMessageObj {
+ public:
+  using Producer = TracingServiceState_Producer;
+  using DataSource = TracingServiceState_DataSource;
+  using TracingSession = TracingServiceState_TracingSession;
+  enum FieldNumbers {
+    kProducersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    kTracingSessionsFieldNumber = 6,
+    kSupportsTracingSessionsFieldNumber = 7,
+    kNumSessionsFieldNumber = 3,
+    kNumSessionsStartedFieldNumber = 4,
+    kTracingServiceVersionFieldNumber = 5,
+  };
+
+  TracingServiceState();
+  ~TracingServiceState() override;
+  TracingServiceState(TracingServiceState&&) noexcept;
+  TracingServiceState& operator=(TracingServiceState&&);
+  TracingServiceState(const TracingServiceState&);
+  TracingServiceState& operator=(const TracingServiceState&);
+  bool operator==(const TracingServiceState&) const;
+  bool operator!=(const TracingServiceState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TracingServiceState_Producer>& producers() const { return producers_; }
+  std::vector<TracingServiceState_Producer>* mutable_producers() { return &producers_; }
+  int producers_size() const;
+  void clear_producers();
+  TracingServiceState_Producer* add_producers();
+
+  const std::vector<TracingServiceState_DataSource>& data_sources() const { return data_sources_; }
+  std::vector<TracingServiceState_DataSource>* mutable_data_sources() { return &data_sources_; }
+  int data_sources_size() const;
+  void clear_data_sources();
+  TracingServiceState_DataSource* add_data_sources();
+
+  const std::vector<TracingServiceState_TracingSession>& tracing_sessions() const { return tracing_sessions_; }
+  std::vector<TracingServiceState_TracingSession>* mutable_tracing_sessions() { return &tracing_sessions_; }
+  int tracing_sessions_size() const;
+  void clear_tracing_sessions();
+  TracingServiceState_TracingSession* add_tracing_sessions();
+
+  bool has_supports_tracing_sessions() const { return _has_field_[7]; }
+  bool supports_tracing_sessions() const { return supports_tracing_sessions_; }
+  void set_supports_tracing_sessions(bool value) { supports_tracing_sessions_ = value; _has_field_.set(7); }
+
+  bool has_num_sessions() const { return _has_field_[3]; }
+  int32_t num_sessions() const { return num_sessions_; }
+  void set_num_sessions(int32_t value) { num_sessions_ = value; _has_field_.set(3); }
+
+  bool has_num_sessions_started() const { return _has_field_[4]; }
+  int32_t num_sessions_started() const { return num_sessions_started_; }
+  void set_num_sessions_started(int32_t value) { num_sessions_started_ = value; _has_field_.set(4); }
+
+  bool has_tracing_service_version() const { return _has_field_[5]; }
+  const std::string& tracing_service_version() const { return tracing_service_version_; }
+  void set_tracing_service_version(const std::string& value) { tracing_service_version_ = value; _has_field_.set(5); }
+
+ private:
+  std::vector<TracingServiceState_Producer> producers_;
+  std::vector<TracingServiceState_DataSource> data_sources_;
+  std::vector<TracingServiceState_TracingSession> tracing_sessions_;
+  bool supports_tracing_sessions_{};
+  int32_t num_sessions_{};
+  int32_t num_sessions_started_{};
+  std::string tracing_service_version_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TracingServiceState_TracingSession : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIdFieldNumber = 1,
+    kConsumerUidFieldNumber = 2,
+    kStateFieldNumber = 3,
+    kUniqueSessionNameFieldNumber = 4,
+    kBufferSizeKbFieldNumber = 5,
+    kDurationMsFieldNumber = 6,
+    kNumDataSourcesFieldNumber = 7,
+    kStartRealtimeNsFieldNumber = 8,
+  };
+
+  TracingServiceState_TracingSession();
+  ~TracingServiceState_TracingSession() override;
+  TracingServiceState_TracingSession(TracingServiceState_TracingSession&&) noexcept;
+  TracingServiceState_TracingSession& operator=(TracingServiceState_TracingSession&&);
+  TracingServiceState_TracingSession(const TracingServiceState_TracingSession&);
+  TracingServiceState_TracingSession& operator=(const TracingServiceState_TracingSession&);
+  bool operator==(const TracingServiceState_TracingSession&) const;
+  bool operator!=(const TracingServiceState_TracingSession& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_id() const { return _has_field_[1]; }
+  uint64_t id() const { return id_; }
+  void set_id(uint64_t value) { id_ = value; _has_field_.set(1); }
+
+  bool has_consumer_uid() const { return _has_field_[2]; }
+  int32_t consumer_uid() const { return consumer_uid_; }
+  void set_consumer_uid(int32_t value) { consumer_uid_ = value; _has_field_.set(2); }
+
+  bool has_state() const { return _has_field_[3]; }
+  const std::string& state() const { return state_; }
+  void set_state(const std::string& value) { state_ = value; _has_field_.set(3); }
+
+  bool has_unique_session_name() const { return _has_field_[4]; }
+  const std::string& unique_session_name() const { return unique_session_name_; }
+  void set_unique_session_name(const std::string& value) { unique_session_name_ = value; _has_field_.set(4); }
+
+  const std::vector<uint32_t>& buffer_size_kb() const { return buffer_size_kb_; }
+  std::vector<uint32_t>* mutable_buffer_size_kb() { return &buffer_size_kb_; }
+  int buffer_size_kb_size() const { return static_cast<int>(buffer_size_kb_.size()); }
+  void clear_buffer_size_kb() { buffer_size_kb_.clear(); }
+  void add_buffer_size_kb(uint32_t value) { buffer_size_kb_.emplace_back(value); }
+  uint32_t* add_buffer_size_kb() { buffer_size_kb_.emplace_back(); return &buffer_size_kb_.back(); }
+
+  bool has_duration_ms() const { return _has_field_[6]; }
+  uint32_t duration_ms() const { return duration_ms_; }
+  void set_duration_ms(uint32_t value) { duration_ms_ = value; _has_field_.set(6); }
+
+  bool has_num_data_sources() const { return _has_field_[7]; }
+  uint32_t num_data_sources() const { return num_data_sources_; }
+  void set_num_data_sources(uint32_t value) { num_data_sources_ = value; _has_field_.set(7); }
+
+  bool has_start_realtime_ns() const { return _has_field_[8]; }
+  int64_t start_realtime_ns() const { return start_realtime_ns_; }
+  void set_start_realtime_ns(int64_t value) { start_realtime_ns_ = value; _has_field_.set(8); }
+
+ private:
+  uint64_t id_{};
+  int32_t consumer_uid_{};
+  std::string state_{};
+  std::string unique_session_name_{};
+  std::vector<uint32_t> buffer_size_kb_;
+  uint32_t duration_ms_{};
+  uint32_t num_data_sources_{};
+  int64_t start_realtime_ns_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TracingServiceState_DataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDsDescriptorFieldNumber = 1,
+    kProducerIdFieldNumber = 2,
+  };
+
+  TracingServiceState_DataSource();
+  ~TracingServiceState_DataSource() override;
+  TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept;
+  TracingServiceState_DataSource& operator=(TracingServiceState_DataSource&&);
+  TracingServiceState_DataSource(const TracingServiceState_DataSource&);
+  TracingServiceState_DataSource& operator=(const TracingServiceState_DataSource&);
+  bool operator==(const TracingServiceState_DataSource&) const;
+  bool operator!=(const TracingServiceState_DataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_ds_descriptor() const { return _has_field_[1]; }
+  const DataSourceDescriptor& ds_descriptor() const { return *ds_descriptor_; }
+  DataSourceDescriptor* mutable_ds_descriptor() { _has_field_.set(1); return ds_descriptor_.get(); }
+
+  bool has_producer_id() const { return _has_field_[2]; }
+  int32_t producer_id() const { return producer_id_; }
+  void set_producer_id(int32_t value) { producer_id_ = value; _has_field_.set(2); }
+
+ private:
+  ::protozero::CopyablePtr<DataSourceDescriptor> ds_descriptor_;
+  int32_t producer_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TracingServiceState_Producer : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kPidFieldNumber = 5,
+    kUidFieldNumber = 3,
+    kSdkVersionFieldNumber = 4,
+  };
+
+  TracingServiceState_Producer();
+  ~TracingServiceState_Producer() override;
+  TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept;
+  TracingServiceState_Producer& operator=(TracingServiceState_Producer&&);
+  TracingServiceState_Producer(const TracingServiceState_Producer&);
+  TracingServiceState_Producer& operator=(const TracingServiceState_Producer&);
+  bool operator==(const TracingServiceState_Producer&) const;
+  bool operator!=(const TracingServiceState_Producer& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_id() const { return _has_field_[1]; }
+  int32_t id() const { return id_; }
+  void set_id(int32_t value) { id_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+  bool has_pid() const { return _has_field_[5]; }
+  int32_t pid() const { return pid_; }
+  void set_pid(int32_t value) { pid_ = value; _has_field_.set(5); }
+
+  bool has_uid() const { return _has_field_[3]; }
+  int32_t uid() const { return uid_; }
+  void set_uid(int32_t value) { uid_ = value; _has_field_.set(3); }
+
+  bool has_sdk_version() const { return _has_field_[4]; }
+  const std::string& sdk_version() const { return sdk_version_; }
+  void set_sdk_version(const std::string& value) { sdk_version_ = value; _has_field_.set(4); }
+
+ private:
+  int32_t id_{};
+  std::string name_{};
+  int32_t pid_{};
+  int32_t uid_{};
+  std::string sdk_version_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/track_event_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TrackEventDescriptor;
+class TrackEventCategory;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TrackEventDescriptor : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kAvailableCategoriesFieldNumber = 1,
+  };
+
+  TrackEventDescriptor();
+  ~TrackEventDescriptor() override;
+  TrackEventDescriptor(TrackEventDescriptor&&) noexcept;
+  TrackEventDescriptor& operator=(TrackEventDescriptor&&);
+  TrackEventDescriptor(const TrackEventDescriptor&);
+  TrackEventDescriptor& operator=(const TrackEventDescriptor&);
+  bool operator==(const TrackEventDescriptor&) const;
+  bool operator!=(const TrackEventDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<TrackEventCategory>& available_categories() const { return available_categories_; }
+  std::vector<TrackEventCategory>* mutable_available_categories() { return &available_categories_; }
+  int available_categories_size() const;
+  void clear_available_categories();
+  TrackEventCategory* add_available_categories();
+
+ private:
+  std::vector<TrackEventCategory> available_categories_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TrackEventCategory : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kDescriptionFieldNumber = 2,
+    kTagsFieldNumber = 3,
+  };
+
+  TrackEventCategory();
+  ~TrackEventCategory() override;
+  TrackEventCategory(TrackEventCategory&&) noexcept;
+  TrackEventCategory& operator=(TrackEventCategory&&);
+  TrackEventCategory(const TrackEventCategory&);
+  TrackEventCategory& operator=(const TrackEventCategory&);
+  bool operator==(const TrackEventCategory&) const;
+  bool operator!=(const TrackEventCategory& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_description() const { return _has_field_[2]; }
+  const std::string& description() const { return description_; }
+  void set_description(const std::string& value) { description_ = value; _has_field_.set(2); }
+
+  const std::vector<std::string>& tags() const { return tags_; }
+  std::vector<std::string>* mutable_tags() { return &tags_; }
+  int tags_size() const { return static_cast<int>(tags_.size()); }
+  void clear_tags() { tags_.clear(); }
+  void add_tags(std::string value) { tags_.emplace_back(value); }
+  std::string* add_tags() { tags_.emplace_back(); return &tags_.back(); }
+
+ private:
+  std::string name_{};
+  std::string description_{};
+  std::vector<std::string> tags_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidEnergyConsumer;
+
+class AndroidEnergyConsumerDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidEnergyConsumerDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidEnergyConsumerDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidEnergyConsumerDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_energy_consumers() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> energy_consumers() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class AndroidEnergyConsumerDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = AndroidEnergyConsumerDescriptor_Decoder;
+  enum : int32_t {
+    kEnergyConsumersFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidEnergyConsumerDescriptor"; }
+
+
+  using FieldMetadata_EnergyConsumers =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidEnergyConsumer,
+      AndroidEnergyConsumerDescriptor>;
+
+  static constexpr FieldMetadata_EnergyConsumers kEnergyConsumers{};
+  template <typename T = AndroidEnergyConsumer> T* add_energy_consumers() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class AndroidEnergyConsumer_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidEnergyConsumer_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidEnergyConsumer_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidEnergyConsumer_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_energy_consumer_id() const { return at<1>().valid(); }
+  int32_t energy_consumer_id() const { return at<1>().as_int32(); }
+  bool has_ordinal() const { return at<2>().valid(); }
+  int32_t ordinal() const { return at<2>().as_int32(); }
+  bool has_type() const { return at<3>().valid(); }
+  ::protozero::ConstChars type() const { return at<3>().as_string(); }
+  bool has_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars name() const { return at<4>().as_string(); }
+};
+
+class AndroidEnergyConsumer : public ::protozero::Message {
+ public:
+  using Decoder = AndroidEnergyConsumer_Decoder;
+  enum : int32_t {
+    kEnergyConsumerIdFieldNumber = 1,
+    kOrdinalFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kNameFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidEnergyConsumer"; }
+
+
+  using FieldMetadata_EnergyConsumerId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidEnergyConsumer>;
+
+  static constexpr FieldMetadata_EnergyConsumerId kEnergyConsumerId{};
+  void set_energy_consumer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnergyConsumerId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ordinal =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidEnergyConsumer>;
+
+  static constexpr FieldMetadata_Ordinal kOrdinal{};
+  void set_ordinal(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ordinal::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidEnergyConsumer>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Type::kFieldId, data, size);
+  }
+  void set_type(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Type::kFieldId, chars.data, chars.size);
+  }
+  void set_type(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidEnergyConsumer>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/android_log_constants.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+enum AndroidLogId : int32_t {
+  LID_DEFAULT = 0,
+  LID_RADIO = 1,
+  LID_EVENTS = 2,
+  LID_SYSTEM = 3,
+  LID_CRASH = 4,
+  LID_STATS = 5,
+  LID_SECURITY = 6,
+  LID_KERNEL = 7,
+};
+
+constexpr AndroidLogId AndroidLogId_MIN = AndroidLogId::LID_DEFAULT;
+constexpr AndroidLogId AndroidLogId_MAX = AndroidLogId::LID_KERNEL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AndroidLogId_Name(::perfetto::protos::pbzero::AndroidLogId value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_DEFAULT:
+    return "LID_DEFAULT";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_RADIO:
+    return "LID_RADIO";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_EVENTS:
+    return "LID_EVENTS";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_SYSTEM:
+    return "LID_SYSTEM";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_CRASH:
+    return "LID_CRASH";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_STATS:
+    return "LID_STATS";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_SECURITY:
+    return "LID_SECURITY";
+
+  case ::perfetto::protos::pbzero::AndroidLogId::LID_KERNEL:
+    return "LID_KERNEL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+enum AndroidLogPriority : int32_t {
+  PRIO_UNSPECIFIED = 0,
+  PRIO_UNUSED = 1,
+  PRIO_VERBOSE = 2,
+  PRIO_DEBUG = 3,
+  PRIO_INFO = 4,
+  PRIO_WARN = 5,
+  PRIO_ERROR = 6,
+  PRIO_FATAL = 7,
+};
+
+constexpr AndroidLogPriority AndroidLogPriority_MIN = AndroidLogPriority::PRIO_UNSPECIFIED;
+constexpr AndroidLogPriority AndroidLogPriority_MAX = AndroidLogPriority::PRIO_FATAL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AndroidLogPriority_Name(::perfetto::protos::pbzero::AndroidLogPriority value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_UNSPECIFIED:
+    return "PRIO_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_UNUSED:
+    return "PRIO_UNUSED";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_VERBOSE:
+    return "PRIO_VERBOSE";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_DEBUG:
+    return "PRIO_DEBUG";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_INFO:
+    return "PRIO_INFO";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_WARN:
+    return "PRIO_WARN";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_ERROR:
+    return "PRIO_ERROR";
+
+  case ::perfetto::protos::pbzero::AndroidLogPriority::PRIO_FATAL:
+    return "PRIO_FATAL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/commit_data_request.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class CommitDataRequest_ChunkToPatch;
+class CommitDataRequest_ChunkToPatch_Patch;
+class CommitDataRequest_ChunksToMove;
+
+class CommitDataRequest_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  CommitDataRequest_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CommitDataRequest_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CommitDataRequest_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chunks_to_move() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> chunks_to_move() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_chunks_to_patch() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> chunks_to_patch() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_flush_request_id() const { return at<3>().valid(); }
+  uint64_t flush_request_id() const { return at<3>().as_uint64(); }
+};
+
+class CommitDataRequest : public ::protozero::Message {
+ public:
+  using Decoder = CommitDataRequest_Decoder;
+  enum : int32_t {
+    kChunksToMoveFieldNumber = 1,
+    kChunksToPatchFieldNumber = 2,
+    kFlushRequestIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CommitDataRequest"; }
+
+  using ChunksToMove = ::perfetto::protos::pbzero::CommitDataRequest_ChunksToMove;
+  using ChunkToPatch = ::perfetto::protos::pbzero::CommitDataRequest_ChunkToPatch;
+
+  using FieldMetadata_ChunksToMove =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CommitDataRequest_ChunksToMove,
+      CommitDataRequest>;
+
+  static constexpr FieldMetadata_ChunksToMove kChunksToMove{};
+  template <typename T = CommitDataRequest_ChunksToMove> T* add_chunks_to_move() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ChunksToPatch =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CommitDataRequest_ChunkToPatch,
+      CommitDataRequest>;
+
+  static constexpr FieldMetadata_ChunksToPatch kChunksToPatch{};
+  template <typename T = CommitDataRequest_ChunkToPatch> T* add_chunks_to_patch() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_FlushRequestId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CommitDataRequest>;
+
+  static constexpr FieldMetadata_FlushRequestId kFlushRequestId{};
+  void set_flush_request_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushRequestId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CommitDataRequest_ChunkToPatch_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  CommitDataRequest_ChunkToPatch_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CommitDataRequest_ChunkToPatch_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CommitDataRequest_ChunkToPatch_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_target_buffer() const { return at<1>().valid(); }
+  uint32_t target_buffer() const { return at<1>().as_uint32(); }
+  bool has_writer_id() const { return at<2>().valid(); }
+  uint32_t writer_id() const { return at<2>().as_uint32(); }
+  bool has_chunk_id() const { return at<3>().valid(); }
+  uint32_t chunk_id() const { return at<3>().as_uint32(); }
+  bool has_patches() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> patches() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_has_more_patches() const { return at<5>().valid(); }
+  bool has_more_patches() const { return at<5>().as_bool(); }
+};
+
+class CommitDataRequest_ChunkToPatch : public ::protozero::Message {
+ public:
+  using Decoder = CommitDataRequest_ChunkToPatch_Decoder;
+  enum : int32_t {
+    kTargetBufferFieldNumber = 1,
+    kWriterIdFieldNumber = 2,
+    kChunkIdFieldNumber = 3,
+    kPatchesFieldNumber = 4,
+    kHasMorePatchesFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CommitDataRequest.ChunkToPatch"; }
+
+  using Patch = ::perfetto::protos::pbzero::CommitDataRequest_ChunkToPatch_Patch;
+
+  using FieldMetadata_TargetBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunkToPatch>;
+
+  static constexpr FieldMetadata_TargetBuffer kTargetBuffer{};
+  void set_target_buffer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetBuffer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WriterId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunkToPatch>;
+
+  static constexpr FieldMetadata_WriterId kWriterId{};
+  void set_writer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriterId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChunkId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunkToPatch>;
+
+  static constexpr FieldMetadata_ChunkId kChunkId{};
+  void set_chunk_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunkId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Patches =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CommitDataRequest_ChunkToPatch_Patch,
+      CommitDataRequest_ChunkToPatch>;
+
+  static constexpr FieldMetadata_Patches kPatches{};
+  template <typename T = CommitDataRequest_ChunkToPatch_Patch> T* add_patches() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_HasMorePatches =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      CommitDataRequest_ChunkToPatch>;
+
+  static constexpr FieldMetadata_HasMorePatches kHasMorePatches{};
+  void set_has_more_patches(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasMorePatches::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CommitDataRequest_ChunkToPatch_Patch_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CommitDataRequest_ChunkToPatch_Patch_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CommitDataRequest_ChunkToPatch_Patch_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CommitDataRequest_ChunkToPatch_Patch_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_offset() const { return at<1>().valid(); }
+  uint32_t offset() const { return at<1>().as_uint32(); }
+  bool has_data() const { return at<2>().valid(); }
+  ::protozero::ConstBytes data() const { return at<2>().as_bytes(); }
+};
+
+class CommitDataRequest_ChunkToPatch_Patch : public ::protozero::Message {
+ public:
+  using Decoder = CommitDataRequest_ChunkToPatch_Patch_Decoder;
+  enum : int32_t {
+    kOffsetFieldNumber = 1,
+    kDataFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CommitDataRequest.ChunkToPatch.Patch"; }
+
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunkToPatch_Patch>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Data =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      CommitDataRequest_ChunkToPatch_Patch>;
+
+  static constexpr FieldMetadata_Data kData{};
+  void set_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Data::kFieldId, data, size);
+  }
+  void set_data(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Data::kFieldId, bytes.data, bytes.size);
+  }
+  void set_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Data::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CommitDataRequest_ChunksToMove_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CommitDataRequest_ChunksToMove_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CommitDataRequest_ChunksToMove_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CommitDataRequest_ChunksToMove_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_page() const { return at<1>().valid(); }
+  uint32_t page() const { return at<1>().as_uint32(); }
+  bool has_chunk() const { return at<2>().valid(); }
+  uint32_t chunk() const { return at<2>().as_uint32(); }
+  bool has_target_buffer() const { return at<3>().valid(); }
+  uint32_t target_buffer() const { return at<3>().as_uint32(); }
+  bool has_data() const { return at<4>().valid(); }
+  ::protozero::ConstBytes data() const { return at<4>().as_bytes(); }
+};
+
+class CommitDataRequest_ChunksToMove : public ::protozero::Message {
+ public:
+  using Decoder = CommitDataRequest_ChunksToMove_Decoder;
+  enum : int32_t {
+    kPageFieldNumber = 1,
+    kChunkFieldNumber = 2,
+    kTargetBufferFieldNumber = 3,
+    kDataFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CommitDataRequest.ChunksToMove"; }
+
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunksToMove>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Chunk =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunksToMove>;
+
+  static constexpr FieldMetadata_Chunk kChunk{};
+  void set_chunk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chunk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CommitDataRequest_ChunksToMove>;
+
+  static constexpr FieldMetadata_TargetBuffer kTargetBuffer{};
+  void set_target_buffer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetBuffer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Data =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      CommitDataRequest_ChunksToMove>;
+
+  static constexpr FieldMetadata_Data kData{};
+  void set_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Data::kFieldId, data, size);
+  }
+  void set_data(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Data::kFieldId, bytes.data, bytes.size);
+  }
+  void set_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Data::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/data_source_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DATA_SOURCE_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FtraceDescriptor;
+class GpuCounterDescriptor;
+class TrackEventDescriptor;
+
+class DataSourceDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DataSourceDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DataSourceDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DataSourceDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_id() const { return at<7>().valid(); }
+  uint64_t id() const { return at<7>().as_uint64(); }
+  bool has_will_notify_on_stop() const { return at<2>().valid(); }
+  bool will_notify_on_stop() const { return at<2>().as_bool(); }
+  bool has_will_notify_on_start() const { return at<3>().valid(); }
+  bool will_notify_on_start() const { return at<3>().as_bool(); }
+  bool has_handles_incremental_state_clear() const { return at<4>().valid(); }
+  bool handles_incremental_state_clear() const { return at<4>().as_bool(); }
+  bool has_no_flush() const { return at<9>().valid(); }
+  bool no_flush() const { return at<9>().as_bool(); }
+  bool has_gpu_counter_descriptor() const { return at<5>().valid(); }
+  ::protozero::ConstBytes gpu_counter_descriptor() const { return at<5>().as_bytes(); }
+  bool has_track_event_descriptor() const { return at<6>().valid(); }
+  ::protozero::ConstBytes track_event_descriptor() const { return at<6>().as_bytes(); }
+  bool has_ftrace_descriptor() const { return at<8>().valid(); }
+  ::protozero::ConstBytes ftrace_descriptor() const { return at<8>().as_bytes(); }
+};
+
+class DataSourceDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = DataSourceDescriptor_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kIdFieldNumber = 7,
+    kWillNotifyOnStopFieldNumber = 2,
+    kWillNotifyOnStartFieldNumber = 3,
+    kHandlesIncrementalStateClearFieldNumber = 4,
+    kNoFlushFieldNumber = 9,
+    kGpuCounterDescriptorFieldNumber = 5,
+    kTrackEventDescriptorFieldNumber = 6,
+    kFtraceDescriptorFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DataSourceDescriptor"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WillNotifyOnStop =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_WillNotifyOnStop kWillNotifyOnStop{};
+  void set_will_notify_on_stop(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_WillNotifyOnStop::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WillNotifyOnStart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_WillNotifyOnStart kWillNotifyOnStart{};
+  void set_will_notify_on_start(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_WillNotifyOnStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HandlesIncrementalStateClear =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_HandlesIncrementalStateClear kHandlesIncrementalStateClear{};
+  void set_handles_incremental_state_clear(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HandlesIncrementalStateClear::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NoFlush =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_NoFlush kNoFlush{};
+  void set_no_flush(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NoFlush::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GpuCounterDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterDescriptor,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_GpuCounterDescriptor kGpuCounterDescriptor{};
+  template <typename T = GpuCounterDescriptor> T* set_gpu_counter_descriptor() {
+    return BeginNestedMessage<T>(5);
+  }
+
+  void set_gpu_counter_descriptor_raw(const std::string& raw) {
+    return AppendBytes(5, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_TrackEventDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventDescriptor,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_TrackEventDescriptor kTrackEventDescriptor{};
+  template <typename T = TrackEventDescriptor> T* set_track_event_descriptor() {
+    return BeginNestedMessage<T>(6);
+  }
+
+  void set_track_event_descriptor_raw(const std::string& raw) {
+    return AppendBytes(6, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_FtraceDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceDescriptor,
+      DataSourceDescriptor>;
+
+  static constexpr FieldMetadata_FtraceDescriptor kFtraceDescriptor{};
+  template <typename T = FtraceDescriptor> T* set_ftrace_descriptor() {
+    return BeginNestedMessage<T>(8);
+  }
+
+  void set_ftrace_descriptor_raw(const std::string& raw) {
+    return AppendBytes(8, raw.data(), raw.size());
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DescriptorProto;
+class DescriptorProto_ReservedRange;
+class EnumDescriptorProto;
+class EnumValueDescriptorProto;
+class FieldDescriptorProto;
+class FieldOptions;
+class FileDescriptorProto;
+class OneofDescriptorProto;
+class OneofOptions;
+class UninterpretedOption;
+class UninterpretedOption_NamePart;
+namespace perfetto_pbzero_enum_FieldDescriptorProto {
+enum Label : int32_t;
+}  // namespace perfetto_pbzero_enum_FieldDescriptorProto
+using FieldDescriptorProto_Label = perfetto_pbzero_enum_FieldDescriptorProto::Label;
+namespace perfetto_pbzero_enum_FieldDescriptorProto {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_FieldDescriptorProto
+using FieldDescriptorProto_Type = perfetto_pbzero_enum_FieldDescriptorProto::Type;
+
+namespace perfetto_pbzero_enum_FieldDescriptorProto {
+enum Type : int32_t {
+  TYPE_DOUBLE = 1,
+  TYPE_FLOAT = 2,
+  TYPE_INT64 = 3,
+  TYPE_UINT64 = 4,
+  TYPE_INT32 = 5,
+  TYPE_FIXED64 = 6,
+  TYPE_FIXED32 = 7,
+  TYPE_BOOL = 8,
+  TYPE_STRING = 9,
+  TYPE_GROUP = 10,
+  TYPE_MESSAGE = 11,
+  TYPE_BYTES = 12,
+  TYPE_UINT32 = 13,
+  TYPE_ENUM = 14,
+  TYPE_SFIXED32 = 15,
+  TYPE_SFIXED64 = 16,
+  TYPE_SINT32 = 17,
+  TYPE_SINT64 = 18,
+};
+} // namespace perfetto_pbzero_enum_FieldDescriptorProto
+using FieldDescriptorProto_Type = perfetto_pbzero_enum_FieldDescriptorProto::Type;
+
+
+constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_MIN = FieldDescriptorProto_Type::TYPE_DOUBLE;
+constexpr FieldDescriptorProto_Type FieldDescriptorProto_Type_MAX = FieldDescriptorProto_Type::TYPE_SINT64;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FieldDescriptorProto_Type_Name(::perfetto::protos::pbzero::FieldDescriptorProto_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_DOUBLE:
+    return "TYPE_DOUBLE";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_FLOAT:
+    return "TYPE_FLOAT";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_INT64:
+    return "TYPE_INT64";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_UINT64:
+    return "TYPE_UINT64";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_INT32:
+    return "TYPE_INT32";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_FIXED64:
+    return "TYPE_FIXED64";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_FIXED32:
+    return "TYPE_FIXED32";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_BOOL:
+    return "TYPE_BOOL";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_STRING:
+    return "TYPE_STRING";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_GROUP:
+    return "TYPE_GROUP";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_MESSAGE:
+    return "TYPE_MESSAGE";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_BYTES:
+    return "TYPE_BYTES";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_UINT32:
+    return "TYPE_UINT32";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_ENUM:
+    return "TYPE_ENUM";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_SFIXED32:
+    return "TYPE_SFIXED32";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_SFIXED64:
+    return "TYPE_SFIXED64";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_SINT32:
+    return "TYPE_SINT32";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Type::TYPE_SINT64:
+    return "TYPE_SINT64";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_FieldDescriptorProto {
+enum Label : int32_t {
+  LABEL_OPTIONAL = 1,
+  LABEL_REQUIRED = 2,
+  LABEL_REPEATED = 3,
+};
+} // namespace perfetto_pbzero_enum_FieldDescriptorProto
+using FieldDescriptorProto_Label = perfetto_pbzero_enum_FieldDescriptorProto::Label;
+
+
+constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_MIN = FieldDescriptorProto_Label::LABEL_OPTIONAL;
+constexpr FieldDescriptorProto_Label FieldDescriptorProto_Label_MAX = FieldDescriptorProto_Label::LABEL_REPEATED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FieldDescriptorProto_Label_Name(::perfetto::protos::pbzero::FieldDescriptorProto_Label value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Label::LABEL_OPTIONAL:
+    return "LABEL_OPTIONAL";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Label::LABEL_REQUIRED:
+    return "LABEL_REQUIRED";
+
+  case ::perfetto::protos::pbzero::FieldDescriptorProto_Label::LABEL_REPEATED:
+    return "LABEL_REPEATED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class OneofOptions_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  OneofOptions_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit OneofOptions_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit OneofOptions_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class OneofOptions : public ::protozero::Message {
+ public:
+  using Decoder = OneofOptions_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.OneofOptions"; }
+
+};
+
+class EnumValueDescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EnumValueDescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EnumValueDescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EnumValueDescriptorProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_number() const { return at<2>().valid(); }
+  int32_t number() const { return at<2>().as_int32(); }
+};
+
+class EnumValueDescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = EnumValueDescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kNumberFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EnumValueDescriptorProto"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EnumValueDescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Number =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      EnumValueDescriptorProto>;
+
+  static constexpr FieldMetadata_Number kNumber{};
+  void set_number(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Number::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class EnumDescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  EnumDescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EnumDescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EnumDescriptorProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> value() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_reserved_name() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> reserved_name() const { return GetRepeated<::protozero::ConstChars>(5); }
+};
+
+class EnumDescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = EnumDescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+    kReservedNameFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EnumDescriptorProto"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EnumDescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EnumValueDescriptorProto,
+      EnumDescriptorProto>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  template <typename T = EnumValueDescriptorProto> T* add_value() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ReservedName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EnumDescriptorProto>;
+
+  static constexpr FieldMetadata_ReservedName kReservedName{};
+  void add_reserved_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ReservedName::kFieldId, data, size);
+  }
+  void add_reserved_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ReservedName::kFieldId, chars.data, chars.size);
+  }
+  void add_reserved_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class OneofDescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  OneofDescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit OneofDescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit OneofDescriptorProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_options() const { return at<2>().valid(); }
+  ::protozero::ConstBytes options() const { return at<2>().as_bytes(); }
+};
+
+class OneofDescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = OneofDescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kOptionsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.OneofDescriptorProto"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      OneofDescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Options =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      OneofOptions,
+      OneofDescriptorProto>;
+
+  static constexpr FieldMetadata_Options kOptions{};
+  template <typename T = OneofOptions> T* set_options() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class FieldDescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FieldDescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FieldDescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FieldDescriptorProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_number() const { return at<3>().valid(); }
+  int32_t number() const { return at<3>().as_int32(); }
+  bool has_label() const { return at<4>().valid(); }
+  int32_t label() const { return at<4>().as_int32(); }
+  bool has_type() const { return at<5>().valid(); }
+  int32_t type() const { return at<5>().as_int32(); }
+  bool has_type_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars type_name() const { return at<6>().as_string(); }
+  bool has_extendee() const { return at<2>().valid(); }
+  ::protozero::ConstChars extendee() const { return at<2>().as_string(); }
+  bool has_default_value() const { return at<7>().valid(); }
+  ::protozero::ConstChars default_value() const { return at<7>().as_string(); }
+  bool has_options() const { return at<8>().valid(); }
+  ::protozero::ConstBytes options() const { return at<8>().as_bytes(); }
+  bool has_oneof_index() const { return at<9>().valid(); }
+  int32_t oneof_index() const { return at<9>().as_int32(); }
+};
+
+class FieldDescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = FieldDescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kNumberFieldNumber = 3,
+    kLabelFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kTypeNameFieldNumber = 6,
+    kExtendeeFieldNumber = 2,
+    kDefaultValueFieldNumber = 7,
+    kOptionsFieldNumber = 8,
+    kOneofIndexFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FieldDescriptorProto"; }
+
+
+  using Type = ::perfetto::protos::pbzero::FieldDescriptorProto_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::FieldDescriptorProto_Type_Name(value);
+  }
+
+  using Label = ::perfetto::protos::pbzero::FieldDescriptorProto_Label;
+  static inline const char* Label_Name(Label value) {
+    return ::perfetto::protos::pbzero::FieldDescriptorProto_Label_Name(value);
+  }
+  static inline const Type TYPE_DOUBLE = Type::TYPE_DOUBLE;
+  static inline const Type TYPE_FLOAT = Type::TYPE_FLOAT;
+  static inline const Type TYPE_INT64 = Type::TYPE_INT64;
+  static inline const Type TYPE_UINT64 = Type::TYPE_UINT64;
+  static inline const Type TYPE_INT32 = Type::TYPE_INT32;
+  static inline const Type TYPE_FIXED64 = Type::TYPE_FIXED64;
+  static inline const Type TYPE_FIXED32 = Type::TYPE_FIXED32;
+  static inline const Type TYPE_BOOL = Type::TYPE_BOOL;
+  static inline const Type TYPE_STRING = Type::TYPE_STRING;
+  static inline const Type TYPE_GROUP = Type::TYPE_GROUP;
+  static inline const Type TYPE_MESSAGE = Type::TYPE_MESSAGE;
+  static inline const Type TYPE_BYTES = Type::TYPE_BYTES;
+  static inline const Type TYPE_UINT32 = Type::TYPE_UINT32;
+  static inline const Type TYPE_ENUM = Type::TYPE_ENUM;
+  static inline const Type TYPE_SFIXED32 = Type::TYPE_SFIXED32;
+  static inline const Type TYPE_SFIXED64 = Type::TYPE_SFIXED64;
+  static inline const Type TYPE_SINT32 = Type::TYPE_SINT32;
+  static inline const Type TYPE_SINT64 = Type::TYPE_SINT64;
+  static inline const Label LABEL_OPTIONAL = Label::LABEL_OPTIONAL;
+  static inline const Label LABEL_REQUIRED = Label::LABEL_REQUIRED;
+  static inline const Label LABEL_REPEATED = Label::LABEL_REPEATED;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Number =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Number kNumber{};
+  void set_number(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Number::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Label =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FieldDescriptorProto_Label,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Label kLabel{};
+  void set_label(::perfetto::protos::pbzero::FieldDescriptorProto_Label value) {
+    static constexpr uint32_t field_id = FieldMetadata_Label::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FieldDescriptorProto_Type,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(::perfetto::protos::pbzero::FieldDescriptorProto_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TypeName =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_TypeName kTypeName{};
+  void set_type_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TypeName::kFieldId, data, size);
+  }
+  void set_type_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TypeName::kFieldId, chars.data, chars.size);
+  }
+  void set_type_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TypeName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Extendee =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Extendee kExtendee{};
+  void set_extendee(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Extendee::kFieldId, data, size);
+  }
+  void set_extendee(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Extendee::kFieldId, chars.data, chars.size);
+  }
+  void set_extendee(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Extendee::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DefaultValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_DefaultValue kDefaultValue{};
+  void set_default_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DefaultValue::kFieldId, data, size);
+  }
+  void set_default_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DefaultValue::kFieldId, chars.data, chars.size);
+  }
+  void set_default_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DefaultValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Options =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FieldOptions,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_Options kOptions{};
+  template <typename T = FieldOptions> T* set_options() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_OneofIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FieldDescriptorProto>;
+
+  static constexpr FieldMetadata_OneofIndex kOneofIndex{};
+  void set_oneof_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OneofIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FieldOptions_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/999, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FieldOptions_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FieldOptions_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FieldOptions_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_packed() const { return at<2>().valid(); }
+  bool packed() const { return at<2>().as_bool(); }
+  bool has_uninterpreted_option() const { return at<999>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> uninterpreted_option() const { return GetRepeated<::protozero::ConstBytes>(999); }
+};
+
+class FieldOptions : public ::protozero::Message {
+ public:
+  using Decoder = FieldOptions_Decoder;
+  enum : int32_t {
+    kPackedFieldNumber = 2,
+    kUninterpretedOptionFieldNumber = 999,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FieldOptions"; }
+
+
+  using FieldMetadata_Packed =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FieldOptions>;
+
+  static constexpr FieldMetadata_Packed kPacked{};
+  void set_packed(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Packed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UninterpretedOption =
+    ::protozero::proto_utils::FieldMetadata<
+      999,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UninterpretedOption,
+      FieldOptions>;
+
+  static constexpr FieldMetadata_UninterpretedOption kUninterpretedOption{};
+  template <typename T = UninterpretedOption> T* add_uninterpreted_option() {
+    return BeginNestedMessage<T>(999);
+  }
+
+};
+
+class UninterpretedOption_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  UninterpretedOption_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UninterpretedOption_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UninterpretedOption_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> name() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_identifier_value() const { return at<3>().valid(); }
+  ::protozero::ConstChars identifier_value() const { return at<3>().as_string(); }
+  bool has_positive_int_value() const { return at<4>().valid(); }
+  uint64_t positive_int_value() const { return at<4>().as_uint64(); }
+  bool has_negative_int_value() const { return at<5>().valid(); }
+  int64_t negative_int_value() const { return at<5>().as_int64(); }
+  bool has_double_value() const { return at<6>().valid(); }
+  double double_value() const { return at<6>().as_double(); }
+  bool has_string_value() const { return at<7>().valid(); }
+  ::protozero::ConstBytes string_value() const { return at<7>().as_bytes(); }
+  bool has_aggregate_value() const { return at<8>().valid(); }
+  ::protozero::ConstChars aggregate_value() const { return at<8>().as_string(); }
+};
+
+class UninterpretedOption : public ::protozero::Message {
+ public:
+  using Decoder = UninterpretedOption_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 2,
+    kIdentifierValueFieldNumber = 3,
+    kPositiveIntValueFieldNumber = 4,
+    kNegativeIntValueFieldNumber = 5,
+    kDoubleValueFieldNumber = 6,
+    kStringValueFieldNumber = 7,
+    kAggregateValueFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UninterpretedOption"; }
+
+  using NamePart = ::perfetto::protos::pbzero::UninterpretedOption_NamePart;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UninterpretedOption_NamePart,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_Name kName{};
+  template <typename T = UninterpretedOption_NamePart> T* add_name() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_IdentifierValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_IdentifierValue kIdentifierValue{};
+  void set_identifier_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_IdentifierValue::kFieldId, data, size);
+  }
+  void set_identifier_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_IdentifierValue::kFieldId, chars.data, chars.size);
+  }
+  void set_identifier_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_IdentifierValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PositiveIntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_PositiveIntValue kPositiveIntValue{};
+  void set_positive_int_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PositiveIntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NegativeIntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_NegativeIntValue kNegativeIntValue{};
+  void set_negative_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NegativeIntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, bytes.data, bytes.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AggregateValue =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UninterpretedOption>;
+
+  static constexpr FieldMetadata_AggregateValue kAggregateValue{};
+  void set_aggregate_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AggregateValue::kFieldId, data, size);
+  }
+  void set_aggregate_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AggregateValue::kFieldId, chars.data, chars.size);
+  }
+  void set_aggregate_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AggregateValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class UninterpretedOption_NamePart_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UninterpretedOption_NamePart_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UninterpretedOption_NamePart_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UninterpretedOption_NamePart_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name_part() const { return at<1>().valid(); }
+  ::protozero::ConstChars name_part() const { return at<1>().as_string(); }
+  bool has_is_extension() const { return at<2>().valid(); }
+  bool is_extension() const { return at<2>().as_bool(); }
+};
+
+class UninterpretedOption_NamePart : public ::protozero::Message {
+ public:
+  using Decoder = UninterpretedOption_NamePart_Decoder;
+  enum : int32_t {
+    kNamePartFieldNumber = 1,
+    kIsExtensionFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UninterpretedOption.NamePart"; }
+
+
+  using FieldMetadata_NamePart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UninterpretedOption_NamePart>;
+
+  static constexpr FieldMetadata_NamePart kNamePart{};
+  void set_name_part(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_NamePart::kFieldId, data, size);
+  }
+  void set_name_part(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_NamePart::kFieldId, chars.data, chars.size);
+  }
+  void set_name_part(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_NamePart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsExtension =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      UninterpretedOption_NamePart>;
+
+  static constexpr FieldMetadata_IsExtension kIsExtension{};
+  void set_is_extension(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsExtension::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  DescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DescriptorProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_field() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> field() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_extension() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> extension() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_nested_type() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> nested_type() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_enum_type() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> enum_type() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_oneof_decl() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> oneof_decl() const { return GetRepeated<::protozero::ConstBytes>(8); }
+  bool has_reserved_range() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> reserved_range() const { return GetRepeated<::protozero::ConstBytes>(9); }
+  bool has_reserved_name() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> reserved_name() const { return GetRepeated<::protozero::ConstChars>(10); }
+};
+
+class DescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = DescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kFieldFieldNumber = 2,
+    kExtensionFieldNumber = 6,
+    kNestedTypeFieldNumber = 3,
+    kEnumTypeFieldNumber = 4,
+    kOneofDeclFieldNumber = 8,
+    kReservedRangeFieldNumber = 9,
+    kReservedNameFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DescriptorProto"; }
+
+  using ReservedRange = ::perfetto::protos::pbzero::DescriptorProto_ReservedRange;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FieldDescriptorProto,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_Field kField{};
+  template <typename T = FieldDescriptorProto> T* add_field() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_Extension =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FieldDescriptorProto,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_Extension kExtension{};
+  template <typename T = FieldDescriptorProto> T* add_extension() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_NestedType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DescriptorProto,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_NestedType kNestedType{};
+  template <typename T = DescriptorProto> T* add_nested_type() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_EnumType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EnumDescriptorProto,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_EnumType kEnumType{};
+  template <typename T = EnumDescriptorProto> T* add_enum_type() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_OneofDecl =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      OneofDescriptorProto,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_OneofDecl kOneofDecl{};
+  template <typename T = OneofDescriptorProto> T* add_oneof_decl() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_ReservedRange =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DescriptorProto_ReservedRange,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_ReservedRange kReservedRange{};
+  template <typename T = DescriptorProto_ReservedRange> T* add_reserved_range() {
+    return BeginNestedMessage<T>(9);
+  }
+
+
+  using FieldMetadata_ReservedName =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DescriptorProto>;
+
+  static constexpr FieldMetadata_ReservedName kReservedName{};
+  void add_reserved_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ReservedName::kFieldId, data, size);
+  }
+  void add_reserved_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ReservedName::kFieldId, chars.data, chars.size);
+  }
+  void add_reserved_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DescriptorProto_ReservedRange_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DescriptorProto_ReservedRange_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DescriptorProto_ReservedRange_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DescriptorProto_ReservedRange_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_start() const { return at<1>().valid(); }
+  int32_t start() const { return at<1>().as_int32(); }
+  bool has_end() const { return at<2>().valid(); }
+  int32_t end() const { return at<2>().as_int32(); }
+};
+
+class DescriptorProto_ReservedRange : public ::protozero::Message {
+ public:
+  using Decoder = DescriptorProto_ReservedRange_Decoder;
+  enum : int32_t {
+    kStartFieldNumber = 1,
+    kEndFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DescriptorProto.ReservedRange"; }
+
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DescriptorProto_ReservedRange>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_End =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DescriptorProto_ReservedRange>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FileDescriptorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FileDescriptorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FileDescriptorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FileDescriptorProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_package() const { return at<2>().valid(); }
+  ::protozero::ConstChars package() const { return at<2>().as_string(); }
+  bool has_dependency() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> dependency() const { return GetRepeated<::protozero::ConstChars>(3); }
+  bool has_public_dependency() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> public_dependency() const { return GetRepeated<int32_t>(10); }
+  bool has_weak_dependency() const { return at<11>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> weak_dependency() const { return GetRepeated<int32_t>(11); }
+  bool has_message_type() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> message_type() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_enum_type() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> enum_type() const { return GetRepeated<::protozero::ConstBytes>(5); }
+  bool has_extension() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> extension() const { return GetRepeated<::protozero::ConstBytes>(7); }
+};
+
+class FileDescriptorProto : public ::protozero::Message {
+ public:
+  using Decoder = FileDescriptorProto_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kPackageFieldNumber = 2,
+    kDependencyFieldNumber = 3,
+    kPublicDependencyFieldNumber = 10,
+    kWeakDependencyFieldNumber = 11,
+    kMessageTypeFieldNumber = 4,
+    kEnumTypeFieldNumber = 5,
+    kExtensionFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FileDescriptorProto"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Package =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_Package kPackage{};
+  void set_package(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Package::kFieldId, data, size);
+  }
+  void set_package(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Package::kFieldId, chars.data, chars.size);
+  }
+  void set_package(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Package::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dependency =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_Dependency kDependency{};
+  void add_dependency(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Dependency::kFieldId, data, size);
+  }
+  void add_dependency(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Dependency::kFieldId, chars.data, chars.size);
+  }
+  void add_dependency(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dependency::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PublicDependency =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_PublicDependency kPublicDependency{};
+  void add_public_dependency(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PublicDependency::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WeakDependency =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_WeakDependency kWeakDependency{};
+  void add_weak_dependency(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WeakDependency::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MessageType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DescriptorProto,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_MessageType kMessageType{};
+  template <typename T = DescriptorProto> T* add_message_type() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_EnumType =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EnumDescriptorProto,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_EnumType kEnumType{};
+  template <typename T = EnumDescriptorProto> T* add_enum_type() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Extension =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FieldDescriptorProto,
+      FileDescriptorProto>;
+
+  static constexpr FieldMetadata_Extension kExtension{};
+  template <typename T = FieldDescriptorProto> T* add_extension() {
+    return BeginNestedMessage<T>(7);
+  }
+
+};
+
+class FileDescriptorSet_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FileDescriptorSet_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FileDescriptorSet_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FileDescriptorSet_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_file() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> file() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class FileDescriptorSet : public ::protozero::Message {
+ public:
+  using Decoder = FileDescriptorSet_Decoder;
+  enum : int32_t {
+    kFileFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FileDescriptorSet"; }
+
+
+  using FieldMetadata_File =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FileDescriptorProto,
+      FileDescriptorSet>;
+
+  static constexpr FieldMetadata_File kFile{};
+  template <typename T = FileDescriptorProto> T* add_file() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/ftrace_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_FTRACE_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_FTRACE_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FtraceDescriptor_AtraceCategory;
+
+class FtraceDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_atrace_categories() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> atrace_categories() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class FtraceDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = FtraceDescriptor_Decoder;
+  enum : int32_t {
+    kAtraceCategoriesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceDescriptor"; }
+
+  using AtraceCategory = ::perfetto::protos::pbzero::FtraceDescriptor_AtraceCategory;
+
+  using FieldMetadata_AtraceCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceDescriptor_AtraceCategory,
+      FtraceDescriptor>;
+
+  static constexpr FieldMetadata_AtraceCategories kAtraceCategories{};
+  template <typename T = FtraceDescriptor_AtraceCategory> T* add_atrace_categories() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class FtraceDescriptor_AtraceCategory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceDescriptor_AtraceCategory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceDescriptor_AtraceCategory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceDescriptor_AtraceCategory_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_description() const { return at<2>().valid(); }
+  ::protozero::ConstChars description() const { return at<2>().as_string(); }
+};
+
+class FtraceDescriptor_AtraceCategory : public ::protozero::Message {
+ public:
+  using Decoder = FtraceDescriptor_AtraceCategory_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kDescriptionFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceDescriptor.AtraceCategory"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceDescriptor_AtraceCategory>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceDescriptor_AtraceCategory>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/gpu_counter_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GpuCounterDescriptor_GpuCounterBlock;
+class GpuCounterDescriptor_GpuCounterSpec;
+namespace perfetto_pbzero_enum_GpuCounterDescriptor {
+enum GpuCounterGroup : int32_t;
+}  // namespace perfetto_pbzero_enum_GpuCounterDescriptor
+using GpuCounterDescriptor_GpuCounterGroup = perfetto_pbzero_enum_GpuCounterDescriptor::GpuCounterGroup;
+namespace perfetto_pbzero_enum_GpuCounterDescriptor {
+enum MeasureUnit : int32_t;
+}  // namespace perfetto_pbzero_enum_GpuCounterDescriptor
+using GpuCounterDescriptor_MeasureUnit = perfetto_pbzero_enum_GpuCounterDescriptor::MeasureUnit;
+
+namespace perfetto_pbzero_enum_GpuCounterDescriptor {
+enum GpuCounterGroup : int32_t {
+  UNCLASSIFIED = 0,
+  SYSTEM = 1,
+  VERTICES = 2,
+  FRAGMENTS = 3,
+  PRIMITIVES = 4,
+  MEMORY = 5,
+  COMPUTE = 6,
+};
+} // namespace perfetto_pbzero_enum_GpuCounterDescriptor
+using GpuCounterDescriptor_GpuCounterGroup = perfetto_pbzero_enum_GpuCounterDescriptor::GpuCounterGroup;
+
+
+constexpr GpuCounterDescriptor_GpuCounterGroup GpuCounterDescriptor_GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup::UNCLASSIFIED;
+constexpr GpuCounterDescriptor_GpuCounterGroup GpuCounterDescriptor_GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup::COMPUTE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* GpuCounterDescriptor_GpuCounterGroup_Name(::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::UNCLASSIFIED:
+    return "UNCLASSIFIED";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::SYSTEM:
+    return "SYSTEM";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::VERTICES:
+    return "VERTICES";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::FRAGMENTS:
+    return "FRAGMENTS";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::PRIMITIVES:
+    return "PRIMITIVES";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::MEMORY:
+    return "MEMORY";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup::COMPUTE:
+    return "COMPUTE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_GpuCounterDescriptor {
+enum MeasureUnit : int32_t {
+  NONE = 0,
+  BIT = 1,
+  KILOBIT = 2,
+  MEGABIT = 3,
+  GIGABIT = 4,
+  TERABIT = 5,
+  PETABIT = 6,
+  BYTE = 7,
+  KILOBYTE = 8,
+  MEGABYTE = 9,
+  GIGABYTE = 10,
+  TERABYTE = 11,
+  PETABYTE = 12,
+  HERTZ = 13,
+  KILOHERTZ = 14,
+  MEGAHERTZ = 15,
+  GIGAHERTZ = 16,
+  TERAHERTZ = 17,
+  PETAHERTZ = 18,
+  NANOSECOND = 19,
+  MICROSECOND = 20,
+  MILLISECOND = 21,
+  SECOND = 22,
+  MINUTE = 23,
+  HOUR = 24,
+  VERTEX = 25,
+  PIXEL = 26,
+  TRIANGLE = 27,
+  PRIMITIVE = 38,
+  FRAGMENT = 39,
+  MILLIWATT = 28,
+  WATT = 29,
+  KILOWATT = 30,
+  JOULE = 31,
+  VOLT = 32,
+  AMPERE = 33,
+  CELSIUS = 34,
+  FAHRENHEIT = 35,
+  KELVIN = 36,
+  PERCENT = 37,
+  INSTRUCTION = 40,
+};
+} // namespace perfetto_pbzero_enum_GpuCounterDescriptor
+using GpuCounterDescriptor_MeasureUnit = perfetto_pbzero_enum_GpuCounterDescriptor::MeasureUnit;
+
+
+constexpr GpuCounterDescriptor_MeasureUnit GpuCounterDescriptor_MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit::NONE;
+constexpr GpuCounterDescriptor_MeasureUnit GpuCounterDescriptor_MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit::INSTRUCTION;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* GpuCounterDescriptor_MeasureUnit_Name(::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::NONE:
+    return "NONE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::BIT:
+    return "BIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::KILOBIT:
+    return "KILOBIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MEGABIT:
+    return "MEGABIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::GIGABIT:
+    return "GIGABIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::TERABIT:
+    return "TERABIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PETABIT:
+    return "PETABIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::BYTE:
+    return "BYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::KILOBYTE:
+    return "KILOBYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MEGABYTE:
+    return "MEGABYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::GIGABYTE:
+    return "GIGABYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::TERABYTE:
+    return "TERABYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PETABYTE:
+    return "PETABYTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::HERTZ:
+    return "HERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::KILOHERTZ:
+    return "KILOHERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MEGAHERTZ:
+    return "MEGAHERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::GIGAHERTZ:
+    return "GIGAHERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::TERAHERTZ:
+    return "TERAHERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PETAHERTZ:
+    return "PETAHERTZ";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::NANOSECOND:
+    return "NANOSECOND";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MICROSECOND:
+    return "MICROSECOND";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MILLISECOND:
+    return "MILLISECOND";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::SECOND:
+    return "SECOND";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MINUTE:
+    return "MINUTE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::HOUR:
+    return "HOUR";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::VERTEX:
+    return "VERTEX";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PIXEL:
+    return "PIXEL";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::TRIANGLE:
+    return "TRIANGLE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PRIMITIVE:
+    return "PRIMITIVE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::FRAGMENT:
+    return "FRAGMENT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::MILLIWATT:
+    return "MILLIWATT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::WATT:
+    return "WATT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::KILOWATT:
+    return "KILOWATT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::JOULE:
+    return "JOULE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::VOLT:
+    return "VOLT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::AMPERE:
+    return "AMPERE";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::CELSIUS:
+    return "CELSIUS";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::FAHRENHEIT:
+    return "FAHRENHEIT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::KELVIN:
+    return "KELVIN";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::PERCENT:
+    return "PERCENT";
+
+  case ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit::INSTRUCTION:
+    return "INSTRUCTION";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class GpuCounterDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuCounterDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_specs() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> specs() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_blocks() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> blocks() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_min_sampling_period_ns() const { return at<3>().valid(); }
+  uint64_t min_sampling_period_ns() const { return at<3>().as_uint64(); }
+  bool has_max_sampling_period_ns() const { return at<4>().valid(); }
+  uint64_t max_sampling_period_ns() const { return at<4>().as_uint64(); }
+  bool has_supports_instrumented_sampling() const { return at<5>().valid(); }
+  bool supports_instrumented_sampling() const { return at<5>().as_bool(); }
+};
+
+class GpuCounterDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterDescriptor_Decoder;
+  enum : int32_t {
+    kSpecsFieldNumber = 1,
+    kBlocksFieldNumber = 2,
+    kMinSamplingPeriodNsFieldNumber = 3,
+    kMaxSamplingPeriodNsFieldNumber = 4,
+    kSupportsInstrumentedSamplingFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterDescriptor"; }
+
+  using GpuCounterSpec = ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterSpec;
+  using GpuCounterBlock = ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterBlock;
+
+  using GpuCounterGroup = ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup;
+  static inline const char* GpuCounterGroup_Name(GpuCounterGroup value) {
+    return ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup_Name(value);
+  }
+
+  using MeasureUnit = ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit;
+  static inline const char* MeasureUnit_Name(MeasureUnit value) {
+    return ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit_Name(value);
+  }
+  static inline const GpuCounterGroup UNCLASSIFIED = GpuCounterGroup::UNCLASSIFIED;
+  static inline const GpuCounterGroup SYSTEM = GpuCounterGroup::SYSTEM;
+  static inline const GpuCounterGroup VERTICES = GpuCounterGroup::VERTICES;
+  static inline const GpuCounterGroup FRAGMENTS = GpuCounterGroup::FRAGMENTS;
+  static inline const GpuCounterGroup PRIMITIVES = GpuCounterGroup::PRIMITIVES;
+  static inline const GpuCounterGroup MEMORY = GpuCounterGroup::MEMORY;
+  static inline const GpuCounterGroup COMPUTE = GpuCounterGroup::COMPUTE;
+  static inline const MeasureUnit NONE = MeasureUnit::NONE;
+  static inline const MeasureUnit BIT = MeasureUnit::BIT;
+  static inline const MeasureUnit KILOBIT = MeasureUnit::KILOBIT;
+  static inline const MeasureUnit MEGABIT = MeasureUnit::MEGABIT;
+  static inline const MeasureUnit GIGABIT = MeasureUnit::GIGABIT;
+  static inline const MeasureUnit TERABIT = MeasureUnit::TERABIT;
+  static inline const MeasureUnit PETABIT = MeasureUnit::PETABIT;
+  static inline const MeasureUnit BYTE = MeasureUnit::BYTE;
+  static inline const MeasureUnit KILOBYTE = MeasureUnit::KILOBYTE;
+  static inline const MeasureUnit MEGABYTE = MeasureUnit::MEGABYTE;
+  static inline const MeasureUnit GIGABYTE = MeasureUnit::GIGABYTE;
+  static inline const MeasureUnit TERABYTE = MeasureUnit::TERABYTE;
+  static inline const MeasureUnit PETABYTE = MeasureUnit::PETABYTE;
+  static inline const MeasureUnit HERTZ = MeasureUnit::HERTZ;
+  static inline const MeasureUnit KILOHERTZ = MeasureUnit::KILOHERTZ;
+  static inline const MeasureUnit MEGAHERTZ = MeasureUnit::MEGAHERTZ;
+  static inline const MeasureUnit GIGAHERTZ = MeasureUnit::GIGAHERTZ;
+  static inline const MeasureUnit TERAHERTZ = MeasureUnit::TERAHERTZ;
+  static inline const MeasureUnit PETAHERTZ = MeasureUnit::PETAHERTZ;
+  static inline const MeasureUnit NANOSECOND = MeasureUnit::NANOSECOND;
+  static inline const MeasureUnit MICROSECOND = MeasureUnit::MICROSECOND;
+  static inline const MeasureUnit MILLISECOND = MeasureUnit::MILLISECOND;
+  static inline const MeasureUnit SECOND = MeasureUnit::SECOND;
+  static inline const MeasureUnit MINUTE = MeasureUnit::MINUTE;
+  static inline const MeasureUnit HOUR = MeasureUnit::HOUR;
+  static inline const MeasureUnit VERTEX = MeasureUnit::VERTEX;
+  static inline const MeasureUnit PIXEL = MeasureUnit::PIXEL;
+  static inline const MeasureUnit TRIANGLE = MeasureUnit::TRIANGLE;
+  static inline const MeasureUnit PRIMITIVE = MeasureUnit::PRIMITIVE;
+  static inline const MeasureUnit FRAGMENT = MeasureUnit::FRAGMENT;
+  static inline const MeasureUnit MILLIWATT = MeasureUnit::MILLIWATT;
+  static inline const MeasureUnit WATT = MeasureUnit::WATT;
+  static inline const MeasureUnit KILOWATT = MeasureUnit::KILOWATT;
+  static inline const MeasureUnit JOULE = MeasureUnit::JOULE;
+  static inline const MeasureUnit VOLT = MeasureUnit::VOLT;
+  static inline const MeasureUnit AMPERE = MeasureUnit::AMPERE;
+  static inline const MeasureUnit CELSIUS = MeasureUnit::CELSIUS;
+  static inline const MeasureUnit FAHRENHEIT = MeasureUnit::FAHRENHEIT;
+  static inline const MeasureUnit KELVIN = MeasureUnit::KELVIN;
+  static inline const MeasureUnit PERCENT = MeasureUnit::PERCENT;
+  static inline const MeasureUnit INSTRUCTION = MeasureUnit::INSTRUCTION;
+
+  using FieldMetadata_Specs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterDescriptor_GpuCounterSpec,
+      GpuCounterDescriptor>;
+
+  static constexpr FieldMetadata_Specs kSpecs{};
+  template <typename T = GpuCounterDescriptor_GpuCounterSpec> T* add_specs() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterDescriptor_GpuCounterBlock,
+      GpuCounterDescriptor>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  template <typename T = GpuCounterDescriptor_GpuCounterBlock> T* add_blocks() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_MinSamplingPeriodNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuCounterDescriptor>;
+
+  static constexpr FieldMetadata_MinSamplingPeriodNs kMinSamplingPeriodNs{};
+  void set_min_sampling_period_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinSamplingPeriodNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxSamplingPeriodNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuCounterDescriptor>;
+
+  static constexpr FieldMetadata_MaxSamplingPeriodNs kMaxSamplingPeriodNs{};
+  void set_max_sampling_period_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxSamplingPeriodNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SupportsInstrumentedSampling =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      GpuCounterDescriptor>;
+
+  static constexpr FieldMetadata_SupportsInstrumentedSampling kSupportsInstrumentedSampling{};
+  void set_supports_instrumented_sampling(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SupportsInstrumentedSampling::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class GpuCounterDescriptor_GpuCounterBlock_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuCounterDescriptor_GpuCounterBlock_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterDescriptor_GpuCounterBlock_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterDescriptor_GpuCounterBlock_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_block_id() const { return at<1>().valid(); }
+  uint32_t block_id() const { return at<1>().as_uint32(); }
+  bool has_block_capacity() const { return at<2>().valid(); }
+  uint32_t block_capacity() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+  bool has_description() const { return at<4>().valid(); }
+  ::protozero::ConstChars description() const { return at<4>().as_string(); }
+  bool has_counter_ids() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> counter_ids() const { return GetRepeated<uint32_t>(5); }
+};
+
+class GpuCounterDescriptor_GpuCounterBlock : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterDescriptor_GpuCounterBlock_Decoder;
+  enum : int32_t {
+    kBlockIdFieldNumber = 1,
+    kBlockCapacityFieldNumber = 2,
+    kNameFieldNumber = 3,
+    kDescriptionFieldNumber = 4,
+    kCounterIdsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterDescriptor.GpuCounterBlock"; }
+
+
+  using FieldMetadata_BlockId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  static constexpr FieldMetadata_BlockId kBlockId{};
+  void set_block_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BlockCapacity =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  static constexpr FieldMetadata_BlockCapacity kBlockCapacity{};
+  void set_block_capacity(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockCapacity::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CounterIds =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterDescriptor_GpuCounterBlock>;
+
+  static constexpr FieldMetadata_CounterIds kCounterIds{};
+  void add_counter_ids(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class GpuCounterDescriptor_GpuCounterSpec_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuCounterDescriptor_GpuCounterSpec_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterDescriptor_GpuCounterSpec_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterDescriptor_GpuCounterSpec_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_counter_id() const { return at<1>().valid(); }
+  uint32_t counter_id() const { return at<1>().as_uint32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_description() const { return at<3>().valid(); }
+  ::protozero::ConstChars description() const { return at<3>().as_string(); }
+  bool has_int_peak_value() const { return at<5>().valid(); }
+  int64_t int_peak_value() const { return at<5>().as_int64(); }
+  bool has_double_peak_value() const { return at<6>().valid(); }
+  double double_peak_value() const { return at<6>().as_double(); }
+  bool has_numerator_units() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> numerator_units() const { return GetRepeated<int32_t>(7); }
+  bool has_denominator_units() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> denominator_units() const { return GetRepeated<int32_t>(8); }
+  bool has_select_by_default() const { return at<9>().valid(); }
+  bool select_by_default() const { return at<9>().as_bool(); }
+  bool has_groups() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> groups() const { return GetRepeated<int32_t>(10); }
+};
+
+class GpuCounterDescriptor_GpuCounterSpec : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterDescriptor_GpuCounterSpec_Decoder;
+  enum : int32_t {
+    kCounterIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kDescriptionFieldNumber = 3,
+    kIntPeakValueFieldNumber = 5,
+    kDoublePeakValueFieldNumber = 6,
+    kNumeratorUnitsFieldNumber = 7,
+    kDenominatorUnitsFieldNumber = 8,
+    kSelectByDefaultFieldNumber = 9,
+    kGroupsFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterDescriptor.GpuCounterSpec"; }
+
+
+  using FieldMetadata_CounterId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_CounterId kCounterId{};
+  void set_counter_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntPeakValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_IntPeakValue kIntPeakValue{};
+  void set_int_peak_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntPeakValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoublePeakValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_DoublePeakValue kDoublePeakValue{};
+  void set_double_peak_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoublePeakValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumeratorUnits =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_NumeratorUnits kNumeratorUnits{};
+  void add_numerator_units(::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumeratorUnits::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DenominatorUnits =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_DenominatorUnits kDenominatorUnits{};
+  void add_denominator_units(::perfetto::protos::pbzero::GpuCounterDescriptor_MeasureUnit value) {
+    static constexpr uint32_t field_id = FieldMetadata_DenominatorUnits::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SelectByDefault =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_SelectByDefault kSelectByDefault{};
+  void set_select_by_default(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelectByDefault::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Groups =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup,
+      GpuCounterDescriptor_GpuCounterSpec>;
+
+  static constexpr FieldMetadata_Groups kGroups{};
+  void add_groups(::perfetto::protos::pbzero::GpuCounterDescriptor_GpuCounterGroup value) {
+    static constexpr uint32_t field_id = FieldMetadata_Groups::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/interceptor_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class InterceptorDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InterceptorDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InterceptorDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InterceptorDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+};
+
+class InterceptorDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = InterceptorDescriptor_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InterceptorDescriptor"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InterceptorDescriptor>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/observable_events.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ObservableEvents_CloneTriggerHit;
+class ObservableEvents_DataSourceInstanceStateChange;
+namespace perfetto_pbzero_enum_ObservableEvents {
+enum DataSourceInstanceState : int32_t;
+}  // namespace perfetto_pbzero_enum_ObservableEvents
+using ObservableEvents_DataSourceInstanceState = perfetto_pbzero_enum_ObservableEvents::DataSourceInstanceState;
+
+namespace perfetto_pbzero_enum_ObservableEvents {
+enum Type : int32_t {
+  TYPE_UNSPECIFIED = 0,
+  TYPE_DATA_SOURCES_INSTANCES = 1,
+  TYPE_ALL_DATA_SOURCES_STARTED = 2,
+  TYPE_CLONE_TRIGGER_HIT = 4,
+};
+} // namespace perfetto_pbzero_enum_ObservableEvents
+using ObservableEvents_Type = perfetto_pbzero_enum_ObservableEvents::Type;
+
+
+constexpr ObservableEvents_Type ObservableEvents_Type_MIN = ObservableEvents_Type::TYPE_UNSPECIFIED;
+constexpr ObservableEvents_Type ObservableEvents_Type_MAX = ObservableEvents_Type::TYPE_CLONE_TRIGGER_HIT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ObservableEvents_Type_Name(::perfetto::protos::pbzero::ObservableEvents_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ObservableEvents_Type::TYPE_UNSPECIFIED:
+    return "TYPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ObservableEvents_Type::TYPE_DATA_SOURCES_INSTANCES:
+    return "TYPE_DATA_SOURCES_INSTANCES";
+
+  case ::perfetto::protos::pbzero::ObservableEvents_Type::TYPE_ALL_DATA_SOURCES_STARTED:
+    return "TYPE_ALL_DATA_SOURCES_STARTED";
+
+  case ::perfetto::protos::pbzero::ObservableEvents_Type::TYPE_CLONE_TRIGGER_HIT:
+    return "TYPE_CLONE_TRIGGER_HIT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ObservableEvents {
+enum DataSourceInstanceState : int32_t {
+  DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
+  DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
+};
+} // namespace perfetto_pbzero_enum_ObservableEvents
+using ObservableEvents_DataSourceInstanceState = perfetto_pbzero_enum_ObservableEvents::DataSourceInstanceState;
+
+
+constexpr ObservableEvents_DataSourceInstanceState ObservableEvents_DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STOPPED;
+constexpr ObservableEvents_DataSourceInstanceState ObservableEvents_DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STARTED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ObservableEvents_DataSourceInstanceState_Name(::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STOPPED:
+    return "DATA_SOURCE_INSTANCE_STATE_STOPPED";
+
+  case ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STARTED:
+    return "DATA_SOURCE_INSTANCE_STATE_STARTED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ObservableEvents_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ObservableEvents_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ObservableEvents_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ObservableEvents_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_instance_state_changes() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> instance_state_changes() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_all_data_sources_started() const { return at<2>().valid(); }
+  bool all_data_sources_started() const { return at<2>().as_bool(); }
+  bool has_clone_trigger_hit() const { return at<3>().valid(); }
+  ::protozero::ConstBytes clone_trigger_hit() const { return at<3>().as_bytes(); }
+};
+
+class ObservableEvents : public ::protozero::Message {
+ public:
+  using Decoder = ObservableEvents_Decoder;
+  enum : int32_t {
+    kInstanceStateChangesFieldNumber = 1,
+    kAllDataSourcesStartedFieldNumber = 2,
+    kCloneTriggerHitFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ObservableEvents"; }
+
+  using DataSourceInstanceStateChange = ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceStateChange;
+  using CloneTriggerHit = ::perfetto::protos::pbzero::ObservableEvents_CloneTriggerHit;
+
+  using Type = ::perfetto::protos::pbzero::ObservableEvents_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::ObservableEvents_Type_Name(value);
+  }
+
+  using DataSourceInstanceState = ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState;
+  static inline const char* DataSourceInstanceState_Name(DataSourceInstanceState value) {
+    return ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState_Name(value);
+  }
+  static inline const Type TYPE_UNSPECIFIED = Type::TYPE_UNSPECIFIED;
+  static inline const Type TYPE_DATA_SOURCES_INSTANCES = Type::TYPE_DATA_SOURCES_INSTANCES;
+  static inline const Type TYPE_ALL_DATA_SOURCES_STARTED = Type::TYPE_ALL_DATA_SOURCES_STARTED;
+  static inline const Type TYPE_CLONE_TRIGGER_HIT = Type::TYPE_CLONE_TRIGGER_HIT;
+  static inline const DataSourceInstanceState DATA_SOURCE_INSTANCE_STATE_STOPPED = DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STOPPED;
+  static inline const DataSourceInstanceState DATA_SOURCE_INSTANCE_STATE_STARTED = DataSourceInstanceState::DATA_SOURCE_INSTANCE_STATE_STARTED;
+
+  using FieldMetadata_InstanceStateChanges =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ObservableEvents_DataSourceInstanceStateChange,
+      ObservableEvents>;
+
+  static constexpr FieldMetadata_InstanceStateChanges kInstanceStateChanges{};
+  template <typename T = ObservableEvents_DataSourceInstanceStateChange> T* add_instance_state_changes() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_AllDataSourcesStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ObservableEvents>;
+
+  static constexpr FieldMetadata_AllDataSourcesStarted kAllDataSourcesStarted{};
+  void set_all_data_sources_started(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllDataSourcesStarted::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CloneTriggerHit =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ObservableEvents_CloneTriggerHit,
+      ObservableEvents>;
+
+  static constexpr FieldMetadata_CloneTriggerHit kCloneTriggerHit{};
+  template <typename T = ObservableEvents_CloneTriggerHit> T* set_clone_trigger_hit() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class ObservableEvents_CloneTriggerHit_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ObservableEvents_CloneTriggerHit_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ObservableEvents_CloneTriggerHit_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ObservableEvents_CloneTriggerHit_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tracing_session_id() const { return at<1>().valid(); }
+  int64_t tracing_session_id() const { return at<1>().as_int64(); }
+};
+
+class ObservableEvents_CloneTriggerHit : public ::protozero::Message {
+ public:
+  using Decoder = ObservableEvents_CloneTriggerHit_Decoder;
+  enum : int32_t {
+    kTracingSessionIdFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ObservableEvents.CloneTriggerHit"; }
+
+
+  using FieldMetadata_TracingSessionId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ObservableEvents_CloneTriggerHit>;
+
+  static constexpr FieldMetadata_TracingSessionId kTracingSessionId{};
+  void set_tracing_session_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingSessionId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ObservableEvents_DataSourceInstanceStateChange_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ObservableEvents_DataSourceInstanceStateChange_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ObservableEvents_DataSourceInstanceStateChange_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ObservableEvents_DataSourceInstanceStateChange_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_producer_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars producer_name() const { return at<1>().as_string(); }
+  bool has_data_source_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars data_source_name() const { return at<2>().as_string(); }
+  bool has_state() const { return at<3>().valid(); }
+  int32_t state() const { return at<3>().as_int32(); }
+};
+
+class ObservableEvents_DataSourceInstanceStateChange : public ::protozero::Message {
+ public:
+  using Decoder = ObservableEvents_DataSourceInstanceStateChange_Decoder;
+  enum : int32_t {
+    kProducerNameFieldNumber = 1,
+    kDataSourceNameFieldNumber = 2,
+    kStateFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ObservableEvents.DataSourceInstanceStateChange"; }
+
+
+  using FieldMetadata_ProducerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObservableEvents_DataSourceInstanceStateChange>;
+
+  static constexpr FieldMetadata_ProducerName kProducerName{};
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
+  }
+  void set_producer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, chars.data, chars.size);
+  }
+  void set_producer_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducerName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataSourceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObservableEvents_DataSourceInstanceStateChange>;
+
+  static constexpr FieldMetadata_DataSourceName kDataSourceName{};
+  void set_data_source_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DataSourceName::kFieldId, data, size);
+  }
+  void set_data_source_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DataSourceName::kFieldId, chars.data, chars.size);
+  }
+  void set_data_source_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSourceName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState,
+      ObservableEvents_DataSourceInstanceStateChange>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(::perfetto::protos::pbzero::ObservableEvents_DataSourceInstanceState value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/perf_events.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PerfEvents_RawEvent;
+class PerfEvents_Timebase;
+class PerfEvents_Tracepoint;
+namespace perfetto_pbzero_enum_PerfEvents {
+enum Counter : int32_t;
+}  // namespace perfetto_pbzero_enum_PerfEvents
+using PerfEvents_Counter = perfetto_pbzero_enum_PerfEvents::Counter;
+namespace perfetto_pbzero_enum_PerfEvents {
+enum PerfClock : int32_t;
+}  // namespace perfetto_pbzero_enum_PerfEvents
+using PerfEvents_PerfClock = perfetto_pbzero_enum_PerfEvents::PerfClock;
+
+namespace perfetto_pbzero_enum_PerfEvents {
+enum Counter : int32_t {
+  UNKNOWN_COUNTER = 0,
+  SW_CPU_CLOCK = 1,
+  SW_PAGE_FAULTS = 2,
+  SW_TASK_CLOCK = 3,
+  SW_CONTEXT_SWITCHES = 4,
+  SW_CPU_MIGRATIONS = 5,
+  SW_PAGE_FAULTS_MIN = 6,
+  SW_PAGE_FAULTS_MAJ = 7,
+  SW_ALIGNMENT_FAULTS = 8,
+  SW_EMULATION_FAULTS = 9,
+  SW_DUMMY = 20,
+  HW_CPU_CYCLES = 10,
+  HW_INSTRUCTIONS = 11,
+  HW_CACHE_REFERENCES = 12,
+  HW_CACHE_MISSES = 13,
+  HW_BRANCH_INSTRUCTIONS = 14,
+  HW_BRANCH_MISSES = 15,
+  HW_BUS_CYCLES = 16,
+  HW_STALLED_CYCLES_FRONTEND = 17,
+  HW_STALLED_CYCLES_BACKEND = 18,
+  HW_REF_CPU_CYCLES = 19,
+};
+} // namespace perfetto_pbzero_enum_PerfEvents
+using PerfEvents_Counter = perfetto_pbzero_enum_PerfEvents::Counter;
+
+
+constexpr PerfEvents_Counter PerfEvents_Counter_MIN = PerfEvents_Counter::UNKNOWN_COUNTER;
+constexpr PerfEvents_Counter PerfEvents_Counter_MAX = PerfEvents_Counter::SW_DUMMY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PerfEvents_Counter_Name(::perfetto::protos::pbzero::PerfEvents_Counter value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::UNKNOWN_COUNTER:
+    return "UNKNOWN_COUNTER";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_CPU_CLOCK:
+    return "SW_CPU_CLOCK";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_PAGE_FAULTS:
+    return "SW_PAGE_FAULTS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_TASK_CLOCK:
+    return "SW_TASK_CLOCK";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_CONTEXT_SWITCHES:
+    return "SW_CONTEXT_SWITCHES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_CPU_MIGRATIONS:
+    return "SW_CPU_MIGRATIONS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_PAGE_FAULTS_MIN:
+    return "SW_PAGE_FAULTS_MIN";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_PAGE_FAULTS_MAJ:
+    return "SW_PAGE_FAULTS_MAJ";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_ALIGNMENT_FAULTS:
+    return "SW_ALIGNMENT_FAULTS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_EMULATION_FAULTS:
+    return "SW_EMULATION_FAULTS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::SW_DUMMY:
+    return "SW_DUMMY";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_CPU_CYCLES:
+    return "HW_CPU_CYCLES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_INSTRUCTIONS:
+    return "HW_INSTRUCTIONS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_CACHE_REFERENCES:
+    return "HW_CACHE_REFERENCES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_CACHE_MISSES:
+    return "HW_CACHE_MISSES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_BRANCH_INSTRUCTIONS:
+    return "HW_BRANCH_INSTRUCTIONS";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_BRANCH_MISSES:
+    return "HW_BRANCH_MISSES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_BUS_CYCLES:
+    return "HW_BUS_CYCLES";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_STALLED_CYCLES_FRONTEND:
+    return "HW_STALLED_CYCLES_FRONTEND";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_STALLED_CYCLES_BACKEND:
+    return "HW_STALLED_CYCLES_BACKEND";
+
+  case ::perfetto::protos::pbzero::PerfEvents_Counter::HW_REF_CPU_CYCLES:
+    return "HW_REF_CPU_CYCLES";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_PerfEvents {
+enum PerfClock : int32_t {
+  UNKNOWN_PERF_CLOCK = 0,
+  PERF_CLOCK_REALTIME = 1,
+  PERF_CLOCK_MONOTONIC = 2,
+  PERF_CLOCK_MONOTONIC_RAW = 3,
+  PERF_CLOCK_BOOTTIME = 4,
+};
+} // namespace perfetto_pbzero_enum_PerfEvents
+using PerfEvents_PerfClock = perfetto_pbzero_enum_PerfEvents::PerfClock;
+
+
+constexpr PerfEvents_PerfClock PerfEvents_PerfClock_MIN = PerfEvents_PerfClock::UNKNOWN_PERF_CLOCK;
+constexpr PerfEvents_PerfClock PerfEvents_PerfClock_MAX = PerfEvents_PerfClock::PERF_CLOCK_BOOTTIME;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PerfEvents_PerfClock_Name(::perfetto::protos::pbzero::PerfEvents_PerfClock value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PerfEvents_PerfClock::UNKNOWN_PERF_CLOCK:
+    return "UNKNOWN_PERF_CLOCK";
+
+  case ::perfetto::protos::pbzero::PerfEvents_PerfClock::PERF_CLOCK_REALTIME:
+    return "PERF_CLOCK_REALTIME";
+
+  case ::perfetto::protos::pbzero::PerfEvents_PerfClock::PERF_CLOCK_MONOTONIC:
+    return "PERF_CLOCK_MONOTONIC";
+
+  case ::perfetto::protos::pbzero::PerfEvents_PerfClock::PERF_CLOCK_MONOTONIC_RAW:
+    return "PERF_CLOCK_MONOTONIC_RAW";
+
+  case ::perfetto::protos::pbzero::PerfEvents_PerfClock::PERF_CLOCK_BOOTTIME:
+    return "PERF_CLOCK_BOOTTIME";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class PerfEvents_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfEvents_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEvents_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEvents_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class PerfEvents : public ::protozero::Message {
+ public:
+  using Decoder = PerfEvents_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEvents"; }
+
+  using Timebase = ::perfetto::protos::pbzero::PerfEvents_Timebase;
+  using Tracepoint = ::perfetto::protos::pbzero::PerfEvents_Tracepoint;
+  using RawEvent = ::perfetto::protos::pbzero::PerfEvents_RawEvent;
+
+  using Counter = ::perfetto::protos::pbzero::PerfEvents_Counter;
+  static inline const char* Counter_Name(Counter value) {
+    return ::perfetto::protos::pbzero::PerfEvents_Counter_Name(value);
+  }
+
+  using PerfClock = ::perfetto::protos::pbzero::PerfEvents_PerfClock;
+  static inline const char* PerfClock_Name(PerfClock value) {
+    return ::perfetto::protos::pbzero::PerfEvents_PerfClock_Name(value);
+  }
+  static inline const Counter UNKNOWN_COUNTER = Counter::UNKNOWN_COUNTER;
+  static inline const Counter SW_CPU_CLOCK = Counter::SW_CPU_CLOCK;
+  static inline const Counter SW_PAGE_FAULTS = Counter::SW_PAGE_FAULTS;
+  static inline const Counter SW_TASK_CLOCK = Counter::SW_TASK_CLOCK;
+  static inline const Counter SW_CONTEXT_SWITCHES = Counter::SW_CONTEXT_SWITCHES;
+  static inline const Counter SW_CPU_MIGRATIONS = Counter::SW_CPU_MIGRATIONS;
+  static inline const Counter SW_PAGE_FAULTS_MIN = Counter::SW_PAGE_FAULTS_MIN;
+  static inline const Counter SW_PAGE_FAULTS_MAJ = Counter::SW_PAGE_FAULTS_MAJ;
+  static inline const Counter SW_ALIGNMENT_FAULTS = Counter::SW_ALIGNMENT_FAULTS;
+  static inline const Counter SW_EMULATION_FAULTS = Counter::SW_EMULATION_FAULTS;
+  static inline const Counter SW_DUMMY = Counter::SW_DUMMY;
+  static inline const Counter HW_CPU_CYCLES = Counter::HW_CPU_CYCLES;
+  static inline const Counter HW_INSTRUCTIONS = Counter::HW_INSTRUCTIONS;
+  static inline const Counter HW_CACHE_REFERENCES = Counter::HW_CACHE_REFERENCES;
+  static inline const Counter HW_CACHE_MISSES = Counter::HW_CACHE_MISSES;
+  static inline const Counter HW_BRANCH_INSTRUCTIONS = Counter::HW_BRANCH_INSTRUCTIONS;
+  static inline const Counter HW_BRANCH_MISSES = Counter::HW_BRANCH_MISSES;
+  static inline const Counter HW_BUS_CYCLES = Counter::HW_BUS_CYCLES;
+  static inline const Counter HW_STALLED_CYCLES_FRONTEND = Counter::HW_STALLED_CYCLES_FRONTEND;
+  static inline const Counter HW_STALLED_CYCLES_BACKEND = Counter::HW_STALLED_CYCLES_BACKEND;
+  static inline const Counter HW_REF_CPU_CYCLES = Counter::HW_REF_CPU_CYCLES;
+  static inline const PerfClock UNKNOWN_PERF_CLOCK = PerfClock::UNKNOWN_PERF_CLOCK;
+  static inline const PerfClock PERF_CLOCK_REALTIME = PerfClock::PERF_CLOCK_REALTIME;
+  static inline const PerfClock PERF_CLOCK_MONOTONIC = PerfClock::PERF_CLOCK_MONOTONIC;
+  static inline const PerfClock PERF_CLOCK_MONOTONIC_RAW = PerfClock::PERF_CLOCK_MONOTONIC_RAW;
+  static inline const PerfClock PERF_CLOCK_BOOTTIME = PerfClock::PERF_CLOCK_BOOTTIME;
+};
+
+class PerfEvents_RawEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfEvents_RawEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEvents_RawEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEvents_RawEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  uint32_t type() const { return at<1>().as_uint32(); }
+  bool has_config() const { return at<2>().valid(); }
+  uint64_t config() const { return at<2>().as_uint64(); }
+  bool has_config1() const { return at<3>().valid(); }
+  uint64_t config1() const { return at<3>().as_uint64(); }
+  bool has_config2() const { return at<4>().valid(); }
+  uint64_t config2() const { return at<4>().as_uint64(); }
+};
+
+class PerfEvents_RawEvent : public ::protozero::Message {
+ public:
+  using Decoder = PerfEvents_RawEvent_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kConfigFieldNumber = 2,
+    kConfig1FieldNumber = 3,
+    kConfig2FieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEvents.RawEvent"; }
+
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEvents_RawEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Config =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_RawEvent>;
+
+  static constexpr FieldMetadata_Config kConfig{};
+  void set_config(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Config::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Config1 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_RawEvent>;
+
+  static constexpr FieldMetadata_Config1 kConfig1{};
+  void set_config1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Config1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Config2 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_RawEvent>;
+
+  static constexpr FieldMetadata_Config2 kConfig2{};
+  void set_config2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Config2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PerfEvents_Tracepoint_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfEvents_Tracepoint_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEvents_Tracepoint_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEvents_Tracepoint_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_filter() const { return at<2>().valid(); }
+  ::protozero::ConstChars filter() const { return at<2>().as_string(); }
+};
+
+class PerfEvents_Tracepoint : public ::protozero::Message {
+ public:
+  using Decoder = PerfEvents_Tracepoint_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kFilterFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEvents.Tracepoint"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEvents_Tracepoint>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Filter =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEvents_Tracepoint>;
+
+  static constexpr FieldMetadata_Filter kFilter{};
+  void set_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Filter::kFieldId, data, size);
+  }
+  void set_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Filter::kFieldId, chars.data, chars.size);
+  }
+  void set_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Filter::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PerfEvents_Timebase_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfEvents_Timebase_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEvents_Timebase_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEvents_Timebase_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_frequency() const { return at<2>().valid(); }
+  uint64_t frequency() const { return at<2>().as_uint64(); }
+  bool has_period() const { return at<1>().valid(); }
+  uint64_t period() const { return at<1>().as_uint64(); }
+  bool has_counter() const { return at<4>().valid(); }
+  int32_t counter() const { return at<4>().as_int32(); }
+  bool has_tracepoint() const { return at<3>().valid(); }
+  ::protozero::ConstBytes tracepoint() const { return at<3>().as_bytes(); }
+  bool has_raw_event() const { return at<5>().valid(); }
+  ::protozero::ConstBytes raw_event() const { return at<5>().as_bytes(); }
+  bool has_timestamp_clock() const { return at<11>().valid(); }
+  int32_t timestamp_clock() const { return at<11>().as_int32(); }
+  bool has_name() const { return at<10>().valid(); }
+  ::protozero::ConstChars name() const { return at<10>().as_string(); }
+};
+
+class PerfEvents_Timebase : public ::protozero::Message {
+ public:
+  using Decoder = PerfEvents_Timebase_Decoder;
+  enum : int32_t {
+    kFrequencyFieldNumber = 2,
+    kPeriodFieldNumber = 1,
+    kCounterFieldNumber = 4,
+    kTracepointFieldNumber = 3,
+    kRawEventFieldNumber = 5,
+    kTimestampClockFieldNumber = 11,
+    kNameFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEvents.Timebase"; }
+
+
+  using FieldMetadata_Frequency =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_Frequency kFrequency{};
+  void set_frequency(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Frequency::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Period =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_Period kPeriod{};
+  void set_period(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Period::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Counter =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::PerfEvents_Counter,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_Counter kCounter{};
+  void set_counter(::perfetto::protos::pbzero::PerfEvents_Counter value) {
+    static constexpr uint32_t field_id = FieldMetadata_Counter::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tracepoint =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEvents_Tracepoint,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_Tracepoint kTracepoint{};
+  template <typename T = PerfEvents_Tracepoint> T* set_tracepoint() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_RawEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEvents_RawEvent,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_RawEvent kRawEvent{};
+  template <typename T = PerfEvents_RawEvent> T* set_raw_event() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_TimestampClock =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::PerfEvents_PerfClock,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_TimestampClock kTimestampClock{};
+  void set_timestamp_clock(::perfetto::protos::pbzero::PerfEvents_PerfClock value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampClock::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEvents_Timebase>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/sys_stats_counters.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+enum MeminfoCounters : int32_t {
+  MEMINFO_UNSPECIFIED = 0,
+  MEMINFO_MEM_TOTAL = 1,
+  MEMINFO_MEM_FREE = 2,
+  MEMINFO_MEM_AVAILABLE = 3,
+  MEMINFO_BUFFERS = 4,
+  MEMINFO_CACHED = 5,
+  MEMINFO_SWAP_CACHED = 6,
+  MEMINFO_ACTIVE = 7,
+  MEMINFO_INACTIVE = 8,
+  MEMINFO_ACTIVE_ANON = 9,
+  MEMINFO_INACTIVE_ANON = 10,
+  MEMINFO_ACTIVE_FILE = 11,
+  MEMINFO_INACTIVE_FILE = 12,
+  MEMINFO_UNEVICTABLE = 13,
+  MEMINFO_MLOCKED = 14,
+  MEMINFO_SWAP_TOTAL = 15,
+  MEMINFO_SWAP_FREE = 16,
+  MEMINFO_DIRTY = 17,
+  MEMINFO_WRITEBACK = 18,
+  MEMINFO_ANON_PAGES = 19,
+  MEMINFO_MAPPED = 20,
+  MEMINFO_SHMEM = 21,
+  MEMINFO_SLAB = 22,
+  MEMINFO_SLAB_RECLAIMABLE = 23,
+  MEMINFO_SLAB_UNRECLAIMABLE = 24,
+  MEMINFO_KERNEL_STACK = 25,
+  MEMINFO_PAGE_TABLES = 26,
+  MEMINFO_COMMIT_LIMIT = 27,
+  MEMINFO_COMMITED_AS = 28,
+  MEMINFO_VMALLOC_TOTAL = 29,
+  MEMINFO_VMALLOC_USED = 30,
+  MEMINFO_VMALLOC_CHUNK = 31,
+  MEMINFO_CMA_TOTAL = 32,
+  MEMINFO_CMA_FREE = 33,
+};
+
+constexpr MeminfoCounters MeminfoCounters_MIN = MeminfoCounters::MEMINFO_UNSPECIFIED;
+constexpr MeminfoCounters MeminfoCounters_MAX = MeminfoCounters::MEMINFO_CMA_FREE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* MeminfoCounters_Name(::perfetto::protos::pbzero::MeminfoCounters value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_UNSPECIFIED:
+    return "MEMINFO_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_MEM_TOTAL:
+    return "MEMINFO_MEM_TOTAL";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_MEM_FREE:
+    return "MEMINFO_MEM_FREE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_MEM_AVAILABLE:
+    return "MEMINFO_MEM_AVAILABLE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_BUFFERS:
+    return "MEMINFO_BUFFERS";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_CACHED:
+    return "MEMINFO_CACHED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SWAP_CACHED:
+    return "MEMINFO_SWAP_CACHED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_ACTIVE:
+    return "MEMINFO_ACTIVE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_INACTIVE:
+    return "MEMINFO_INACTIVE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_ACTIVE_ANON:
+    return "MEMINFO_ACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_INACTIVE_ANON:
+    return "MEMINFO_INACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_ACTIVE_FILE:
+    return "MEMINFO_ACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_INACTIVE_FILE:
+    return "MEMINFO_INACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_UNEVICTABLE:
+    return "MEMINFO_UNEVICTABLE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_MLOCKED:
+    return "MEMINFO_MLOCKED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SWAP_TOTAL:
+    return "MEMINFO_SWAP_TOTAL";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SWAP_FREE:
+    return "MEMINFO_SWAP_FREE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_DIRTY:
+    return "MEMINFO_DIRTY";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_WRITEBACK:
+    return "MEMINFO_WRITEBACK";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_ANON_PAGES:
+    return "MEMINFO_ANON_PAGES";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_MAPPED:
+    return "MEMINFO_MAPPED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SHMEM:
+    return "MEMINFO_SHMEM";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SLAB:
+    return "MEMINFO_SLAB";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SLAB_RECLAIMABLE:
+    return "MEMINFO_SLAB_RECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_SLAB_UNRECLAIMABLE:
+    return "MEMINFO_SLAB_UNRECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_KERNEL_STACK:
+    return "MEMINFO_KERNEL_STACK";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_PAGE_TABLES:
+    return "MEMINFO_PAGE_TABLES";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_COMMIT_LIMIT:
+    return "MEMINFO_COMMIT_LIMIT";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_COMMITED_AS:
+    return "MEMINFO_COMMITED_AS";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_VMALLOC_TOTAL:
+    return "MEMINFO_VMALLOC_TOTAL";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_VMALLOC_USED:
+    return "MEMINFO_VMALLOC_USED";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_VMALLOC_CHUNK:
+    return "MEMINFO_VMALLOC_CHUNK";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_CMA_TOTAL:
+    return "MEMINFO_CMA_TOTAL";
+
+  case ::perfetto::protos::pbzero::MeminfoCounters::MEMINFO_CMA_FREE:
+    return "MEMINFO_CMA_FREE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+enum VmstatCounters : int32_t {
+  VMSTAT_UNSPECIFIED = 0,
+  VMSTAT_NR_FREE_PAGES = 1,
+  VMSTAT_NR_ALLOC_BATCH = 2,
+  VMSTAT_NR_INACTIVE_ANON = 3,
+  VMSTAT_NR_ACTIVE_ANON = 4,
+  VMSTAT_NR_INACTIVE_FILE = 5,
+  VMSTAT_NR_ACTIVE_FILE = 6,
+  VMSTAT_NR_UNEVICTABLE = 7,
+  VMSTAT_NR_MLOCK = 8,
+  VMSTAT_NR_ANON_PAGES = 9,
+  VMSTAT_NR_MAPPED = 10,
+  VMSTAT_NR_FILE_PAGES = 11,
+  VMSTAT_NR_DIRTY = 12,
+  VMSTAT_NR_WRITEBACK = 13,
+  VMSTAT_NR_SLAB_RECLAIMABLE = 14,
+  VMSTAT_NR_SLAB_UNRECLAIMABLE = 15,
+  VMSTAT_NR_PAGE_TABLE_PAGES = 16,
+  VMSTAT_NR_KERNEL_STACK = 17,
+  VMSTAT_NR_OVERHEAD = 18,
+  VMSTAT_NR_UNSTABLE = 19,
+  VMSTAT_NR_BOUNCE = 20,
+  VMSTAT_NR_VMSCAN_WRITE = 21,
+  VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22,
+  VMSTAT_NR_WRITEBACK_TEMP = 23,
+  VMSTAT_NR_ISOLATED_ANON = 24,
+  VMSTAT_NR_ISOLATED_FILE = 25,
+  VMSTAT_NR_SHMEM = 26,
+  VMSTAT_NR_DIRTIED = 27,
+  VMSTAT_NR_WRITTEN = 28,
+  VMSTAT_NR_PAGES_SCANNED = 29,
+  VMSTAT_WORKINGSET_REFAULT = 30,
+  VMSTAT_WORKINGSET_ACTIVATE = 31,
+  VMSTAT_WORKINGSET_NODERECLAIM = 32,
+  VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33,
+  VMSTAT_NR_FREE_CMA = 34,
+  VMSTAT_NR_SWAPCACHE = 35,
+  VMSTAT_NR_DIRTY_THRESHOLD = 36,
+  VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37,
+  VMSTAT_PGPGIN = 38,
+  VMSTAT_PGPGOUT = 39,
+  VMSTAT_PGPGOUTCLEAN = 40,
+  VMSTAT_PSWPIN = 41,
+  VMSTAT_PSWPOUT = 42,
+  VMSTAT_PGALLOC_DMA = 43,
+  VMSTAT_PGALLOC_NORMAL = 44,
+  VMSTAT_PGALLOC_MOVABLE = 45,
+  VMSTAT_PGFREE = 46,
+  VMSTAT_PGACTIVATE = 47,
+  VMSTAT_PGDEACTIVATE = 48,
+  VMSTAT_PGFAULT = 49,
+  VMSTAT_PGMAJFAULT = 50,
+  VMSTAT_PGREFILL_DMA = 51,
+  VMSTAT_PGREFILL_NORMAL = 52,
+  VMSTAT_PGREFILL_MOVABLE = 53,
+  VMSTAT_PGSTEAL_KSWAPD_DMA = 54,
+  VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55,
+  VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56,
+  VMSTAT_PGSTEAL_DIRECT_DMA = 57,
+  VMSTAT_PGSTEAL_DIRECT_NORMAL = 58,
+  VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59,
+  VMSTAT_PGSCAN_KSWAPD_DMA = 60,
+  VMSTAT_PGSCAN_KSWAPD_NORMAL = 61,
+  VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62,
+  VMSTAT_PGSCAN_DIRECT_DMA = 63,
+  VMSTAT_PGSCAN_DIRECT_NORMAL = 64,
+  VMSTAT_PGSCAN_DIRECT_MOVABLE = 65,
+  VMSTAT_PGSCAN_DIRECT_THROTTLE = 66,
+  VMSTAT_PGINODESTEAL = 67,
+  VMSTAT_SLABS_SCANNED = 68,
+  VMSTAT_KSWAPD_INODESTEAL = 69,
+  VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70,
+  VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71,
+  VMSTAT_PAGEOUTRUN = 72,
+  VMSTAT_ALLOCSTALL = 73,
+  VMSTAT_PGROTATED = 74,
+  VMSTAT_DROP_PAGECACHE = 75,
+  VMSTAT_DROP_SLAB = 76,
+  VMSTAT_PGMIGRATE_SUCCESS = 77,
+  VMSTAT_PGMIGRATE_FAIL = 78,
+  VMSTAT_COMPACT_MIGRATE_SCANNED = 79,
+  VMSTAT_COMPACT_FREE_SCANNED = 80,
+  VMSTAT_COMPACT_ISOLATED = 81,
+  VMSTAT_COMPACT_STALL = 82,
+  VMSTAT_COMPACT_FAIL = 83,
+  VMSTAT_COMPACT_SUCCESS = 84,
+  VMSTAT_COMPACT_DAEMON_WAKE = 85,
+  VMSTAT_UNEVICTABLE_PGS_CULLED = 86,
+  VMSTAT_UNEVICTABLE_PGS_SCANNED = 87,
+  VMSTAT_UNEVICTABLE_PGS_RESCUED = 88,
+  VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89,
+  VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90,
+  VMSTAT_UNEVICTABLE_PGS_CLEARED = 91,
+  VMSTAT_UNEVICTABLE_PGS_STRANDED = 92,
+  VMSTAT_NR_ZSPAGES = 93,
+  VMSTAT_NR_ION_HEAP = 94,
+  VMSTAT_NR_GPU_HEAP = 95,
+  VMSTAT_ALLOCSTALL_DMA = 96,
+  VMSTAT_ALLOCSTALL_MOVABLE = 97,
+  VMSTAT_ALLOCSTALL_NORMAL = 98,
+  VMSTAT_COMPACT_DAEMON_FREE_SCANNED = 99,
+  VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED = 100,
+  VMSTAT_NR_FASTRPC = 101,
+  VMSTAT_NR_INDIRECTLY_RECLAIMABLE = 102,
+  VMSTAT_NR_ION_HEAP_POOL = 103,
+  VMSTAT_NR_KERNEL_MISC_RECLAIMABLE = 104,
+  VMSTAT_NR_SHADOW_CALL_STACK_BYTES = 105,
+  VMSTAT_NR_SHMEM_HUGEPAGES = 106,
+  VMSTAT_NR_SHMEM_PMDMAPPED = 107,
+  VMSTAT_NR_UNRECLAIMABLE_PAGES = 108,
+  VMSTAT_NR_ZONE_ACTIVE_ANON = 109,
+  VMSTAT_NR_ZONE_ACTIVE_FILE = 110,
+  VMSTAT_NR_ZONE_INACTIVE_ANON = 111,
+  VMSTAT_NR_ZONE_INACTIVE_FILE = 112,
+  VMSTAT_NR_ZONE_UNEVICTABLE = 113,
+  VMSTAT_NR_ZONE_WRITE_PENDING = 114,
+  VMSTAT_OOM_KILL = 115,
+  VMSTAT_PGLAZYFREE = 116,
+  VMSTAT_PGLAZYFREED = 117,
+  VMSTAT_PGREFILL = 118,
+  VMSTAT_PGSCAN_DIRECT = 119,
+  VMSTAT_PGSCAN_KSWAPD = 120,
+  VMSTAT_PGSKIP_DMA = 121,
+  VMSTAT_PGSKIP_MOVABLE = 122,
+  VMSTAT_PGSKIP_NORMAL = 123,
+  VMSTAT_PGSTEAL_DIRECT = 124,
+  VMSTAT_PGSTEAL_KSWAPD = 125,
+  VMSTAT_SWAP_RA = 126,
+  VMSTAT_SWAP_RA_HIT = 127,
+  VMSTAT_WORKINGSET_RESTORE = 128,
+};
+
+constexpr VmstatCounters VmstatCounters_MIN = VmstatCounters::VMSTAT_UNSPECIFIED;
+constexpr VmstatCounters VmstatCounters_MAX = VmstatCounters::VMSTAT_WORKINGSET_RESTORE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* VmstatCounters_Name(::perfetto::protos::pbzero::VmstatCounters value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNSPECIFIED:
+    return "VMSTAT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FREE_PAGES:
+    return "VMSTAT_NR_FREE_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ALLOC_BATCH:
+    return "VMSTAT_NR_ALLOC_BATCH";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_INACTIVE_ANON:
+    return "VMSTAT_NR_INACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ACTIVE_ANON:
+    return "VMSTAT_NR_ACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_INACTIVE_FILE:
+    return "VMSTAT_NR_INACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ACTIVE_FILE:
+    return "VMSTAT_NR_ACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_UNEVICTABLE:
+    return "VMSTAT_NR_UNEVICTABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_MLOCK:
+    return "VMSTAT_NR_MLOCK";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ANON_PAGES:
+    return "VMSTAT_NR_ANON_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_MAPPED:
+    return "VMSTAT_NR_MAPPED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FILE_PAGES:
+    return "VMSTAT_NR_FILE_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTY:
+    return "VMSTAT_NR_DIRTY";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_WRITEBACK:
+    return "VMSTAT_NR_WRITEBACK";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SLAB_RECLAIMABLE:
+    return "VMSTAT_NR_SLAB_RECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SLAB_UNRECLAIMABLE:
+    return "VMSTAT_NR_SLAB_UNRECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_PAGE_TABLE_PAGES:
+    return "VMSTAT_NR_PAGE_TABLE_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_KERNEL_STACK:
+    return "VMSTAT_NR_KERNEL_STACK";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_OVERHEAD:
+    return "VMSTAT_NR_OVERHEAD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_UNSTABLE:
+    return "VMSTAT_NR_UNSTABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_BOUNCE:
+    return "VMSTAT_NR_BOUNCE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_VMSCAN_WRITE:
+    return "VMSTAT_NR_VMSCAN_WRITE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM:
+    return "VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_WRITEBACK_TEMP:
+    return "VMSTAT_NR_WRITEBACK_TEMP";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ISOLATED_ANON:
+    return "VMSTAT_NR_ISOLATED_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ISOLATED_FILE:
+    return "VMSTAT_NR_ISOLATED_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SHMEM:
+    return "VMSTAT_NR_SHMEM";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTIED:
+    return "VMSTAT_NR_DIRTIED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_WRITTEN:
+    return "VMSTAT_NR_WRITTEN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_PAGES_SCANNED:
+    return "VMSTAT_NR_PAGES_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_REFAULT:
+    return "VMSTAT_WORKINGSET_REFAULT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_ACTIVATE:
+    return "VMSTAT_WORKINGSET_ACTIVATE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_NODERECLAIM:
+    return "VMSTAT_WORKINGSET_NODERECLAIM";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES:
+    return "VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FREE_CMA:
+    return "VMSTAT_NR_FREE_CMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SWAPCACHE:
+    return "VMSTAT_NR_SWAPCACHE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTY_THRESHOLD:
+    return "VMSTAT_NR_DIRTY_THRESHOLD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD:
+    return "VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGPGIN:
+    return "VMSTAT_PGPGIN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGPGOUT:
+    return "VMSTAT_PGPGOUT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGPGOUTCLEAN:
+    return "VMSTAT_PGPGOUTCLEAN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PSWPIN:
+    return "VMSTAT_PSWPIN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PSWPOUT:
+    return "VMSTAT_PSWPOUT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_DMA:
+    return "VMSTAT_PGALLOC_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_NORMAL:
+    return "VMSTAT_PGALLOC_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGALLOC_MOVABLE:
+    return "VMSTAT_PGALLOC_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGFREE:
+    return "VMSTAT_PGFREE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGACTIVATE:
+    return "VMSTAT_PGACTIVATE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGDEACTIVATE:
+    return "VMSTAT_PGDEACTIVATE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGFAULT:
+    return "VMSTAT_PGFAULT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGMAJFAULT:
+    return "VMSTAT_PGMAJFAULT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGREFILL_DMA:
+    return "VMSTAT_PGREFILL_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGREFILL_NORMAL:
+    return "VMSTAT_PGREFILL_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGREFILL_MOVABLE:
+    return "VMSTAT_PGREFILL_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD_DMA:
+    return "VMSTAT_PGSTEAL_KSWAPD_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD_NORMAL:
+    return "VMSTAT_PGSTEAL_KSWAPD_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD_MOVABLE:
+    return "VMSTAT_PGSTEAL_KSWAPD_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT_DMA:
+    return "VMSTAT_PGSTEAL_DIRECT_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT_NORMAL:
+    return "VMSTAT_PGSTEAL_DIRECT_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT_MOVABLE:
+    return "VMSTAT_PGSTEAL_DIRECT_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD_DMA:
+    return "VMSTAT_PGSCAN_KSWAPD_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD_NORMAL:
+    return "VMSTAT_PGSCAN_KSWAPD_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD_MOVABLE:
+    return "VMSTAT_PGSCAN_KSWAPD_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_DMA:
+    return "VMSTAT_PGSCAN_DIRECT_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_NORMAL:
+    return "VMSTAT_PGSCAN_DIRECT_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_MOVABLE:
+    return "VMSTAT_PGSCAN_DIRECT_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT_THROTTLE:
+    return "VMSTAT_PGSCAN_DIRECT_THROTTLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGINODESTEAL:
+    return "VMSTAT_PGINODESTEAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_SLABS_SCANNED:
+    return "VMSTAT_SLABS_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_KSWAPD_INODESTEAL:
+    return "VMSTAT_KSWAPD_INODESTEAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY:
+    return "VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY:
+    return "VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PAGEOUTRUN:
+    return "VMSTAT_PAGEOUTRUN";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL:
+    return "VMSTAT_ALLOCSTALL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGROTATED:
+    return "VMSTAT_PGROTATED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_DROP_PAGECACHE:
+    return "VMSTAT_DROP_PAGECACHE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_DROP_SLAB:
+    return "VMSTAT_DROP_SLAB";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGMIGRATE_SUCCESS:
+    return "VMSTAT_PGMIGRATE_SUCCESS";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGMIGRATE_FAIL:
+    return "VMSTAT_PGMIGRATE_FAIL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_MIGRATE_SCANNED:
+    return "VMSTAT_COMPACT_MIGRATE_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_FREE_SCANNED:
+    return "VMSTAT_COMPACT_FREE_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_ISOLATED:
+    return "VMSTAT_COMPACT_ISOLATED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_STALL:
+    return "VMSTAT_COMPACT_STALL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_FAIL:
+    return "VMSTAT_COMPACT_FAIL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_SUCCESS:
+    return "VMSTAT_COMPACT_SUCCESS";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_DAEMON_WAKE:
+    return "VMSTAT_COMPACT_DAEMON_WAKE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_CULLED:
+    return "VMSTAT_UNEVICTABLE_PGS_CULLED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_SCANNED:
+    return "VMSTAT_UNEVICTABLE_PGS_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_RESCUED:
+    return "VMSTAT_UNEVICTABLE_PGS_RESCUED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_MLOCKED:
+    return "VMSTAT_UNEVICTABLE_PGS_MLOCKED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_MUNLOCKED:
+    return "VMSTAT_UNEVICTABLE_PGS_MUNLOCKED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_CLEARED:
+    return "VMSTAT_UNEVICTABLE_PGS_CLEARED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_UNEVICTABLE_PGS_STRANDED:
+    return "VMSTAT_UNEVICTABLE_PGS_STRANDED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZSPAGES:
+    return "VMSTAT_NR_ZSPAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ION_HEAP:
+    return "VMSTAT_NR_ION_HEAP";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_GPU_HEAP:
+    return "VMSTAT_NR_GPU_HEAP";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL_DMA:
+    return "VMSTAT_ALLOCSTALL_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL_MOVABLE:
+    return "VMSTAT_ALLOCSTALL_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_ALLOCSTALL_NORMAL:
+    return "VMSTAT_ALLOCSTALL_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_DAEMON_FREE_SCANNED:
+    return "VMSTAT_COMPACT_DAEMON_FREE_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED:
+    return "VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_FASTRPC:
+    return "VMSTAT_NR_FASTRPC";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_INDIRECTLY_RECLAIMABLE:
+    return "VMSTAT_NR_INDIRECTLY_RECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ION_HEAP_POOL:
+    return "VMSTAT_NR_ION_HEAP_POOL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_KERNEL_MISC_RECLAIMABLE:
+    return "VMSTAT_NR_KERNEL_MISC_RECLAIMABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SHADOW_CALL_STACK_BYTES:
+    return "VMSTAT_NR_SHADOW_CALL_STACK_BYTES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SHMEM_HUGEPAGES:
+    return "VMSTAT_NR_SHMEM_HUGEPAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_SHMEM_PMDMAPPED:
+    return "VMSTAT_NR_SHMEM_PMDMAPPED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_UNRECLAIMABLE_PAGES:
+    return "VMSTAT_NR_UNRECLAIMABLE_PAGES";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_ACTIVE_ANON:
+    return "VMSTAT_NR_ZONE_ACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_ACTIVE_FILE:
+    return "VMSTAT_NR_ZONE_ACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_INACTIVE_ANON:
+    return "VMSTAT_NR_ZONE_INACTIVE_ANON";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_INACTIVE_FILE:
+    return "VMSTAT_NR_ZONE_INACTIVE_FILE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_UNEVICTABLE:
+    return "VMSTAT_NR_ZONE_UNEVICTABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_NR_ZONE_WRITE_PENDING:
+    return "VMSTAT_NR_ZONE_WRITE_PENDING";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_OOM_KILL:
+    return "VMSTAT_OOM_KILL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGLAZYFREE:
+    return "VMSTAT_PGLAZYFREE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGLAZYFREED:
+    return "VMSTAT_PGLAZYFREED";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGREFILL:
+    return "VMSTAT_PGREFILL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_DIRECT:
+    return "VMSTAT_PGSCAN_DIRECT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSCAN_KSWAPD:
+    return "VMSTAT_PGSCAN_KSWAPD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSKIP_DMA:
+    return "VMSTAT_PGSKIP_DMA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSKIP_MOVABLE:
+    return "VMSTAT_PGSKIP_MOVABLE";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSKIP_NORMAL:
+    return "VMSTAT_PGSKIP_NORMAL";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_DIRECT:
+    return "VMSTAT_PGSTEAL_DIRECT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_PGSTEAL_KSWAPD:
+    return "VMSTAT_PGSTEAL_KSWAPD";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_SWAP_RA:
+    return "VMSTAT_SWAP_RA";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_SWAP_RA_HIT:
+    return "VMSTAT_SWAP_RA_HIT";
+
+  case ::perfetto::protos::pbzero::VmstatCounters::VMSTAT_WORKINGSET_RESTORE:
+    return "VMSTAT_WORKINGSET_RESTORE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TraceStats_BufferStats;
+class TraceStats_FilterStats;
+class TraceStats_WriterStats;
+namespace perfetto_pbzero_enum_TraceStats {
+enum FinalFlushOutcome : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceStats
+using TraceStats_FinalFlushOutcome = perfetto_pbzero_enum_TraceStats::FinalFlushOutcome;
+
+namespace perfetto_pbzero_enum_TraceStats {
+enum FinalFlushOutcome : int32_t {
+  FINAL_FLUSH_UNSPECIFIED = 0,
+  FINAL_FLUSH_SUCCEEDED = 1,
+  FINAL_FLUSH_FAILED = 2,
+};
+} // namespace perfetto_pbzero_enum_TraceStats
+using TraceStats_FinalFlushOutcome = perfetto_pbzero_enum_TraceStats::FinalFlushOutcome;
+
+
+constexpr TraceStats_FinalFlushOutcome TraceStats_FinalFlushOutcome_MIN = TraceStats_FinalFlushOutcome::FINAL_FLUSH_UNSPECIFIED;
+constexpr TraceStats_FinalFlushOutcome TraceStats_FinalFlushOutcome_MAX = TraceStats_FinalFlushOutcome::FINAL_FLUSH_FAILED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceStats_FinalFlushOutcome_Name(::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome::FINAL_FLUSH_UNSPECIFIED:
+    return "FINAL_FLUSH_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome::FINAL_FLUSH_SUCCEEDED:
+    return "FINAL_FLUSH_SUCCEEDED";
+
+  case ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome::FINAL_FLUSH_FAILED:
+    return "FINAL_FLUSH_FAILED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class TraceStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/18, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TraceStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffer_stats() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buffer_stats() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_chunk_payload_histogram_def() const { return at<17>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> chunk_payload_histogram_def() const { return GetRepeated<int64_t>(17); }
+  bool has_writer_stats() const { return at<18>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> writer_stats() const { return GetRepeated<::protozero::ConstBytes>(18); }
+  bool has_producers_connected() const { return at<2>().valid(); }
+  uint32_t producers_connected() const { return at<2>().as_uint32(); }
+  bool has_producers_seen() const { return at<3>().valid(); }
+  uint64_t producers_seen() const { return at<3>().as_uint64(); }
+  bool has_data_sources_registered() const { return at<4>().valid(); }
+  uint32_t data_sources_registered() const { return at<4>().as_uint32(); }
+  bool has_data_sources_seen() const { return at<5>().valid(); }
+  uint64_t data_sources_seen() const { return at<5>().as_uint64(); }
+  bool has_tracing_sessions() const { return at<6>().valid(); }
+  uint32_t tracing_sessions() const { return at<6>().as_uint32(); }
+  bool has_total_buffers() const { return at<7>().valid(); }
+  uint32_t total_buffers() const { return at<7>().as_uint32(); }
+  bool has_chunks_discarded() const { return at<8>().valid(); }
+  uint64_t chunks_discarded() const { return at<8>().as_uint64(); }
+  bool has_patches_discarded() const { return at<9>().valid(); }
+  uint64_t patches_discarded() const { return at<9>().as_uint64(); }
+  bool has_invalid_packets() const { return at<10>().valid(); }
+  uint64_t invalid_packets() const { return at<10>().as_uint64(); }
+  bool has_filter_stats() const { return at<11>().valid(); }
+  ::protozero::ConstBytes filter_stats() const { return at<11>().as_bytes(); }
+  bool has_flushes_requested() const { return at<12>().valid(); }
+  uint64_t flushes_requested() const { return at<12>().as_uint64(); }
+  bool has_flushes_succeeded() const { return at<13>().valid(); }
+  uint64_t flushes_succeeded() const { return at<13>().as_uint64(); }
+  bool has_flushes_failed() const { return at<14>().valid(); }
+  uint64_t flushes_failed() const { return at<14>().as_uint64(); }
+  bool has_final_flush_outcome() const { return at<15>().valid(); }
+  int32_t final_flush_outcome() const { return at<15>().as_int32(); }
+};
+
+class TraceStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_Decoder;
+  enum : int32_t {
+    kBufferStatsFieldNumber = 1,
+    kChunkPayloadHistogramDefFieldNumber = 17,
+    kWriterStatsFieldNumber = 18,
+    kProducersConnectedFieldNumber = 2,
+    kProducersSeenFieldNumber = 3,
+    kDataSourcesRegisteredFieldNumber = 4,
+    kDataSourcesSeenFieldNumber = 5,
+    kTracingSessionsFieldNumber = 6,
+    kTotalBuffersFieldNumber = 7,
+    kChunksDiscardedFieldNumber = 8,
+    kPatchesDiscardedFieldNumber = 9,
+    kInvalidPacketsFieldNumber = 10,
+    kFilterStatsFieldNumber = 11,
+    kFlushesRequestedFieldNumber = 12,
+    kFlushesSucceededFieldNumber = 13,
+    kFlushesFailedFieldNumber = 14,
+    kFinalFlushOutcomeFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceStats"; }
+
+  using BufferStats = ::perfetto::protos::pbzero::TraceStats_BufferStats;
+  using WriterStats = ::perfetto::protos::pbzero::TraceStats_WriterStats;
+  using FilterStats = ::perfetto::protos::pbzero::TraceStats_FilterStats;
+
+  using FinalFlushOutcome = ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome;
+  static inline const char* FinalFlushOutcome_Name(FinalFlushOutcome value) {
+    return ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome_Name(value);
+  }
+  static inline const FinalFlushOutcome FINAL_FLUSH_UNSPECIFIED = FinalFlushOutcome::FINAL_FLUSH_UNSPECIFIED;
+  static inline const FinalFlushOutcome FINAL_FLUSH_SUCCEEDED = FinalFlushOutcome::FINAL_FLUSH_SUCCEEDED;
+  static inline const FinalFlushOutcome FINAL_FLUSH_FAILED = FinalFlushOutcome::FINAL_FLUSH_FAILED;
+
+  using FieldMetadata_BufferStats =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceStats_BufferStats,
+      TraceStats>;
+
+  static constexpr FieldMetadata_BufferStats kBufferStats{};
+  template <typename T = TraceStats_BufferStats> T* add_buffer_stats() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ChunkPayloadHistogramDef =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_ChunkPayloadHistogramDef kChunkPayloadHistogramDef{};
+  void add_chunk_payload_histogram_def(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunkPayloadHistogramDef::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WriterStats =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceStats_WriterStats,
+      TraceStats>;
+
+  static constexpr FieldMetadata_WriterStats kWriterStats{};
+  template <typename T = TraceStats_WriterStats> T* add_writer_stats() {
+    return BeginNestedMessage<T>(18);
+  }
+
+
+  using FieldMetadata_ProducersConnected =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_ProducersConnected kProducersConnected{};
+  void set_producers_connected(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducersConnected::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProducersSeen =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_ProducersSeen kProducersSeen{};
+  void set_producers_seen(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducersSeen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataSourcesRegistered =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_DataSourcesRegistered kDataSourcesRegistered{};
+  void set_data_sources_registered(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSourcesRegistered::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataSourcesSeen =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_DataSourcesSeen kDataSourcesSeen{};
+  void set_data_sources_seen(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSourcesSeen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TracingSessions =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_TracingSessions kTracingSessions{};
+  void set_tracing_sessions(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingSessions::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalBuffers =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_TotalBuffers kTotalBuffers{};
+  void set_total_buffers(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalBuffers::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChunksDiscarded =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded{};
+  void set_chunks_discarded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksDiscarded::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PatchesDiscarded =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_PatchesDiscarded kPatchesDiscarded{};
+  void set_patches_discarded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PatchesDiscarded::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InvalidPackets =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_InvalidPackets kInvalidPackets{};
+  void set_invalid_packets(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InvalidPackets::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FilterStats =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceStats_FilterStats,
+      TraceStats>;
+
+  static constexpr FieldMetadata_FilterStats kFilterStats{};
+  template <typename T = TraceStats_FilterStats> T* set_filter_stats() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_FlushesRequested =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_FlushesRequested kFlushesRequested{};
+  void set_flushes_requested(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushesRequested::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FlushesSucceeded =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_FlushesSucceeded kFlushesSucceeded{};
+  void set_flushes_succeeded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushesSucceeded::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FlushesFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats>;
+
+  static constexpr FieldMetadata_FlushesFailed kFlushesFailed{};
+  void set_flushes_failed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushesFailed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FinalFlushOutcome =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome,
+      TraceStats>;
+
+  static constexpr FieldMetadata_FinalFlushOutcome kFinalFlushOutcome{};
+  void set_final_flush_outcome(::perfetto::protos::pbzero::TraceStats_FinalFlushOutcome value) {
+    static constexpr uint32_t field_id = FieldMetadata_FinalFlushOutcome::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceStats_FilterStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/20, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TraceStats_FilterStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceStats_FilterStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceStats_FilterStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_input_packets() const { return at<1>().valid(); }
+  uint64_t input_packets() const { return at<1>().as_uint64(); }
+  bool has_input_bytes() const { return at<2>().valid(); }
+  uint64_t input_bytes() const { return at<2>().as_uint64(); }
+  bool has_output_bytes() const { return at<3>().valid(); }
+  uint64_t output_bytes() const { return at<3>().as_uint64(); }
+  bool has_errors() const { return at<4>().valid(); }
+  uint64_t errors() const { return at<4>().as_uint64(); }
+  bool has_time_taken_ns() const { return at<5>().valid(); }
+  uint64_t time_taken_ns() const { return at<5>().as_uint64(); }
+  bool has_bytes_discarded_per_buffer() const { return at<20>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> bytes_discarded_per_buffer() const { return GetRepeated<uint64_t>(20); }
+};
+
+class TraceStats_FilterStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_FilterStats_Decoder;
+  enum : int32_t {
+    kInputPacketsFieldNumber = 1,
+    kInputBytesFieldNumber = 2,
+    kOutputBytesFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+    kTimeTakenNsFieldNumber = 5,
+    kBytesDiscardedPerBufferFieldNumber = 20,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceStats.FilterStats"; }
+
+
+  using FieldMetadata_InputPackets =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_InputPackets kInputPackets{};
+  void set_input_packets(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputPackets::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InputBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_InputBytes kInputBytes{};
+  void set_input_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OutputBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_OutputBytes kOutputBytes{};
+  void set_output_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OutputBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Errors =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_Errors kErrors{};
+  void set_errors(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Errors::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimeTakenNs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_TimeTakenNs kTimeTakenNs{};
+  void set_time_taken_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimeTakenNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BytesDiscardedPerBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_FilterStats>;
+
+  static constexpr FieldMetadata_BytesDiscardedPerBuffer kBytesDiscardedPerBuffer{};
+  void add_bytes_discarded_per_buffer(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesDiscardedPerBuffer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceStats_WriterStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceStats_WriterStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceStats_WriterStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceStats_WriterStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_sequence_id() const { return at<1>().valid(); }
+  uint64_t sequence_id() const { return at<1>().as_uint64(); }
+  bool has_buffer() const { return at<4>().valid(); }
+  uint32_t buffer() const { return at<4>().as_uint32(); }
+  bool has_chunk_payload_histogram_counts() const { return at<2>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> chunk_payload_histogram_counts(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(2, parse_error_ptr); }
+  bool has_chunk_payload_histogram_sum() const { return at<3>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t> chunk_payload_histogram_sum(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t>(3, parse_error_ptr); }
+};
+
+class TraceStats_WriterStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_WriterStats_Decoder;
+  enum : int32_t {
+    kSequenceIdFieldNumber = 1,
+    kBufferFieldNumber = 4,
+    kChunkPayloadHistogramCountsFieldNumber = 2,
+    kChunkPayloadHistogramSumFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceStats.WriterStats"; }
+
+
+  using FieldMetadata_SequenceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_WriterStats>;
+
+  static constexpr FieldMetadata_SequenceId kSequenceId{};
+  void set_sequence_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SequenceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Buffer =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceStats_WriterStats>;
+
+  static constexpr FieldMetadata_Buffer kBuffer{};
+  void set_buffer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Buffer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChunkPayloadHistogramCounts =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_WriterStats>;
+
+  static constexpr FieldMetadata_ChunkPayloadHistogramCounts kChunkPayloadHistogramCounts{};
+  void set_chunk_payload_histogram_counts(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ChunkPayloadHistogramCounts::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_ChunkPayloadHistogramSum =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceStats_WriterStats>;
+
+  static constexpr FieldMetadata_ChunkPayloadHistogramSum kChunkPayloadHistogramSum{};
+  void set_chunk_payload_histogram_sum(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ChunkPayloadHistogramSum::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+};
+
+class TraceStats_BufferStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceStats_BufferStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceStats_BufferStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceStats_BufferStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffer_size() const { return at<12>().valid(); }
+  uint64_t buffer_size() const { return at<12>().as_uint64(); }
+  bool has_bytes_written() const { return at<1>().valid(); }
+  uint64_t bytes_written() const { return at<1>().as_uint64(); }
+  bool has_bytes_overwritten() const { return at<13>().valid(); }
+  uint64_t bytes_overwritten() const { return at<13>().as_uint64(); }
+  bool has_bytes_read() const { return at<14>().valid(); }
+  uint64_t bytes_read() const { return at<14>().as_uint64(); }
+  bool has_padding_bytes_written() const { return at<15>().valid(); }
+  uint64_t padding_bytes_written() const { return at<15>().as_uint64(); }
+  bool has_padding_bytes_cleared() const { return at<16>().valid(); }
+  uint64_t padding_bytes_cleared() const { return at<16>().as_uint64(); }
+  bool has_chunks_written() const { return at<2>().valid(); }
+  uint64_t chunks_written() const { return at<2>().as_uint64(); }
+  bool has_chunks_rewritten() const { return at<10>().valid(); }
+  uint64_t chunks_rewritten() const { return at<10>().as_uint64(); }
+  bool has_chunks_overwritten() const { return at<3>().valid(); }
+  uint64_t chunks_overwritten() const { return at<3>().as_uint64(); }
+  bool has_chunks_discarded() const { return at<18>().valid(); }
+  uint64_t chunks_discarded() const { return at<18>().as_uint64(); }
+  bool has_chunks_read() const { return at<17>().valid(); }
+  uint64_t chunks_read() const { return at<17>().as_uint64(); }
+  bool has_chunks_committed_out_of_order() const { return at<11>().valid(); }
+  uint64_t chunks_committed_out_of_order() const { return at<11>().as_uint64(); }
+  bool has_write_wrap_count() const { return at<4>().valid(); }
+  uint64_t write_wrap_count() const { return at<4>().as_uint64(); }
+  bool has_patches_succeeded() const { return at<5>().valid(); }
+  uint64_t patches_succeeded() const { return at<5>().as_uint64(); }
+  bool has_patches_failed() const { return at<6>().valid(); }
+  uint64_t patches_failed() const { return at<6>().as_uint64(); }
+  bool has_readaheads_succeeded() const { return at<7>().valid(); }
+  uint64_t readaheads_succeeded() const { return at<7>().as_uint64(); }
+  bool has_readaheads_failed() const { return at<8>().valid(); }
+  uint64_t readaheads_failed() const { return at<8>().as_uint64(); }
+  bool has_abi_violations() const { return at<9>().valid(); }
+  uint64_t abi_violations() const { return at<9>().as_uint64(); }
+  bool has_trace_writer_packet_loss() const { return at<19>().valid(); }
+  uint64_t trace_writer_packet_loss() const { return at<19>().as_uint64(); }
+};
+
+class TraceStats_BufferStats : public ::protozero::Message {
+ public:
+  using Decoder = TraceStats_BufferStats_Decoder;
+  enum : int32_t {
+    kBufferSizeFieldNumber = 12,
+    kBytesWrittenFieldNumber = 1,
+    kBytesOverwrittenFieldNumber = 13,
+    kBytesReadFieldNumber = 14,
+    kPaddingBytesWrittenFieldNumber = 15,
+    kPaddingBytesClearedFieldNumber = 16,
+    kChunksWrittenFieldNumber = 2,
+    kChunksRewrittenFieldNumber = 10,
+    kChunksOverwrittenFieldNumber = 3,
+    kChunksDiscardedFieldNumber = 18,
+    kChunksReadFieldNumber = 17,
+    kChunksCommittedOutOfOrderFieldNumber = 11,
+    kWriteWrapCountFieldNumber = 4,
+    kPatchesSucceededFieldNumber = 5,
+    kPatchesFailedFieldNumber = 6,
+    kReadaheadsSucceededFieldNumber = 7,
+    kReadaheadsFailedFieldNumber = 8,
+    kAbiViolationsFieldNumber = 9,
+    kTraceWriterPacketLossFieldNumber = 19,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceStats.BufferStats"; }
+
+
+  using FieldMetadata_BufferSize =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_BufferSize kBufferSize{};
+  void set_buffer_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BytesWritten =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_BytesWritten kBytesWritten{};
+  void set_bytes_written(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesWritten::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BytesOverwritten =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_BytesOverwritten kBytesOverwritten{};
+  void set_bytes_overwritten(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesOverwritten::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BytesRead =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_BytesRead kBytesRead{};
+  void set_bytes_read(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesRead::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PaddingBytesWritten =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_PaddingBytesWritten kPaddingBytesWritten{};
+  void set_padding_bytes_written(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaddingBytesWritten::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PaddingBytesCleared =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_PaddingBytesCleared kPaddingBytesCleared{};
+  void set_padding_bytes_cleared(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaddingBytesCleared::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChunksWritten =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksWritten kChunksWritten{};
+  void set_chunks_written(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksWritten::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChunksRewritten =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksRewritten kChunksRewritten{};
+  void set_chunks_rewritten(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksRewritten::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChunksOverwritten =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksOverwritten kChunksOverwritten{};
+  void set_chunks_overwritten(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksOverwritten::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChunksDiscarded =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded{};
+  void set_chunks_discarded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksDiscarded::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChunksRead =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksRead kChunksRead{};
+  void set_chunks_read(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksRead::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChunksCommittedOutOfOrder =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ChunksCommittedOutOfOrder kChunksCommittedOutOfOrder{};
+  void set_chunks_committed_out_of_order(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunksCommittedOutOfOrder::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WriteWrapCount =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_WriteWrapCount kWriteWrapCount{};
+  void set_write_wrap_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriteWrapCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PatchesSucceeded =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_PatchesSucceeded kPatchesSucceeded{};
+  void set_patches_succeeded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PatchesSucceeded::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PatchesFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_PatchesFailed kPatchesFailed{};
+  void set_patches_failed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PatchesFailed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReadaheadsSucceeded =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ReadaheadsSucceeded kReadaheadsSucceeded{};
+  void set_readaheads_succeeded(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadaheadsSucceeded::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReadaheadsFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_ReadaheadsFailed kReadaheadsFailed{};
+  void set_readaheads_failed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadaheadsFailed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AbiViolations =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_AbiViolations kAbiViolations{};
+  void set_abi_violations(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AbiViolations::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceWriterPacketLoss =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceStats_BufferStats>;
+
+  static constexpr FieldMetadata_TraceWriterPacketLoss kTraceWriterPacketLoss{};
+  void set_trace_writer_packet_loss(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceWriterPacketLoss::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_capabilities.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ObservableEvents {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_ObservableEvents
+using ObservableEvents_Type = perfetto_pbzero_enum_ObservableEvents::Type;
+
+class TracingServiceCapabilities_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TracingServiceCapabilities_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceCapabilities_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceCapabilities_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_has_query_capabilities() const { return at<1>().valid(); }
+  bool has_query_capabilities() const { return at<1>().as_bool(); }
+  bool has_observable_events() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> observable_events() const { return GetRepeated<int32_t>(2); }
+  bool has_has_trace_config_output_path() const { return at<3>().valid(); }
+  bool has_trace_config_output_path() const { return at<3>().as_bool(); }
+  bool has_has_clone_session() const { return at<4>().valid(); }
+  bool has_clone_session() const { return at<4>().as_bool(); }
+};
+
+class TracingServiceCapabilities : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceCapabilities_Decoder;
+  enum : int32_t {
+    kHasQueryCapabilitiesFieldNumber = 1,
+    kObservableEventsFieldNumber = 2,
+    kHasTraceConfigOutputPathFieldNumber = 3,
+    kHasCloneSessionFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceCapabilities"; }
+
+
+  using FieldMetadata_HasQueryCapabilities =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceCapabilities>;
+
+  static constexpr FieldMetadata_HasQueryCapabilities kHasQueryCapabilities{};
+  void set_has_query_capabilities(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasQueryCapabilities::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ObservableEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ObservableEvents_Type,
+      TracingServiceCapabilities>;
+
+  static constexpr FieldMetadata_ObservableEvents kObservableEvents{};
+  void add_observable_events(::perfetto::protos::pbzero::ObservableEvents_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObservableEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasTraceConfigOutputPath =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceCapabilities>;
+
+  static constexpr FieldMetadata_HasTraceConfigOutputPath kHasTraceConfigOutputPath{};
+  void set_has_trace_config_output_path(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasTraceConfigOutputPath::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasCloneSession =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceCapabilities>;
+
+  static constexpr FieldMetadata_HasCloneSession kHasCloneSession{};
+  void set_has_clone_session(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasCloneSession::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_state.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DataSourceDescriptor;
+class TracingServiceState_DataSource;
+class TracingServiceState_Producer;
+class TracingServiceState_TracingSession;
+
+class TracingServiceState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TracingServiceState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_producers() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> producers() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_data_sources() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> data_sources() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_tracing_sessions() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> tracing_sessions() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_supports_tracing_sessions() const { return at<7>().valid(); }
+  bool supports_tracing_sessions() const { return at<7>().as_bool(); }
+  bool has_num_sessions() const { return at<3>().valid(); }
+  int32_t num_sessions() const { return at<3>().as_int32(); }
+  bool has_num_sessions_started() const { return at<4>().valid(); }
+  int32_t num_sessions_started() const { return at<4>().as_int32(); }
+  bool has_tracing_service_version() const { return at<5>().valid(); }
+  ::protozero::ConstChars tracing_service_version() const { return at<5>().as_string(); }
+};
+
+class TracingServiceState : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceState_Decoder;
+  enum : int32_t {
+    kProducersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    kTracingSessionsFieldNumber = 6,
+    kSupportsTracingSessionsFieldNumber = 7,
+    kNumSessionsFieldNumber = 3,
+    kNumSessionsStartedFieldNumber = 4,
+    kTracingServiceVersionFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceState"; }
+
+  using Producer = ::perfetto::protos::pbzero::TracingServiceState_Producer;
+  using DataSource = ::perfetto::protos::pbzero::TracingServiceState_DataSource;
+  using TracingSession = ::perfetto::protos::pbzero::TracingServiceState_TracingSession;
+
+  using FieldMetadata_Producers =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingServiceState_Producer,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_Producers kProducers{};
+  template <typename T = TracingServiceState_Producer> T* add_producers() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_DataSources =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingServiceState_DataSource,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_DataSources kDataSources{};
+  template <typename T = TracingServiceState_DataSource> T* add_data_sources() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_TracingSessions =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingServiceState_TracingSession,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_TracingSessions kTracingSessions{};
+  template <typename T = TracingServiceState_TracingSession> T* add_tracing_sessions() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_SupportsTracingSessions =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_SupportsTracingSessions kSupportsTracingSessions{};
+  void set_supports_tracing_sessions(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SupportsTracingSessions::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumSessions =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_NumSessions kNumSessions{};
+  void set_num_sessions(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumSessions::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumSessionsStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_NumSessionsStarted kNumSessionsStarted{};
+  void set_num_sessions_started(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumSessionsStarted::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TracingServiceVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState>;
+
+  static constexpr FieldMetadata_TracingServiceVersion kTracingServiceVersion{};
+  void set_tracing_service_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, data, size);
+  }
+  void set_tracing_service_version(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, chars.data, chars.size);
+  }
+  void set_tracing_service_version(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingServiceVersion::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TracingServiceState_TracingSession_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TracingServiceState_TracingSession_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceState_TracingSession_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceState_TracingSession_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_consumer_uid() const { return at<2>().valid(); }
+  int32_t consumer_uid() const { return at<2>().as_int32(); }
+  bool has_state() const { return at<3>().valid(); }
+  ::protozero::ConstChars state() const { return at<3>().as_string(); }
+  bool has_unique_session_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars unique_session_name() const { return at<4>().as_string(); }
+  bool has_buffer_size_kb() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> buffer_size_kb() const { return GetRepeated<uint32_t>(5); }
+  bool has_duration_ms() const { return at<6>().valid(); }
+  uint32_t duration_ms() const { return at<6>().as_uint32(); }
+  bool has_num_data_sources() const { return at<7>().valid(); }
+  uint32_t num_data_sources() const { return at<7>().as_uint32(); }
+  bool has_start_realtime_ns() const { return at<8>().valid(); }
+  int64_t start_realtime_ns() const { return at<8>().as_int64(); }
+};
+
+class TracingServiceState_TracingSession : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceState_TracingSession_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kConsumerUidFieldNumber = 2,
+    kStateFieldNumber = 3,
+    kUniqueSessionNameFieldNumber = 4,
+    kBufferSizeKbFieldNumber = 5,
+    kDurationMsFieldNumber = 6,
+    kNumDataSourcesFieldNumber = 7,
+    kStartRealtimeNsFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceState.TracingSession"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ConsumerUid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_ConsumerUid kConsumerUid{};
+  void set_consumer_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ConsumerUid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_State::kFieldId, data, size);
+  }
+  void set_state(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_State::kFieldId, chars.data, chars.size);
+  }
+  void set_state(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UniqueSessionName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_UniqueSessionName kUniqueSessionName{};
+  void set_unique_session_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, data, size);
+  }
+  void set_unique_session_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, chars.data, chars.size);
+  }
+  void set_unique_session_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_UniqueSessionName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BufferSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_BufferSizeKb kBufferSizeKb{};
+  void add_buffer_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferSizeKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DurationMs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_DurationMs kDurationMs{};
+  void set_duration_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DurationMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumDataSources =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_NumDataSources kNumDataSources{};
+  void set_num_data_sources(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumDataSources::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartRealtimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TracingServiceState_TracingSession>;
+
+  static constexpr FieldMetadata_StartRealtimeNs kStartRealtimeNs{};
+  void set_start_realtime_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartRealtimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TracingServiceState_DataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracingServiceState_DataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceState_DataSource_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceState_DataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ds_descriptor() const { return at<1>().valid(); }
+  ::protozero::ConstBytes ds_descriptor() const { return at<1>().as_bytes(); }
+  bool has_producer_id() const { return at<2>().valid(); }
+  int32_t producer_id() const { return at<2>().as_int32(); }
+};
+
+class TracingServiceState_DataSource : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceState_DataSource_Decoder;
+  enum : int32_t {
+    kDsDescriptorFieldNumber = 1,
+    kProducerIdFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceState.DataSource"; }
+
+
+  using FieldMetadata_DsDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DataSourceDescriptor,
+      TracingServiceState_DataSource>;
+
+  static constexpr FieldMetadata_DsDescriptor kDsDescriptor{};
+  template <typename T = DataSourceDescriptor> T* set_ds_descriptor() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ProducerId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_DataSource>;
+
+  static constexpr FieldMetadata_ProducerId kProducerId{};
+  void set_producer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducerId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TracingServiceState_Producer_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracingServiceState_Producer_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceState_Producer_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceState_Producer_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_pid() const { return at<5>().valid(); }
+  int32_t pid() const { return at<5>().as_int32(); }
+  bool has_uid() const { return at<3>().valid(); }
+  int32_t uid() const { return at<3>().as_int32(); }
+  bool has_sdk_version() const { return at<4>().valid(); }
+  ::protozero::ConstChars sdk_version() const { return at<4>().as_string(); }
+};
+
+class TracingServiceState_Producer : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceState_Producer_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kPidFieldNumber = 5,
+    kUidFieldNumber = 3,
+    kSdkVersionFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceState.Producer"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_Producer>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState_Producer>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_Producer>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingServiceState_Producer>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SdkVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingServiceState_Producer>;
+
+  static constexpr FieldMetadata_SdkVersion kSdkVersion{};
+  void set_sdk_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SdkVersion::kFieldId, data, size);
+  }
+  void set_sdk_version(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SdkVersion::kFieldId, chars.data, chars.size);
+  }
+  void set_sdk_version(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SdkVersion::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/common/track_event_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TrackEventCategory;
+
+class TrackEventDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TrackEventDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEventDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEventDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_available_categories() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> available_categories() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class TrackEventDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventDescriptor_Decoder;
+  enum : int32_t {
+    kAvailableCategoriesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEventDescriptor"; }
+
+
+  using FieldMetadata_AvailableCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventCategory,
+      TrackEventDescriptor>;
+
+  static constexpr FieldMetadata_AvailableCategories kAvailableCategories{};
+  template <typename T = TrackEventCategory> T* add_available_categories() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class TrackEventCategory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TrackEventCategory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEventCategory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEventCategory_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_description() const { return at<2>().valid(); }
+  ::protozero::ConstChars description() const { return at<2>().as_string(); }
+  bool has_tags() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> tags() const { return GetRepeated<::protozero::ConstChars>(3); }
+};
+
+class TrackEventCategory : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventCategory_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kDescriptionFieldNumber = 2,
+    kTagsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEventCategory"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventCategory>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventCategory>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventCategory>;
+
+  static constexpr FieldMetadata_Tags kTags{};
+  void add_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tags::kFieldId, data, size);
+  }
+  void add_tags(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tags::kFieldId, chars.data, chars.size);
+  }
+  void add_tags(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_game_intervention_list_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_GAME_INTERVENTION_LIST_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_GAME_INTERVENTION_LIST_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidGameInterventionListConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidGameInterventionListConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPackageNameFilterFieldNumber = 1,
+  };
+
+  AndroidGameInterventionListConfig();
+  ~AndroidGameInterventionListConfig() override;
+  AndroidGameInterventionListConfig(AndroidGameInterventionListConfig&&) noexcept;
+  AndroidGameInterventionListConfig& operator=(AndroidGameInterventionListConfig&&);
+  AndroidGameInterventionListConfig(const AndroidGameInterventionListConfig&);
+  AndroidGameInterventionListConfig& operator=(const AndroidGameInterventionListConfig&);
+  bool operator==(const AndroidGameInterventionListConfig&) const;
+  bool operator!=(const AndroidGameInterventionListConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& package_name_filter() const { return package_name_filter_; }
+  std::vector<std::string>* mutable_package_name_filter() { return &package_name_filter_; }
+  int package_name_filter_size() const { return static_cast<int>(package_name_filter_.size()); }
+  void clear_package_name_filter() { package_name_filter_.clear(); }
+  void add_package_name_filter(std::string value) { package_name_filter_.emplace_back(value); }
+  std::string* add_package_name_filter() { package_name_filter_.emplace_back(); return &package_name_filter_.back(); }
+
+ private:
+  std::vector<std::string> package_name_filter_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_GAME_INTERVENTION_LIST_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_log_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidLogConfig;
+enum AndroidLogId : int;
+enum AndroidLogPriority : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidLogConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kLogIdsFieldNumber = 1,
+    kMinPrioFieldNumber = 3,
+    kFilterTagsFieldNumber = 4,
+  };
+
+  AndroidLogConfig();
+  ~AndroidLogConfig() override;
+  AndroidLogConfig(AndroidLogConfig&&) noexcept;
+  AndroidLogConfig& operator=(AndroidLogConfig&&);
+  AndroidLogConfig(const AndroidLogConfig&);
+  AndroidLogConfig& operator=(const AndroidLogConfig&);
+  bool operator==(const AndroidLogConfig&) const;
+  bool operator!=(const AndroidLogConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<AndroidLogId>& log_ids() const { return log_ids_; }
+  std::vector<AndroidLogId>* mutable_log_ids() { return &log_ids_; }
+  int log_ids_size() const { return static_cast<int>(log_ids_.size()); }
+  void clear_log_ids() { log_ids_.clear(); }
+  void add_log_ids(AndroidLogId value) { log_ids_.emplace_back(value); }
+  AndroidLogId* add_log_ids() { log_ids_.emplace_back(); return &log_ids_.back(); }
+
+  bool has_min_prio() const { return _has_field_[3]; }
+  AndroidLogPriority min_prio() const { return min_prio_; }
+  void set_min_prio(AndroidLogPriority value) { min_prio_ = value; _has_field_.set(3); }
+
+  const std::vector<std::string>& filter_tags() const { return filter_tags_; }
+  std::vector<std::string>* mutable_filter_tags() { return &filter_tags_; }
+  int filter_tags_size() const { return static_cast<int>(filter_tags_.size()); }
+  void clear_filter_tags() { filter_tags_.clear(); }
+  void add_filter_tags(std::string value) { filter_tags_.emplace_back(value); }
+  std::string* add_filter_tags() { filter_tags_.emplace_back(); return &filter_tags_.back(); }
+
+ private:
+  std::vector<AndroidLogId> log_ids_;
+  AndroidLogPriority min_prio_{};
+  std::vector<std::string> filter_tags_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_polled_state_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidPolledStateConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidPolledStateConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPollMsFieldNumber = 1,
+  };
+
+  AndroidPolledStateConfig();
+  ~AndroidPolledStateConfig() override;
+  AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept;
+  AndroidPolledStateConfig& operator=(AndroidPolledStateConfig&&);
+  AndroidPolledStateConfig(const AndroidPolledStateConfig&);
+  AndroidPolledStateConfig& operator=(const AndroidPolledStateConfig&);
+  bool operator==(const AndroidPolledStateConfig&) const;
+  bool operator!=(const AndroidPolledStateConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_poll_ms() const { return _has_field_[1]; }
+  uint32_t poll_ms() const { return poll_ms_; }
+  void set_poll_ms(uint32_t value) { poll_ms_ = value; _has_field_.set(1); }
+
+ private:
+  uint32_t poll_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SDK_SYSPROP_GUARD_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SDK_SYSPROP_GUARD_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidSdkSyspropGuardConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidSdkSyspropGuardConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSurfaceflingerSkiaTrackEventsFieldNumber = 1,
+    kHwuiSkiaTrackEventsFieldNumber = 2,
+    kHwuiPackageNameFilterFieldNumber = 3,
+  };
+
+  AndroidSdkSyspropGuardConfig();
+  ~AndroidSdkSyspropGuardConfig() override;
+  AndroidSdkSyspropGuardConfig(AndroidSdkSyspropGuardConfig&&) noexcept;
+  AndroidSdkSyspropGuardConfig& operator=(AndroidSdkSyspropGuardConfig&&);
+  AndroidSdkSyspropGuardConfig(const AndroidSdkSyspropGuardConfig&);
+  AndroidSdkSyspropGuardConfig& operator=(const AndroidSdkSyspropGuardConfig&);
+  bool operator==(const AndroidSdkSyspropGuardConfig&) const;
+  bool operator!=(const AndroidSdkSyspropGuardConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_surfaceflinger_skia_track_events() const { return _has_field_[1]; }
+  bool surfaceflinger_skia_track_events() const { return surfaceflinger_skia_track_events_; }
+  void set_surfaceflinger_skia_track_events(bool value) { surfaceflinger_skia_track_events_ = value; _has_field_.set(1); }
+
+  bool has_hwui_skia_track_events() const { return _has_field_[2]; }
+  bool hwui_skia_track_events() const { return hwui_skia_track_events_; }
+  void set_hwui_skia_track_events(bool value) { hwui_skia_track_events_ = value; _has_field_.set(2); }
+
+  const std::vector<std::string>& hwui_package_name_filter() const { return hwui_package_name_filter_; }
+  std::vector<std::string>* mutable_hwui_package_name_filter() { return &hwui_package_name_filter_; }
+  int hwui_package_name_filter_size() const { return static_cast<int>(hwui_package_name_filter_.size()); }
+  void clear_hwui_package_name_filter() { hwui_package_name_filter_.clear(); }
+  void add_hwui_package_name_filter(std::string value) { hwui_package_name_filter_.emplace_back(value); }
+  std::string* add_hwui_package_name_filter() { hwui_package_name_filter_.emplace_back(); return &hwui_package_name_filter_.back(); }
+
+ private:
+  bool surfaceflinger_skia_track_events_{};
+  bool hwui_skia_track_events_{};
+  std::vector<std::string> hwui_package_name_filter_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SDK_SYSPROP_GUARD_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_system_property_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SYSTEM_PROPERTY_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SYSTEM_PROPERTY_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidSystemPropertyConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT AndroidSystemPropertyConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPollMsFieldNumber = 1,
+    kPropertyNameFieldNumber = 2,
+  };
+
+  AndroidSystemPropertyConfig();
+  ~AndroidSystemPropertyConfig() override;
+  AndroidSystemPropertyConfig(AndroidSystemPropertyConfig&&) noexcept;
+  AndroidSystemPropertyConfig& operator=(AndroidSystemPropertyConfig&&);
+  AndroidSystemPropertyConfig(const AndroidSystemPropertyConfig&);
+  AndroidSystemPropertyConfig& operator=(const AndroidSystemPropertyConfig&);
+  bool operator==(const AndroidSystemPropertyConfig&) const;
+  bool operator!=(const AndroidSystemPropertyConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_poll_ms() const { return _has_field_[1]; }
+  uint32_t poll_ms() const { return poll_ms_; }
+  void set_poll_ms(uint32_t value) { poll_ms_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& property_name() const { return property_name_; }
+  std::vector<std::string>* mutable_property_name() { return &property_name_; }
+  int property_name_size() const { return static_cast<int>(property_name_.size()); }
+  void clear_property_name() { property_name_.clear(); }
+  void add_property_name(std::string value) { property_name_.emplace_back(value); }
+  std::string* add_property_name() { property_name_.emplace_back(); return &property_name_.back(); }
+
+ private:
+  uint32_t poll_ms_{};
+  std::vector<std::string> property_name_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SYSTEM_PROPERTY_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/network_trace_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_NETWORK_TRACE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_NETWORK_TRACE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class NetworkPacketTraceConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT NetworkPacketTraceConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPollMsFieldNumber = 1,
+    kAggregationThresholdFieldNumber = 2,
+    kInternLimitFieldNumber = 3,
+    kDropLocalPortFieldNumber = 4,
+    kDropRemotePortFieldNumber = 5,
+    kDropTcpFlagsFieldNumber = 6,
+  };
+
+  NetworkPacketTraceConfig();
+  ~NetworkPacketTraceConfig() override;
+  NetworkPacketTraceConfig(NetworkPacketTraceConfig&&) noexcept;
+  NetworkPacketTraceConfig& operator=(NetworkPacketTraceConfig&&);
+  NetworkPacketTraceConfig(const NetworkPacketTraceConfig&);
+  NetworkPacketTraceConfig& operator=(const NetworkPacketTraceConfig&);
+  bool operator==(const NetworkPacketTraceConfig&) const;
+  bool operator!=(const NetworkPacketTraceConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_poll_ms() const { return _has_field_[1]; }
+  uint32_t poll_ms() const { return poll_ms_; }
+  void set_poll_ms(uint32_t value) { poll_ms_ = value; _has_field_.set(1); }
+
+  bool has_aggregation_threshold() const { return _has_field_[2]; }
+  uint32_t aggregation_threshold() const { return aggregation_threshold_; }
+  void set_aggregation_threshold(uint32_t value) { aggregation_threshold_ = value; _has_field_.set(2); }
+
+  bool has_intern_limit() const { return _has_field_[3]; }
+  uint32_t intern_limit() const { return intern_limit_; }
+  void set_intern_limit(uint32_t value) { intern_limit_ = value; _has_field_.set(3); }
+
+  bool has_drop_local_port() const { return _has_field_[4]; }
+  bool drop_local_port() const { return drop_local_port_; }
+  void set_drop_local_port(bool value) { drop_local_port_ = value; _has_field_.set(4); }
+
+  bool has_drop_remote_port() const { return _has_field_[5]; }
+  bool drop_remote_port() const { return drop_remote_port_; }
+  void set_drop_remote_port(bool value) { drop_remote_port_ = value; _has_field_.set(5); }
+
+  bool has_drop_tcp_flags() const { return _has_field_[6]; }
+  bool drop_tcp_flags() const { return drop_tcp_flags_; }
+  void set_drop_tcp_flags(bool value) { drop_tcp_flags_ = value; _has_field_.set(6); }
+
+ private:
+  uint32_t poll_ms_{};
+  uint32_t aggregation_threshold_{};
+  uint32_t intern_limit_{};
+  bool drop_local_port_{};
+  bool drop_remote_port_{};
+  bool drop_tcp_flags_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_NETWORK_TRACE_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/packages_list_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class PackagesListConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT PackagesListConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPackageNameFilterFieldNumber = 1,
+  };
+
+  PackagesListConfig();
+  ~PackagesListConfig() override;
+  PackagesListConfig(PackagesListConfig&&) noexcept;
+  PackagesListConfig& operator=(PackagesListConfig&&);
+  PackagesListConfig(const PackagesListConfig&);
+  PackagesListConfig& operator=(const PackagesListConfig&);
+  bool operator==(const PackagesListConfig&) const;
+  bool operator!=(const PackagesListConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& package_name_filter() const { return package_name_filter_; }
+  std::vector<std::string>* mutable_package_name_filter() { return &package_name_filter_; }
+  int package_name_filter_size() const { return static_cast<int>(package_name_filter_.size()); }
+  void clear_package_name_filter() { package_name_filter_.clear(); }
+  void add_package_name_filter(std::string value) { package_name_filter_.emplace_back(value); }
+  std::string* add_package_name_filter() { package_name_filter_.emplace_back(); return &package_name_filter_.back(); }
+
+ private:
+  std::vector<std::string> package_name_filter_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/surfaceflinger_layers_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_LAYERS_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_LAYERS_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SurfaceFlingerLayersConfig;
+enum SurfaceFlingerLayersConfig_Mode : int;
+enum SurfaceFlingerLayersConfig_TraceFlag : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum SurfaceFlingerLayersConfig_Mode : int {
+  SurfaceFlingerLayersConfig_Mode_MODE_UNSPECIFIED = 0,
+  SurfaceFlingerLayersConfig_Mode_MODE_ACTIVE = 1,
+  SurfaceFlingerLayersConfig_Mode_MODE_GENERATED = 2,
+  SurfaceFlingerLayersConfig_Mode_MODE_DUMP = 3,
+  SurfaceFlingerLayersConfig_Mode_MODE_GENERATED_BUGREPORT_ONLY = 4,
+};
+enum SurfaceFlingerLayersConfig_TraceFlag : int {
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_UNSPECIFIED = 0,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_INPUT = 2,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_COMPOSITION = 4,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_EXTRA = 8,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_HWC = 16,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_BUFFERS = 32,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_VIRTUAL_DISPLAYS = 64,
+  SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_ALL = 14,
+};
+
+class PERFETTO_EXPORT_COMPONENT SurfaceFlingerLayersConfig : public ::protozero::CppMessageObj {
+ public:
+  using Mode = SurfaceFlingerLayersConfig_Mode;
+  static constexpr auto MODE_UNSPECIFIED = SurfaceFlingerLayersConfig_Mode_MODE_UNSPECIFIED;
+  static constexpr auto MODE_ACTIVE = SurfaceFlingerLayersConfig_Mode_MODE_ACTIVE;
+  static constexpr auto MODE_GENERATED = SurfaceFlingerLayersConfig_Mode_MODE_GENERATED;
+  static constexpr auto MODE_DUMP = SurfaceFlingerLayersConfig_Mode_MODE_DUMP;
+  static constexpr auto MODE_GENERATED_BUGREPORT_ONLY = SurfaceFlingerLayersConfig_Mode_MODE_GENERATED_BUGREPORT_ONLY;
+  static constexpr auto Mode_MIN = SurfaceFlingerLayersConfig_Mode_MODE_UNSPECIFIED;
+  static constexpr auto Mode_MAX = SurfaceFlingerLayersConfig_Mode_MODE_GENERATED_BUGREPORT_ONLY;
+  using TraceFlag = SurfaceFlingerLayersConfig_TraceFlag;
+  static constexpr auto TRACE_FLAG_UNSPECIFIED = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_UNSPECIFIED;
+  static constexpr auto TRACE_FLAG_INPUT = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_INPUT;
+  static constexpr auto TRACE_FLAG_COMPOSITION = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_COMPOSITION;
+  static constexpr auto TRACE_FLAG_EXTRA = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_EXTRA;
+  static constexpr auto TRACE_FLAG_HWC = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_HWC;
+  static constexpr auto TRACE_FLAG_BUFFERS = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_BUFFERS;
+  static constexpr auto TRACE_FLAG_VIRTUAL_DISPLAYS = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_VIRTUAL_DISPLAYS;
+  static constexpr auto TRACE_FLAG_ALL = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_ALL;
+  static constexpr auto TraceFlag_MIN = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_UNSPECIFIED;
+  static constexpr auto TraceFlag_MAX = SurfaceFlingerLayersConfig_TraceFlag_TRACE_FLAG_VIRTUAL_DISPLAYS;
+  enum FieldNumbers {
+    kModeFieldNumber = 1,
+    kTraceFlagsFieldNumber = 2,
+  };
+
+  SurfaceFlingerLayersConfig();
+  ~SurfaceFlingerLayersConfig() override;
+  SurfaceFlingerLayersConfig(SurfaceFlingerLayersConfig&&) noexcept;
+  SurfaceFlingerLayersConfig& operator=(SurfaceFlingerLayersConfig&&);
+  SurfaceFlingerLayersConfig(const SurfaceFlingerLayersConfig&);
+  SurfaceFlingerLayersConfig& operator=(const SurfaceFlingerLayersConfig&);
+  bool operator==(const SurfaceFlingerLayersConfig&) const;
+  bool operator!=(const SurfaceFlingerLayersConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_mode() const { return _has_field_[1]; }
+  SurfaceFlingerLayersConfig_Mode mode() const { return mode_; }
+  void set_mode(SurfaceFlingerLayersConfig_Mode value) { mode_ = value; _has_field_.set(1); }
+
+  const std::vector<SurfaceFlingerLayersConfig_TraceFlag>& trace_flags() const { return trace_flags_; }
+  std::vector<SurfaceFlingerLayersConfig_TraceFlag>* mutable_trace_flags() { return &trace_flags_; }
+  int trace_flags_size() const { return static_cast<int>(trace_flags_.size()); }
+  void clear_trace_flags() { trace_flags_.clear(); }
+  void add_trace_flags(SurfaceFlingerLayersConfig_TraceFlag value) { trace_flags_.emplace_back(value); }
+  SurfaceFlingerLayersConfig_TraceFlag* add_trace_flags() { trace_flags_.emplace_back(); return &trace_flags_.back(); }
+
+ private:
+  SurfaceFlingerLayersConfig_Mode mode_{};
+  std::vector<SurfaceFlingerLayersConfig_TraceFlag> trace_flags_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_LAYERS_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_TRANSACTIONS_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_TRANSACTIONS_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SurfaceFlingerTransactionsConfig;
+enum SurfaceFlingerTransactionsConfig_Mode : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum SurfaceFlingerTransactionsConfig_Mode : int {
+  SurfaceFlingerTransactionsConfig_Mode_MODE_UNSPECIFIED = 0,
+  SurfaceFlingerTransactionsConfig_Mode_MODE_CONTINUOUS = 1,
+  SurfaceFlingerTransactionsConfig_Mode_MODE_ACTIVE = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT SurfaceFlingerTransactionsConfig : public ::protozero::CppMessageObj {
+ public:
+  using Mode = SurfaceFlingerTransactionsConfig_Mode;
+  static constexpr auto MODE_UNSPECIFIED = SurfaceFlingerTransactionsConfig_Mode_MODE_UNSPECIFIED;
+  static constexpr auto MODE_CONTINUOUS = SurfaceFlingerTransactionsConfig_Mode_MODE_CONTINUOUS;
+  static constexpr auto MODE_ACTIVE = SurfaceFlingerTransactionsConfig_Mode_MODE_ACTIVE;
+  static constexpr auto Mode_MIN = SurfaceFlingerTransactionsConfig_Mode_MODE_UNSPECIFIED;
+  static constexpr auto Mode_MAX = SurfaceFlingerTransactionsConfig_Mode_MODE_ACTIVE;
+  enum FieldNumbers {
+    kModeFieldNumber = 1,
+  };
+
+  SurfaceFlingerTransactionsConfig();
+  ~SurfaceFlingerTransactionsConfig() override;
+  SurfaceFlingerTransactionsConfig(SurfaceFlingerTransactionsConfig&&) noexcept;
+  SurfaceFlingerTransactionsConfig& operator=(SurfaceFlingerTransactionsConfig&&);
+  SurfaceFlingerTransactionsConfig(const SurfaceFlingerTransactionsConfig&);
+  SurfaceFlingerTransactionsConfig& operator=(const SurfaceFlingerTransactionsConfig&);
+  bool operator==(const SurfaceFlingerTransactionsConfig&) const;
+  bool operator!=(const SurfaceFlingerTransactionsConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_mode() const { return _has_field_[1]; }
+  SurfaceFlingerTransactionsConfig_Mode mode() const { return mode_; }
+  void set_mode(SurfaceFlingerTransactionsConfig_Mode value) { mode_ = value; _has_field_.set(1); }
+
+ private:
+  SurfaceFlingerTransactionsConfig_Mode mode_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_TRANSACTIONS_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/ftrace/ftrace_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class FtraceConfig;
+class FtraceConfig_PrintFilter;
+class FtraceConfig_PrintFilter_Rule;
+class FtraceConfig_PrintFilter_Rule_AtraceMessage;
+class FtraceConfig_CompactSchedConfig;
+enum FtraceConfig_KsymsMemPolicy : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum FtraceConfig_KsymsMemPolicy : int {
+  FtraceConfig_KsymsMemPolicy_KSYMS_UNSPECIFIED = 0,
+  FtraceConfig_KsymsMemPolicy_KSYMS_CLEANUP_ON_STOP = 1,
+  FtraceConfig_KsymsMemPolicy_KSYMS_RETAIN = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT FtraceConfig : public ::protozero::CppMessageObj {
+ public:
+  using CompactSchedConfig = FtraceConfig_CompactSchedConfig;
+  using PrintFilter = FtraceConfig_PrintFilter;
+  using KsymsMemPolicy = FtraceConfig_KsymsMemPolicy;
+  static constexpr auto KSYMS_UNSPECIFIED = FtraceConfig_KsymsMemPolicy_KSYMS_UNSPECIFIED;
+  static constexpr auto KSYMS_CLEANUP_ON_STOP = FtraceConfig_KsymsMemPolicy_KSYMS_CLEANUP_ON_STOP;
+  static constexpr auto KSYMS_RETAIN = FtraceConfig_KsymsMemPolicy_KSYMS_RETAIN;
+  static constexpr auto KsymsMemPolicy_MIN = FtraceConfig_KsymsMemPolicy_KSYMS_UNSPECIFIED;
+  static constexpr auto KsymsMemPolicy_MAX = FtraceConfig_KsymsMemPolicy_KSYMS_RETAIN;
+  enum FieldNumbers {
+    kFtraceEventsFieldNumber = 1,
+    kAtraceCategoriesFieldNumber = 2,
+    kAtraceAppsFieldNumber = 3,
+    kBufferSizeKbFieldNumber = 10,
+    kDrainPeriodMsFieldNumber = 11,
+    kCompactSchedFieldNumber = 12,
+    kPrintFilterFieldNumber = 22,
+    kSymbolizeKsymsFieldNumber = 13,
+    kKsymsMemPolicyFieldNumber = 17,
+    kInitializeKsymsSynchronouslyForTestingFieldNumber = 14,
+    kThrottleRssStatFieldNumber = 15,
+    kDisableGenericEventsFieldNumber = 16,
+    kSyscallEventsFieldNumber = 18,
+    kEnableFunctionGraphFieldNumber = 19,
+    kFunctionFiltersFieldNumber = 20,
+    kFunctionGraphRootsFieldNumber = 21,
+    kPreserveFtraceBufferFieldNumber = 23,
+    kUseMonotonicRawClockFieldNumber = 24,
+    kInstanceNameFieldNumber = 25,
+  };
+
+  FtraceConfig();
+  ~FtraceConfig() override;
+  FtraceConfig(FtraceConfig&&) noexcept;
+  FtraceConfig& operator=(FtraceConfig&&);
+  FtraceConfig(const FtraceConfig&);
+  FtraceConfig& operator=(const FtraceConfig&);
+  bool operator==(const FtraceConfig&) const;
+  bool operator!=(const FtraceConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& ftrace_events() const { return ftrace_events_; }
+  std::vector<std::string>* mutable_ftrace_events() { return &ftrace_events_; }
+  int ftrace_events_size() const { return static_cast<int>(ftrace_events_.size()); }
+  void clear_ftrace_events() { ftrace_events_.clear(); }
+  void add_ftrace_events(std::string value) { ftrace_events_.emplace_back(value); }
+  std::string* add_ftrace_events() { ftrace_events_.emplace_back(); return &ftrace_events_.back(); }
+
+  const std::vector<std::string>& atrace_categories() const { return atrace_categories_; }
+  std::vector<std::string>* mutable_atrace_categories() { return &atrace_categories_; }
+  int atrace_categories_size() const { return static_cast<int>(atrace_categories_.size()); }
+  void clear_atrace_categories() { atrace_categories_.clear(); }
+  void add_atrace_categories(std::string value) { atrace_categories_.emplace_back(value); }
+  std::string* add_atrace_categories() { atrace_categories_.emplace_back(); return &atrace_categories_.back(); }
+
+  const std::vector<std::string>& atrace_apps() const { return atrace_apps_; }
+  std::vector<std::string>* mutable_atrace_apps() { return &atrace_apps_; }
+  int atrace_apps_size() const { return static_cast<int>(atrace_apps_.size()); }
+  void clear_atrace_apps() { atrace_apps_.clear(); }
+  void add_atrace_apps(std::string value) { atrace_apps_.emplace_back(value); }
+  std::string* add_atrace_apps() { atrace_apps_.emplace_back(); return &atrace_apps_.back(); }
+
+  bool has_buffer_size_kb() const { return _has_field_[10]; }
+  uint32_t buffer_size_kb() const { return buffer_size_kb_; }
+  void set_buffer_size_kb(uint32_t value) { buffer_size_kb_ = value; _has_field_.set(10); }
+
+  bool has_drain_period_ms() const { return _has_field_[11]; }
+  uint32_t drain_period_ms() const { return drain_period_ms_; }
+  void set_drain_period_ms(uint32_t value) { drain_period_ms_ = value; _has_field_.set(11); }
+
+  bool has_compact_sched() const { return _has_field_[12]; }
+  const FtraceConfig_CompactSchedConfig& compact_sched() const { return *compact_sched_; }
+  FtraceConfig_CompactSchedConfig* mutable_compact_sched() { _has_field_.set(12); return compact_sched_.get(); }
+
+  bool has_print_filter() const { return _has_field_[22]; }
+  const FtraceConfig_PrintFilter& print_filter() const { return *print_filter_; }
+  FtraceConfig_PrintFilter* mutable_print_filter() { _has_field_.set(22); return print_filter_.get(); }
+
+  bool has_symbolize_ksyms() const { return _has_field_[13]; }
+  bool symbolize_ksyms() const { return symbolize_ksyms_; }
+  void set_symbolize_ksyms(bool value) { symbolize_ksyms_ = value; _has_field_.set(13); }
+
+  bool has_ksyms_mem_policy() const { return _has_field_[17]; }
+  FtraceConfig_KsymsMemPolicy ksyms_mem_policy() const { return ksyms_mem_policy_; }
+  void set_ksyms_mem_policy(FtraceConfig_KsymsMemPolicy value) { ksyms_mem_policy_ = value; _has_field_.set(17); }
+
+  bool has_initialize_ksyms_synchronously_for_testing() const { return _has_field_[14]; }
+  bool initialize_ksyms_synchronously_for_testing() const { return initialize_ksyms_synchronously_for_testing_; }
+  void set_initialize_ksyms_synchronously_for_testing(bool value) { initialize_ksyms_synchronously_for_testing_ = value; _has_field_.set(14); }
+
+  bool has_throttle_rss_stat() const { return _has_field_[15]; }
+  bool throttle_rss_stat() const { return throttle_rss_stat_; }
+  void set_throttle_rss_stat(bool value) { throttle_rss_stat_ = value; _has_field_.set(15); }
+
+  bool has_disable_generic_events() const { return _has_field_[16]; }
+  bool disable_generic_events() const { return disable_generic_events_; }
+  void set_disable_generic_events(bool value) { disable_generic_events_ = value; _has_field_.set(16); }
+
+  const std::vector<std::string>& syscall_events() const { return syscall_events_; }
+  std::vector<std::string>* mutable_syscall_events() { return &syscall_events_; }
+  int syscall_events_size() const { return static_cast<int>(syscall_events_.size()); }
+  void clear_syscall_events() { syscall_events_.clear(); }
+  void add_syscall_events(std::string value) { syscall_events_.emplace_back(value); }
+  std::string* add_syscall_events() { syscall_events_.emplace_back(); return &syscall_events_.back(); }
+
+  bool has_enable_function_graph() const { return _has_field_[19]; }
+  bool enable_function_graph() const { return enable_function_graph_; }
+  void set_enable_function_graph(bool value) { enable_function_graph_ = value; _has_field_.set(19); }
+
+  const std::vector<std::string>& function_filters() const { return function_filters_; }
+  std::vector<std::string>* mutable_function_filters() { return &function_filters_; }
+  int function_filters_size() const { return static_cast<int>(function_filters_.size()); }
+  void clear_function_filters() { function_filters_.clear(); }
+  void add_function_filters(std::string value) { function_filters_.emplace_back(value); }
+  std::string* add_function_filters() { function_filters_.emplace_back(); return &function_filters_.back(); }
+
+  const std::vector<std::string>& function_graph_roots() const { return function_graph_roots_; }
+  std::vector<std::string>* mutable_function_graph_roots() { return &function_graph_roots_; }
+  int function_graph_roots_size() const { return static_cast<int>(function_graph_roots_.size()); }
+  void clear_function_graph_roots() { function_graph_roots_.clear(); }
+  void add_function_graph_roots(std::string value) { function_graph_roots_.emplace_back(value); }
+  std::string* add_function_graph_roots() { function_graph_roots_.emplace_back(); return &function_graph_roots_.back(); }
+
+  bool has_preserve_ftrace_buffer() const { return _has_field_[23]; }
+  bool preserve_ftrace_buffer() const { return preserve_ftrace_buffer_; }
+  void set_preserve_ftrace_buffer(bool value) { preserve_ftrace_buffer_ = value; _has_field_.set(23); }
+
+  bool has_use_monotonic_raw_clock() const { return _has_field_[24]; }
+  bool use_monotonic_raw_clock() const { return use_monotonic_raw_clock_; }
+  void set_use_monotonic_raw_clock(bool value) { use_monotonic_raw_clock_ = value; _has_field_.set(24); }
+
+  bool has_instance_name() const { return _has_field_[25]; }
+  const std::string& instance_name() const { return instance_name_; }
+  void set_instance_name(const std::string& value) { instance_name_ = value; _has_field_.set(25); }
+
+ private:
+  std::vector<std::string> ftrace_events_;
+  std::vector<std::string> atrace_categories_;
+  std::vector<std::string> atrace_apps_;
+  uint32_t buffer_size_kb_{};
+  uint32_t drain_period_ms_{};
+  ::protozero::CopyablePtr<FtraceConfig_CompactSchedConfig> compact_sched_;
+  ::protozero::CopyablePtr<FtraceConfig_PrintFilter> print_filter_;
+  bool symbolize_ksyms_{};
+  FtraceConfig_KsymsMemPolicy ksyms_mem_policy_{};
+  bool initialize_ksyms_synchronously_for_testing_{};
+  bool throttle_rss_stat_{};
+  bool disable_generic_events_{};
+  std::vector<std::string> syscall_events_;
+  bool enable_function_graph_{};
+  std::vector<std::string> function_filters_;
+  std::vector<std::string> function_graph_roots_;
+  bool preserve_ftrace_buffer_{};
+  bool use_monotonic_raw_clock_{};
+  std::string instance_name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<26> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FtraceConfig_PrintFilter : public ::protozero::CppMessageObj {
+ public:
+  using Rule = FtraceConfig_PrintFilter_Rule;
+  enum FieldNumbers {
+    kRulesFieldNumber = 1,
+  };
+
+  FtraceConfig_PrintFilter();
+  ~FtraceConfig_PrintFilter() override;
+  FtraceConfig_PrintFilter(FtraceConfig_PrintFilter&&) noexcept;
+  FtraceConfig_PrintFilter& operator=(FtraceConfig_PrintFilter&&);
+  FtraceConfig_PrintFilter(const FtraceConfig_PrintFilter&);
+  FtraceConfig_PrintFilter& operator=(const FtraceConfig_PrintFilter&);
+  bool operator==(const FtraceConfig_PrintFilter&) const;
+  bool operator!=(const FtraceConfig_PrintFilter& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<FtraceConfig_PrintFilter_Rule>& rules() const { return rules_; }
+  std::vector<FtraceConfig_PrintFilter_Rule>* mutable_rules() { return &rules_; }
+  int rules_size() const;
+  void clear_rules();
+  FtraceConfig_PrintFilter_Rule* add_rules();
+
+ private:
+  std::vector<FtraceConfig_PrintFilter_Rule> rules_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FtraceConfig_PrintFilter_Rule : public ::protozero::CppMessageObj {
+ public:
+  using AtraceMessage = FtraceConfig_PrintFilter_Rule_AtraceMessage;
+  enum FieldNumbers {
+    kPrefixFieldNumber = 1,
+    kAtraceMsgFieldNumber = 3,
+    kAllowFieldNumber = 2,
+  };
+
+  FtraceConfig_PrintFilter_Rule();
+  ~FtraceConfig_PrintFilter_Rule() override;
+  FtraceConfig_PrintFilter_Rule(FtraceConfig_PrintFilter_Rule&&) noexcept;
+  FtraceConfig_PrintFilter_Rule& operator=(FtraceConfig_PrintFilter_Rule&&);
+  FtraceConfig_PrintFilter_Rule(const FtraceConfig_PrintFilter_Rule&);
+  FtraceConfig_PrintFilter_Rule& operator=(const FtraceConfig_PrintFilter_Rule&);
+  bool operator==(const FtraceConfig_PrintFilter_Rule&) const;
+  bool operator!=(const FtraceConfig_PrintFilter_Rule& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_prefix() const { return _has_field_[1]; }
+  const std::string& prefix() const { return prefix_; }
+  void set_prefix(const std::string& value) { prefix_ = value; _has_field_.set(1); }
+
+  bool has_atrace_msg() const { return _has_field_[3]; }
+  const FtraceConfig_PrintFilter_Rule_AtraceMessage& atrace_msg() const { return *atrace_msg_; }
+  FtraceConfig_PrintFilter_Rule_AtraceMessage* mutable_atrace_msg() { _has_field_.set(3); return atrace_msg_.get(); }
+
+  bool has_allow() const { return _has_field_[2]; }
+  bool allow() const { return allow_; }
+  void set_allow(bool value) { allow_ = value; _has_field_.set(2); }
+
+ private:
+  std::string prefix_{};
+  ::protozero::CopyablePtr<FtraceConfig_PrintFilter_Rule_AtraceMessage> atrace_msg_;
+  bool allow_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FtraceConfig_PrintFilter_Rule_AtraceMessage : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTypeFieldNumber = 1,
+    kPrefixFieldNumber = 2,
+  };
+
+  FtraceConfig_PrintFilter_Rule_AtraceMessage();
+  ~FtraceConfig_PrintFilter_Rule_AtraceMessage() override;
+  FtraceConfig_PrintFilter_Rule_AtraceMessage(FtraceConfig_PrintFilter_Rule_AtraceMessage&&) noexcept;
+  FtraceConfig_PrintFilter_Rule_AtraceMessage& operator=(FtraceConfig_PrintFilter_Rule_AtraceMessage&&);
+  FtraceConfig_PrintFilter_Rule_AtraceMessage(const FtraceConfig_PrintFilter_Rule_AtraceMessage&);
+  FtraceConfig_PrintFilter_Rule_AtraceMessage& operator=(const FtraceConfig_PrintFilter_Rule_AtraceMessage&);
+  bool operator==(const FtraceConfig_PrintFilter_Rule_AtraceMessage&) const;
+  bool operator!=(const FtraceConfig_PrintFilter_Rule_AtraceMessage& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_type() const { return _has_field_[1]; }
+  const std::string& type() const { return type_; }
+  void set_type(const std::string& value) { type_ = value; _has_field_.set(1); }
+
+  bool has_prefix() const { return _has_field_[2]; }
+  const std::string& prefix() const { return prefix_; }
+  void set_prefix(const std::string& value) { prefix_ = value; _has_field_.set(2); }
+
+ private:
+  std::string type_{};
+  std::string prefix_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FtraceConfig_CompactSchedConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kEnabledFieldNumber = 1,
+  };
+
+  FtraceConfig_CompactSchedConfig();
+  ~FtraceConfig_CompactSchedConfig() override;
+  FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept;
+  FtraceConfig_CompactSchedConfig& operator=(FtraceConfig_CompactSchedConfig&&);
+  FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&);
+  FtraceConfig_CompactSchedConfig& operator=(const FtraceConfig_CompactSchedConfig&);
+  bool operator==(const FtraceConfig_CompactSchedConfig&) const;
+  bool operator!=(const FtraceConfig_CompactSchedConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_enabled() const { return _has_field_[1]; }
+  bool enabled() const { return enabled_; }
+  void set_enabled(bool value) { enabled_ = value; _has_field_.set(1); }
+
+ private:
+  bool enabled_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class GpuCounterConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT GpuCounterConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kCounterPeriodNsFieldNumber = 1,
+    kCounterIdsFieldNumber = 2,
+    kInstrumentedSamplingFieldNumber = 3,
+    kFixGpuClockFieldNumber = 4,
+  };
+
+  GpuCounterConfig();
+  ~GpuCounterConfig() override;
+  GpuCounterConfig(GpuCounterConfig&&) noexcept;
+  GpuCounterConfig& operator=(GpuCounterConfig&&);
+  GpuCounterConfig(const GpuCounterConfig&);
+  GpuCounterConfig& operator=(const GpuCounterConfig&);
+  bool operator==(const GpuCounterConfig&) const;
+  bool operator!=(const GpuCounterConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_counter_period_ns() const { return _has_field_[1]; }
+  uint64_t counter_period_ns() const { return counter_period_ns_; }
+  void set_counter_period_ns(uint64_t value) { counter_period_ns_ = value; _has_field_.set(1); }
+
+  const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
+  std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
+  int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
+  void clear_counter_ids() { counter_ids_.clear(); }
+  void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
+  uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
+
+  bool has_instrumented_sampling() const { return _has_field_[3]; }
+  bool instrumented_sampling() const { return instrumented_sampling_; }
+  void set_instrumented_sampling(bool value) { instrumented_sampling_ = value; _has_field_.set(3); }
+
+  bool has_fix_gpu_clock() const { return _has_field_[4]; }
+  bool fix_gpu_clock() const { return fix_gpu_clock_; }
+  void set_fix_gpu_clock(bool value) { fix_gpu_clock_ = value; _has_field_.set(4); }
+
+ private:
+  uint64_t counter_period_ns_{};
+  std::vector<uint32_t> counter_ids_;
+  bool instrumented_sampling_{};
+  bool fix_gpu_clock_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class VulkanMemoryConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT VulkanMemoryConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTrackDriverMemoryUsageFieldNumber = 1,
+    kTrackDeviceMemoryUsageFieldNumber = 2,
+  };
+
+  VulkanMemoryConfig();
+  ~VulkanMemoryConfig() override;
+  VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept;
+  VulkanMemoryConfig& operator=(VulkanMemoryConfig&&);
+  VulkanMemoryConfig(const VulkanMemoryConfig&);
+  VulkanMemoryConfig& operator=(const VulkanMemoryConfig&);
+  bool operator==(const VulkanMemoryConfig&) const;
+  bool operator!=(const VulkanMemoryConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_track_driver_memory_usage() const { return _has_field_[1]; }
+  bool track_driver_memory_usage() const { return track_driver_memory_usage_; }
+  void set_track_driver_memory_usage(bool value) { track_driver_memory_usage_ = value; _has_field_.set(1); }
+
+  bool has_track_device_memory_usage() const { return _has_field_[2]; }
+  bool track_device_memory_usage() const { return track_device_memory_usage_; }
+  void set_track_device_memory_usage(bool value) { track_device_memory_usage_ = value; _has_field_.set(2); }
+
+ private:
+  bool track_driver_memory_usage_{};
+  bool track_device_memory_usage_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/inode_file/inode_file_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class InodeFileConfig;
+class InodeFileConfig_MountPointMappingEntry;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT InodeFileConfig : public ::protozero::CppMessageObj {
+ public:
+  using MountPointMappingEntry = InodeFileConfig_MountPointMappingEntry;
+  enum FieldNumbers {
+    kScanIntervalMsFieldNumber = 1,
+    kScanDelayMsFieldNumber = 2,
+    kScanBatchSizeFieldNumber = 3,
+    kDoNotScanFieldNumber = 4,
+    kScanMountPointsFieldNumber = 5,
+    kMountPointMappingFieldNumber = 6,
+  };
+
+  InodeFileConfig();
+  ~InodeFileConfig() override;
+  InodeFileConfig(InodeFileConfig&&) noexcept;
+  InodeFileConfig& operator=(InodeFileConfig&&);
+  InodeFileConfig(const InodeFileConfig&);
+  InodeFileConfig& operator=(const InodeFileConfig&);
+  bool operator==(const InodeFileConfig&) const;
+  bool operator!=(const InodeFileConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_scan_interval_ms() const { return _has_field_[1]; }
+  uint32_t scan_interval_ms() const { return scan_interval_ms_; }
+  void set_scan_interval_ms(uint32_t value) { scan_interval_ms_ = value; _has_field_.set(1); }
+
+  bool has_scan_delay_ms() const { return _has_field_[2]; }
+  uint32_t scan_delay_ms() const { return scan_delay_ms_; }
+  void set_scan_delay_ms(uint32_t value) { scan_delay_ms_ = value; _has_field_.set(2); }
+
+  bool has_scan_batch_size() const { return _has_field_[3]; }
+  uint32_t scan_batch_size() const { return scan_batch_size_; }
+  void set_scan_batch_size(uint32_t value) { scan_batch_size_ = value; _has_field_.set(3); }
+
+  bool has_do_not_scan() const { return _has_field_[4]; }
+  bool do_not_scan() const { return do_not_scan_; }
+  void set_do_not_scan(bool value) { do_not_scan_ = value; _has_field_.set(4); }
+
+  const std::vector<std::string>& scan_mount_points() const { return scan_mount_points_; }
+  std::vector<std::string>* mutable_scan_mount_points() { return &scan_mount_points_; }
+  int scan_mount_points_size() const { return static_cast<int>(scan_mount_points_.size()); }
+  void clear_scan_mount_points() { scan_mount_points_.clear(); }
+  void add_scan_mount_points(std::string value) { scan_mount_points_.emplace_back(value); }
+  std::string* add_scan_mount_points() { scan_mount_points_.emplace_back(); return &scan_mount_points_.back(); }
+
+  const std::vector<InodeFileConfig_MountPointMappingEntry>& mount_point_mapping() const { return mount_point_mapping_; }
+  std::vector<InodeFileConfig_MountPointMappingEntry>* mutable_mount_point_mapping() { return &mount_point_mapping_; }
+  int mount_point_mapping_size() const;
+  void clear_mount_point_mapping();
+  InodeFileConfig_MountPointMappingEntry* add_mount_point_mapping();
+
+ private:
+  uint32_t scan_interval_ms_{};
+  uint32_t scan_delay_ms_{};
+  uint32_t scan_batch_size_{};
+  bool do_not_scan_{};
+  std::vector<std::string> scan_mount_points_;
+  std::vector<InodeFileConfig_MountPointMappingEntry> mount_point_mapping_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT InodeFileConfig_MountPointMappingEntry : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kMountpointFieldNumber = 1,
+    kScanRootsFieldNumber = 2,
+  };
+
+  InodeFileConfig_MountPointMappingEntry();
+  ~InodeFileConfig_MountPointMappingEntry() override;
+  InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept;
+  InodeFileConfig_MountPointMappingEntry& operator=(InodeFileConfig_MountPointMappingEntry&&);
+  InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&);
+  InodeFileConfig_MountPointMappingEntry& operator=(const InodeFileConfig_MountPointMappingEntry&);
+  bool operator==(const InodeFileConfig_MountPointMappingEntry&) const;
+  bool operator!=(const InodeFileConfig_MountPointMappingEntry& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_mountpoint() const { return _has_field_[1]; }
+  const std::string& mountpoint() const { return mountpoint_; }
+  void set_mountpoint(const std::string& value) { mountpoint_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& scan_roots() const { return scan_roots_; }
+  std::vector<std::string>* mutable_scan_roots() { return &scan_roots_; }
+  int scan_roots_size() const { return static_cast<int>(scan_roots_.size()); }
+  void clear_scan_roots() { scan_roots_.clear(); }
+  void add_scan_roots(std::string value) { scan_roots_.emplace_back(value); }
+  std::string* add_scan_roots() { scan_roots_.emplace_back(); return &scan_roots_.back(); }
+
+ private:
+  std::string mountpoint_{};
+  std::vector<std::string> scan_roots_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/interceptors/console_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ConsoleConfig;
+enum ConsoleConfig_Output : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ConsoleConfig_Output : int {
+  ConsoleConfig_Output_OUTPUT_UNSPECIFIED = 0,
+  ConsoleConfig_Output_OUTPUT_STDOUT = 1,
+  ConsoleConfig_Output_OUTPUT_STDERR = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT ConsoleConfig : public ::protozero::CppMessageObj {
+ public:
+  using Output = ConsoleConfig_Output;
+  static constexpr auto OUTPUT_UNSPECIFIED = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
+  static constexpr auto OUTPUT_STDOUT = ConsoleConfig_Output_OUTPUT_STDOUT;
+  static constexpr auto OUTPUT_STDERR = ConsoleConfig_Output_OUTPUT_STDERR;
+  static constexpr auto Output_MIN = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
+  static constexpr auto Output_MAX = ConsoleConfig_Output_OUTPUT_STDERR;
+  enum FieldNumbers {
+    kOutputFieldNumber = 1,
+    kEnableColorsFieldNumber = 2,
+  };
+
+  ConsoleConfig();
+  ~ConsoleConfig() override;
+  ConsoleConfig(ConsoleConfig&&) noexcept;
+  ConsoleConfig& operator=(ConsoleConfig&&);
+  ConsoleConfig(const ConsoleConfig&);
+  ConsoleConfig& operator=(const ConsoleConfig&);
+  bool operator==(const ConsoleConfig&) const;
+  bool operator!=(const ConsoleConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_output() const { return _has_field_[1]; }
+  ConsoleConfig_Output output() const { return output_; }
+  void set_output(ConsoleConfig_Output value) { output_ = value; _has_field_.set(1); }
+
+  bool has_enable_colors() const { return _has_field_[2]; }
+  bool enable_colors() const { return enable_colors_; }
+  void set_enable_colors(bool value) { enable_colors_ = value; _has_field_.set(2); }
+
+ private:
+  ConsoleConfig_Output output_{};
+  bool enable_colors_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/power/android_power_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class AndroidPowerConfig;
+enum AndroidPowerConfig_BatteryCounters : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AndroidPowerConfig_BatteryCounters : int {
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED = 0,
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE = 1,
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT = 2,
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT = 3,
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG = 4,
+  AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_VOLTAGE = 5,
+};
+
+class PERFETTO_EXPORT_COMPONENT AndroidPowerConfig : public ::protozero::CppMessageObj {
+ public:
+  using BatteryCounters = AndroidPowerConfig_BatteryCounters;
+  static constexpr auto BATTERY_COUNTER_UNSPECIFIED = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
+  static constexpr auto BATTERY_COUNTER_CHARGE = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE;
+  static constexpr auto BATTERY_COUNTER_CAPACITY_PERCENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT;
+  static constexpr auto BATTERY_COUNTER_CURRENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT;
+  static constexpr auto BATTERY_COUNTER_CURRENT_AVG = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
+  static constexpr auto BATTERY_COUNTER_VOLTAGE = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_VOLTAGE;
+  static constexpr auto BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
+  static constexpr auto BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_VOLTAGE;
+  enum FieldNumbers {
+    kBatteryPollMsFieldNumber = 1,
+    kBatteryCountersFieldNumber = 2,
+    kCollectPowerRailsFieldNumber = 3,
+    kCollectEnergyEstimationBreakdownFieldNumber = 4,
+    kCollectEntityStateResidencyFieldNumber = 5,
+  };
+
+  AndroidPowerConfig();
+  ~AndroidPowerConfig() override;
+  AndroidPowerConfig(AndroidPowerConfig&&) noexcept;
+  AndroidPowerConfig& operator=(AndroidPowerConfig&&);
+  AndroidPowerConfig(const AndroidPowerConfig&);
+  AndroidPowerConfig& operator=(const AndroidPowerConfig&);
+  bool operator==(const AndroidPowerConfig&) const;
+  bool operator!=(const AndroidPowerConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_battery_poll_ms() const { return _has_field_[1]; }
+  uint32_t battery_poll_ms() const { return battery_poll_ms_; }
+  void set_battery_poll_ms(uint32_t value) { battery_poll_ms_ = value; _has_field_.set(1); }
+
+  const std::vector<AndroidPowerConfig_BatteryCounters>& battery_counters() const { return battery_counters_; }
+  std::vector<AndroidPowerConfig_BatteryCounters>* mutable_battery_counters() { return &battery_counters_; }
+  int battery_counters_size() const { return static_cast<int>(battery_counters_.size()); }
+  void clear_battery_counters() { battery_counters_.clear(); }
+  void add_battery_counters(AndroidPowerConfig_BatteryCounters value) { battery_counters_.emplace_back(value); }
+  AndroidPowerConfig_BatteryCounters* add_battery_counters() { battery_counters_.emplace_back(); return &battery_counters_.back(); }
+
+  bool has_collect_power_rails() const { return _has_field_[3]; }
+  bool collect_power_rails() const { return collect_power_rails_; }
+  void set_collect_power_rails(bool value) { collect_power_rails_ = value; _has_field_.set(3); }
+
+  bool has_collect_energy_estimation_breakdown() const { return _has_field_[4]; }
+  bool collect_energy_estimation_breakdown() const { return collect_energy_estimation_breakdown_; }
+  void set_collect_energy_estimation_breakdown(bool value) { collect_energy_estimation_breakdown_ = value; _has_field_.set(4); }
+
+  bool has_collect_entity_state_residency() const { return _has_field_[5]; }
+  bool collect_entity_state_residency() const { return collect_entity_state_residency_; }
+  void set_collect_entity_state_residency(bool value) { collect_entity_state_residency_ = value; _has_field_.set(5); }
+
+ private:
+  uint32_t battery_poll_ms_{};
+  std::vector<AndroidPowerConfig_BatteryCounters> battery_counters_;
+  bool collect_power_rails_{};
+  bool collect_energy_estimation_breakdown_{};
+  bool collect_entity_state_residency_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/process_stats/process_stats_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ProcessStatsConfig;
+enum ProcessStatsConfig_Quirks : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ProcessStatsConfig_Quirks : int {
+  ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED = 0,
+  ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP = 1,
+  ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT ProcessStatsConfig : public ::protozero::CppMessageObj {
+ public:
+  using Quirks = ProcessStatsConfig_Quirks;
+  static constexpr auto QUIRKS_UNSPECIFIED = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
+  static constexpr auto DISABLE_INITIAL_DUMP = ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP;
+  static constexpr auto DISABLE_ON_DEMAND = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
+  static constexpr auto Quirks_MIN = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
+  static constexpr auto Quirks_MAX = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
+  enum FieldNumbers {
+    kQuirksFieldNumber = 1,
+    kScanAllProcessesOnStartFieldNumber = 2,
+    kRecordThreadNamesFieldNumber = 3,
+    kProcStatsPollMsFieldNumber = 4,
+    kProcStatsCacheTtlMsFieldNumber = 6,
+    kResolveProcessFdsFieldNumber = 9,
+    kScanSmapsRollupFieldNumber = 10,
+  };
+
+  ProcessStatsConfig();
+  ~ProcessStatsConfig() override;
+  ProcessStatsConfig(ProcessStatsConfig&&) noexcept;
+  ProcessStatsConfig& operator=(ProcessStatsConfig&&);
+  ProcessStatsConfig(const ProcessStatsConfig&);
+  ProcessStatsConfig& operator=(const ProcessStatsConfig&);
+  bool operator==(const ProcessStatsConfig&) const;
+  bool operator!=(const ProcessStatsConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ProcessStatsConfig_Quirks>& quirks() const { return quirks_; }
+  std::vector<ProcessStatsConfig_Quirks>* mutable_quirks() { return &quirks_; }
+  int quirks_size() const { return static_cast<int>(quirks_.size()); }
+  void clear_quirks() { quirks_.clear(); }
+  void add_quirks(ProcessStatsConfig_Quirks value) { quirks_.emplace_back(value); }
+  ProcessStatsConfig_Quirks* add_quirks() { quirks_.emplace_back(); return &quirks_.back(); }
+
+  bool has_scan_all_processes_on_start() const { return _has_field_[2]; }
+  bool scan_all_processes_on_start() const { return scan_all_processes_on_start_; }
+  void set_scan_all_processes_on_start(bool value) { scan_all_processes_on_start_ = value; _has_field_.set(2); }
+
+  bool has_record_thread_names() const { return _has_field_[3]; }
+  bool record_thread_names() const { return record_thread_names_; }
+  void set_record_thread_names(bool value) { record_thread_names_ = value; _has_field_.set(3); }
+
+  bool has_proc_stats_poll_ms() const { return _has_field_[4]; }
+  uint32_t proc_stats_poll_ms() const { return proc_stats_poll_ms_; }
+  void set_proc_stats_poll_ms(uint32_t value) { proc_stats_poll_ms_ = value; _has_field_.set(4); }
+
+  bool has_proc_stats_cache_ttl_ms() const { return _has_field_[6]; }
+  uint32_t proc_stats_cache_ttl_ms() const { return proc_stats_cache_ttl_ms_; }
+  void set_proc_stats_cache_ttl_ms(uint32_t value) { proc_stats_cache_ttl_ms_ = value; _has_field_.set(6); }
+
+  bool has_resolve_process_fds() const { return _has_field_[9]; }
+  bool resolve_process_fds() const { return resolve_process_fds_; }
+  void set_resolve_process_fds(bool value) { resolve_process_fds_ = value; _has_field_.set(9); }
+
+  bool has_scan_smaps_rollup() const { return _has_field_[10]; }
+  bool scan_smaps_rollup() const { return scan_smaps_rollup_; }
+  void set_scan_smaps_rollup(bool value) { scan_smaps_rollup_ = value; _has_field_.set(10); }
+
+ private:
+  std::vector<ProcessStatsConfig_Quirks> quirks_;
+  bool scan_all_processes_on_start_{};
+  bool record_thread_names_{};
+  uint32_t proc_stats_poll_ms_{};
+  uint32_t proc_stats_cache_ttl_ms_{};
+  bool resolve_process_fds_{};
+  bool scan_smaps_rollup_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<11> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/heapprofd_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class HeapprofdConfig;
+class HeapprofdConfig_ContinuousDumpConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT HeapprofdConfig : public ::protozero::CppMessageObj {
+ public:
+  using ContinuousDumpConfig = HeapprofdConfig_ContinuousDumpConfig;
+  enum FieldNumbers {
+    kSamplingIntervalBytesFieldNumber = 1,
+    kAdaptiveSamplingShmemThresholdFieldNumber = 24,
+    kAdaptiveSamplingMaxSamplingIntervalBytesFieldNumber = 25,
+    kProcessCmdlineFieldNumber = 2,
+    kPidFieldNumber = 4,
+    kTargetInstalledByFieldNumber = 26,
+    kHeapsFieldNumber = 20,
+    kExcludeHeapsFieldNumber = 27,
+    kStreamAllocationsFieldNumber = 23,
+    kHeapSamplingIntervalsFieldNumber = 22,
+    kAllHeapsFieldNumber = 21,
+    kAllFieldNumber = 5,
+    kMinAnonymousMemoryKbFieldNumber = 15,
+    kMaxHeapprofdMemoryKbFieldNumber = 16,
+    kMaxHeapprofdCpuSecsFieldNumber = 17,
+    kSkipSymbolPrefixFieldNumber = 7,
+    kContinuousDumpConfigFieldNumber = 6,
+    kShmemSizeBytesFieldNumber = 8,
+    kBlockClientFieldNumber = 9,
+    kBlockClientTimeoutUsFieldNumber = 14,
+    kNoStartupFieldNumber = 10,
+    kNoRunningFieldNumber = 11,
+    kDumpAtMaxFieldNumber = 13,
+    kDisableForkTeardownFieldNumber = 18,
+    kDisableVforkDetectionFieldNumber = 19,
+  };
+
+  HeapprofdConfig();
+  ~HeapprofdConfig() override;
+  HeapprofdConfig(HeapprofdConfig&&) noexcept;
+  HeapprofdConfig& operator=(HeapprofdConfig&&);
+  HeapprofdConfig(const HeapprofdConfig&);
+  HeapprofdConfig& operator=(const HeapprofdConfig&);
+  bool operator==(const HeapprofdConfig&) const;
+  bool operator!=(const HeapprofdConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_sampling_interval_bytes() const { return _has_field_[1]; }
+  uint64_t sampling_interval_bytes() const { return sampling_interval_bytes_; }
+  void set_sampling_interval_bytes(uint64_t value) { sampling_interval_bytes_ = value; _has_field_.set(1); }
+
+  bool has_adaptive_sampling_shmem_threshold() const { return _has_field_[24]; }
+  uint64_t adaptive_sampling_shmem_threshold() const { return adaptive_sampling_shmem_threshold_; }
+  void set_adaptive_sampling_shmem_threshold(uint64_t value) { adaptive_sampling_shmem_threshold_ = value; _has_field_.set(24); }
+
+  bool has_adaptive_sampling_max_sampling_interval_bytes() const { return _has_field_[25]; }
+  uint64_t adaptive_sampling_max_sampling_interval_bytes() const { return adaptive_sampling_max_sampling_interval_bytes_; }
+  void set_adaptive_sampling_max_sampling_interval_bytes(uint64_t value) { adaptive_sampling_max_sampling_interval_bytes_ = value; _has_field_.set(25); }
+
+  const std::vector<std::string>& process_cmdline() const { return process_cmdline_; }
+  std::vector<std::string>* mutable_process_cmdline() { return &process_cmdline_; }
+  int process_cmdline_size() const { return static_cast<int>(process_cmdline_.size()); }
+  void clear_process_cmdline() { process_cmdline_.clear(); }
+  void add_process_cmdline(std::string value) { process_cmdline_.emplace_back(value); }
+  std::string* add_process_cmdline() { process_cmdline_.emplace_back(); return &process_cmdline_.back(); }
+
+  const std::vector<uint64_t>& pid() const { return pid_; }
+  std::vector<uint64_t>* mutable_pid() { return &pid_; }
+  int pid_size() const { return static_cast<int>(pid_.size()); }
+  void clear_pid() { pid_.clear(); }
+  void add_pid(uint64_t value) { pid_.emplace_back(value); }
+  uint64_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
+
+  const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
+  std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
+  int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
+  void clear_target_installed_by() { target_installed_by_.clear(); }
+  void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
+  std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
+
+  const std::vector<std::string>& heaps() const { return heaps_; }
+  std::vector<std::string>* mutable_heaps() { return &heaps_; }
+  int heaps_size() const { return static_cast<int>(heaps_.size()); }
+  void clear_heaps() { heaps_.clear(); }
+  void add_heaps(std::string value) { heaps_.emplace_back(value); }
+  std::string* add_heaps() { heaps_.emplace_back(); return &heaps_.back(); }
+
+  const std::vector<std::string>& exclude_heaps() const { return exclude_heaps_; }
+  std::vector<std::string>* mutable_exclude_heaps() { return &exclude_heaps_; }
+  int exclude_heaps_size() const { return static_cast<int>(exclude_heaps_.size()); }
+  void clear_exclude_heaps() { exclude_heaps_.clear(); }
+  void add_exclude_heaps(std::string value) { exclude_heaps_.emplace_back(value); }
+  std::string* add_exclude_heaps() { exclude_heaps_.emplace_back(); return &exclude_heaps_.back(); }
+
+  bool has_stream_allocations() const { return _has_field_[23]; }
+  bool stream_allocations() const { return stream_allocations_; }
+  void set_stream_allocations(bool value) { stream_allocations_ = value; _has_field_.set(23); }
+
+  const std::vector<uint64_t>& heap_sampling_intervals() const { return heap_sampling_intervals_; }
+  std::vector<uint64_t>* mutable_heap_sampling_intervals() { return &heap_sampling_intervals_; }
+  int heap_sampling_intervals_size() const { return static_cast<int>(heap_sampling_intervals_.size()); }
+  void clear_heap_sampling_intervals() { heap_sampling_intervals_.clear(); }
+  void add_heap_sampling_intervals(uint64_t value) { heap_sampling_intervals_.emplace_back(value); }
+  uint64_t* add_heap_sampling_intervals() { heap_sampling_intervals_.emplace_back(); return &heap_sampling_intervals_.back(); }
+
+  bool has_all_heaps() const { return _has_field_[21]; }
+  bool all_heaps() const { return all_heaps_; }
+  void set_all_heaps(bool value) { all_heaps_ = value; _has_field_.set(21); }
+
+  bool has_all() const { return _has_field_[5]; }
+  bool all() const { return all_; }
+  void set_all(bool value) { all_ = value; _has_field_.set(5); }
+
+  bool has_min_anonymous_memory_kb() const { return _has_field_[15]; }
+  uint32_t min_anonymous_memory_kb() const { return min_anonymous_memory_kb_; }
+  void set_min_anonymous_memory_kb(uint32_t value) { min_anonymous_memory_kb_ = value; _has_field_.set(15); }
+
+  bool has_max_heapprofd_memory_kb() const { return _has_field_[16]; }
+  uint32_t max_heapprofd_memory_kb() const { return max_heapprofd_memory_kb_; }
+  void set_max_heapprofd_memory_kb(uint32_t value) { max_heapprofd_memory_kb_ = value; _has_field_.set(16); }
+
+  bool has_max_heapprofd_cpu_secs() const { return _has_field_[17]; }
+  uint64_t max_heapprofd_cpu_secs() const { return max_heapprofd_cpu_secs_; }
+  void set_max_heapprofd_cpu_secs(uint64_t value) { max_heapprofd_cpu_secs_ = value; _has_field_.set(17); }
+
+  const std::vector<std::string>& skip_symbol_prefix() const { return skip_symbol_prefix_; }
+  std::vector<std::string>* mutable_skip_symbol_prefix() { return &skip_symbol_prefix_; }
+  int skip_symbol_prefix_size() const { return static_cast<int>(skip_symbol_prefix_.size()); }
+  void clear_skip_symbol_prefix() { skip_symbol_prefix_.clear(); }
+  void add_skip_symbol_prefix(std::string value) { skip_symbol_prefix_.emplace_back(value); }
+  std::string* add_skip_symbol_prefix() { skip_symbol_prefix_.emplace_back(); return &skip_symbol_prefix_.back(); }
+
+  bool has_continuous_dump_config() const { return _has_field_[6]; }
+  const HeapprofdConfig_ContinuousDumpConfig& continuous_dump_config() const { return *continuous_dump_config_; }
+  HeapprofdConfig_ContinuousDumpConfig* mutable_continuous_dump_config() { _has_field_.set(6); return continuous_dump_config_.get(); }
+
+  bool has_shmem_size_bytes() const { return _has_field_[8]; }
+  uint64_t shmem_size_bytes() const { return shmem_size_bytes_; }
+  void set_shmem_size_bytes(uint64_t value) { shmem_size_bytes_ = value; _has_field_.set(8); }
+
+  bool has_block_client() const { return _has_field_[9]; }
+  bool block_client() const { return block_client_; }
+  void set_block_client(bool value) { block_client_ = value; _has_field_.set(9); }
+
+  bool has_block_client_timeout_us() const { return _has_field_[14]; }
+  uint32_t block_client_timeout_us() const { return block_client_timeout_us_; }
+  void set_block_client_timeout_us(uint32_t value) { block_client_timeout_us_ = value; _has_field_.set(14); }
+
+  bool has_no_startup() const { return _has_field_[10]; }
+  bool no_startup() const { return no_startup_; }
+  void set_no_startup(bool value) { no_startup_ = value; _has_field_.set(10); }
+
+  bool has_no_running() const { return _has_field_[11]; }
+  bool no_running() const { return no_running_; }
+  void set_no_running(bool value) { no_running_ = value; _has_field_.set(11); }
+
+  bool has_dump_at_max() const { return _has_field_[13]; }
+  bool dump_at_max() const { return dump_at_max_; }
+  void set_dump_at_max(bool value) { dump_at_max_ = value; _has_field_.set(13); }
+
+  bool has_disable_fork_teardown() const { return _has_field_[18]; }
+  bool disable_fork_teardown() const { return disable_fork_teardown_; }
+  void set_disable_fork_teardown(bool value) { disable_fork_teardown_ = value; _has_field_.set(18); }
+
+  bool has_disable_vfork_detection() const { return _has_field_[19]; }
+  bool disable_vfork_detection() const { return disable_vfork_detection_; }
+  void set_disable_vfork_detection(bool value) { disable_vfork_detection_ = value; _has_field_.set(19); }
+
+ private:
+  uint64_t sampling_interval_bytes_{};
+  uint64_t adaptive_sampling_shmem_threshold_{};
+  uint64_t adaptive_sampling_max_sampling_interval_bytes_{};
+  std::vector<std::string> process_cmdline_;
+  std::vector<uint64_t> pid_;
+  std::vector<std::string> target_installed_by_;
+  std::vector<std::string> heaps_;
+  std::vector<std::string> exclude_heaps_;
+  bool stream_allocations_{};
+  std::vector<uint64_t> heap_sampling_intervals_;
+  bool all_heaps_{};
+  bool all_{};
+  uint32_t min_anonymous_memory_kb_{};
+  uint32_t max_heapprofd_memory_kb_{};
+  uint64_t max_heapprofd_cpu_secs_{};
+  std::vector<std::string> skip_symbol_prefix_;
+  ::protozero::CopyablePtr<HeapprofdConfig_ContinuousDumpConfig> continuous_dump_config_;
+  uint64_t shmem_size_bytes_{};
+  bool block_client_{};
+  uint32_t block_client_timeout_us_{};
+  bool no_startup_{};
+  bool no_running_{};
+  bool dump_at_max_{};
+  bool disable_fork_teardown_{};
+  bool disable_vfork_detection_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<28> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT HeapprofdConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDumpPhaseMsFieldNumber = 5,
+    kDumpIntervalMsFieldNumber = 6,
+  };
+
+  HeapprofdConfig_ContinuousDumpConfig();
+  ~HeapprofdConfig_ContinuousDumpConfig() override;
+  HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept;
+  HeapprofdConfig_ContinuousDumpConfig& operator=(HeapprofdConfig_ContinuousDumpConfig&&);
+  HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&);
+  HeapprofdConfig_ContinuousDumpConfig& operator=(const HeapprofdConfig_ContinuousDumpConfig&);
+  bool operator==(const HeapprofdConfig_ContinuousDumpConfig&) const;
+  bool operator!=(const HeapprofdConfig_ContinuousDumpConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_dump_phase_ms() const { return _has_field_[5]; }
+  uint32_t dump_phase_ms() const { return dump_phase_ms_; }
+  void set_dump_phase_ms(uint32_t value) { dump_phase_ms_ = value; _has_field_.set(5); }
+
+  bool has_dump_interval_ms() const { return _has_field_[6]; }
+  uint32_t dump_interval_ms() const { return dump_interval_ms_; }
+  void set_dump_interval_ms(uint32_t value) { dump_interval_ms_ = value; _has_field_.set(6); }
+
+ private:
+  uint32_t dump_phase_ms_{};
+  uint32_t dump_interval_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/java_hprof_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class JavaHprofConfig;
+class JavaHprofConfig_ContinuousDumpConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT JavaHprofConfig : public ::protozero::CppMessageObj {
+ public:
+  using ContinuousDumpConfig = JavaHprofConfig_ContinuousDumpConfig;
+  enum FieldNumbers {
+    kProcessCmdlineFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTargetInstalledByFieldNumber = 7,
+    kContinuousDumpConfigFieldNumber = 3,
+    kMinAnonymousMemoryKbFieldNumber = 4,
+    kDumpSmapsFieldNumber = 5,
+    kIgnoredTypesFieldNumber = 6,
+  };
+
+  JavaHprofConfig();
+  ~JavaHprofConfig() override;
+  JavaHprofConfig(JavaHprofConfig&&) noexcept;
+  JavaHprofConfig& operator=(JavaHprofConfig&&);
+  JavaHprofConfig(const JavaHprofConfig&);
+  JavaHprofConfig& operator=(const JavaHprofConfig&);
+  bool operator==(const JavaHprofConfig&) const;
+  bool operator!=(const JavaHprofConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& process_cmdline() const { return process_cmdline_; }
+  std::vector<std::string>* mutable_process_cmdline() { return &process_cmdline_; }
+  int process_cmdline_size() const { return static_cast<int>(process_cmdline_.size()); }
+  void clear_process_cmdline() { process_cmdline_.clear(); }
+  void add_process_cmdline(std::string value) { process_cmdline_.emplace_back(value); }
+  std::string* add_process_cmdline() { process_cmdline_.emplace_back(); return &process_cmdline_.back(); }
+
+  const std::vector<uint64_t>& pid() const { return pid_; }
+  std::vector<uint64_t>* mutable_pid() { return &pid_; }
+  int pid_size() const { return static_cast<int>(pid_.size()); }
+  void clear_pid() { pid_.clear(); }
+  void add_pid(uint64_t value) { pid_.emplace_back(value); }
+  uint64_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
+
+  const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
+  std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
+  int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
+  void clear_target_installed_by() { target_installed_by_.clear(); }
+  void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
+  std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
+
+  bool has_continuous_dump_config() const { return _has_field_[3]; }
+  const JavaHprofConfig_ContinuousDumpConfig& continuous_dump_config() const { return *continuous_dump_config_; }
+  JavaHprofConfig_ContinuousDumpConfig* mutable_continuous_dump_config() { _has_field_.set(3); return continuous_dump_config_.get(); }
+
+  bool has_min_anonymous_memory_kb() const { return _has_field_[4]; }
+  uint32_t min_anonymous_memory_kb() const { return min_anonymous_memory_kb_; }
+  void set_min_anonymous_memory_kb(uint32_t value) { min_anonymous_memory_kb_ = value; _has_field_.set(4); }
+
+  bool has_dump_smaps() const { return _has_field_[5]; }
+  bool dump_smaps() const { return dump_smaps_; }
+  void set_dump_smaps(bool value) { dump_smaps_ = value; _has_field_.set(5); }
+
+  const std::vector<std::string>& ignored_types() const { return ignored_types_; }
+  std::vector<std::string>* mutable_ignored_types() { return &ignored_types_; }
+  int ignored_types_size() const { return static_cast<int>(ignored_types_.size()); }
+  void clear_ignored_types() { ignored_types_.clear(); }
+  void add_ignored_types(std::string value) { ignored_types_.emplace_back(value); }
+  std::string* add_ignored_types() { ignored_types_.emplace_back(); return &ignored_types_.back(); }
+
+ private:
+  std::vector<std::string> process_cmdline_;
+  std::vector<uint64_t> pid_;
+  std::vector<std::string> target_installed_by_;
+  ::protozero::CopyablePtr<JavaHprofConfig_ContinuousDumpConfig> continuous_dump_config_;
+  uint32_t min_anonymous_memory_kb_{};
+  bool dump_smaps_{};
+  std::vector<std::string> ignored_types_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT JavaHprofConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDumpPhaseMsFieldNumber = 1,
+    kDumpIntervalMsFieldNumber = 2,
+    kScanPidsOnlyOnStartFieldNumber = 3,
+  };
+
+  JavaHprofConfig_ContinuousDumpConfig();
+  ~JavaHprofConfig_ContinuousDumpConfig() override;
+  JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept;
+  JavaHprofConfig_ContinuousDumpConfig& operator=(JavaHprofConfig_ContinuousDumpConfig&&);
+  JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&);
+  JavaHprofConfig_ContinuousDumpConfig& operator=(const JavaHprofConfig_ContinuousDumpConfig&);
+  bool operator==(const JavaHprofConfig_ContinuousDumpConfig&) const;
+  bool operator!=(const JavaHprofConfig_ContinuousDumpConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_dump_phase_ms() const { return _has_field_[1]; }
+  uint32_t dump_phase_ms() const { return dump_phase_ms_; }
+  void set_dump_phase_ms(uint32_t value) { dump_phase_ms_ = value; _has_field_.set(1); }
+
+  bool has_dump_interval_ms() const { return _has_field_[2]; }
+  uint32_t dump_interval_ms() const { return dump_interval_ms_; }
+  void set_dump_interval_ms(uint32_t value) { dump_interval_ms_ = value; _has_field_.set(2); }
+
+  bool has_scan_pids_only_on_start() const { return _has_field_[3]; }
+  bool scan_pids_only_on_start() const { return scan_pids_only_on_start_; }
+  void set_scan_pids_only_on_start(bool value) { scan_pids_only_on_start_ = value; _has_field_.set(3); }
+
+ private:
+  uint32_t dump_phase_ms_{};
+  uint32_t dump_interval_ms_{};
+  bool scan_pids_only_on_start_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/perf_event_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class PerfEventConfig;
+class PerfEventConfig_CallstackSampling;
+class PerfEventConfig_Scope;
+class PerfEvents_Timebase;
+class PerfEvents_RawEvent;
+class PerfEvents_Tracepoint;
+enum PerfEventConfig_UnwindMode : int;
+enum PerfEvents_Counter : int;
+enum PerfEvents_PerfClock : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum PerfEventConfig_UnwindMode : int {
+  PerfEventConfig_UnwindMode_UNWIND_UNKNOWN = 0,
+  PerfEventConfig_UnwindMode_UNWIND_SKIP = 1,
+  PerfEventConfig_UnwindMode_UNWIND_DWARF = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT PerfEventConfig : public ::protozero::CppMessageObj {
+ public:
+  using CallstackSampling = PerfEventConfig_CallstackSampling;
+  using Scope = PerfEventConfig_Scope;
+  using UnwindMode = PerfEventConfig_UnwindMode;
+  static constexpr auto UNWIND_UNKNOWN = PerfEventConfig_UnwindMode_UNWIND_UNKNOWN;
+  static constexpr auto UNWIND_SKIP = PerfEventConfig_UnwindMode_UNWIND_SKIP;
+  static constexpr auto UNWIND_DWARF = PerfEventConfig_UnwindMode_UNWIND_DWARF;
+  static constexpr auto UnwindMode_MIN = PerfEventConfig_UnwindMode_UNWIND_UNKNOWN;
+  static constexpr auto UnwindMode_MAX = PerfEventConfig_UnwindMode_UNWIND_DWARF;
+  enum FieldNumbers {
+    kTimebaseFieldNumber = 15,
+    kCallstackSamplingFieldNumber = 16,
+    kRingBufferReadPeriodMsFieldNumber = 8,
+    kRingBufferPagesFieldNumber = 3,
+    kMaxEnqueuedFootprintKbFieldNumber = 17,
+    kMaxDaemonMemoryKbFieldNumber = 13,
+    kRemoteDescriptorTimeoutMsFieldNumber = 9,
+    kUnwindStateClearPeriodMsFieldNumber = 10,
+    kTargetInstalledByFieldNumber = 18,
+    kAllCpusFieldNumber = 1,
+    kSamplingFrequencyFieldNumber = 2,
+    kKernelFramesFieldNumber = 12,
+    kTargetPidFieldNumber = 4,
+    kTargetCmdlineFieldNumber = 5,
+    kExcludePidFieldNumber = 6,
+    kExcludeCmdlineFieldNumber = 7,
+    kAdditionalCmdlineCountFieldNumber = 11,
+  };
+
+  PerfEventConfig();
+  ~PerfEventConfig() override;
+  PerfEventConfig(PerfEventConfig&&) noexcept;
+  PerfEventConfig& operator=(PerfEventConfig&&);
+  PerfEventConfig(const PerfEventConfig&);
+  PerfEventConfig& operator=(const PerfEventConfig&);
+  bool operator==(const PerfEventConfig&) const;
+  bool operator!=(const PerfEventConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_timebase() const { return _has_field_[15]; }
+  const PerfEvents_Timebase& timebase() const { return *timebase_; }
+  PerfEvents_Timebase* mutable_timebase() { _has_field_.set(15); return timebase_.get(); }
+
+  bool has_callstack_sampling() const { return _has_field_[16]; }
+  const PerfEventConfig_CallstackSampling& callstack_sampling() const { return *callstack_sampling_; }
+  PerfEventConfig_CallstackSampling* mutable_callstack_sampling() { _has_field_.set(16); return callstack_sampling_.get(); }
+
+  bool has_ring_buffer_read_period_ms() const { return _has_field_[8]; }
+  uint32_t ring_buffer_read_period_ms() const { return ring_buffer_read_period_ms_; }
+  void set_ring_buffer_read_period_ms(uint32_t value) { ring_buffer_read_period_ms_ = value; _has_field_.set(8); }
+
+  bool has_ring_buffer_pages() const { return _has_field_[3]; }
+  uint32_t ring_buffer_pages() const { return ring_buffer_pages_; }
+  void set_ring_buffer_pages(uint32_t value) { ring_buffer_pages_ = value; _has_field_.set(3); }
+
+  bool has_max_enqueued_footprint_kb() const { return _has_field_[17]; }
+  uint64_t max_enqueued_footprint_kb() const { return max_enqueued_footprint_kb_; }
+  void set_max_enqueued_footprint_kb(uint64_t value) { max_enqueued_footprint_kb_ = value; _has_field_.set(17); }
+
+  bool has_max_daemon_memory_kb() const { return _has_field_[13]; }
+  uint32_t max_daemon_memory_kb() const { return max_daemon_memory_kb_; }
+  void set_max_daemon_memory_kb(uint32_t value) { max_daemon_memory_kb_ = value; _has_field_.set(13); }
+
+  bool has_remote_descriptor_timeout_ms() const { return _has_field_[9]; }
+  uint32_t remote_descriptor_timeout_ms() const { return remote_descriptor_timeout_ms_; }
+  void set_remote_descriptor_timeout_ms(uint32_t value) { remote_descriptor_timeout_ms_ = value; _has_field_.set(9); }
+
+  bool has_unwind_state_clear_period_ms() const { return _has_field_[10]; }
+  uint32_t unwind_state_clear_period_ms() const { return unwind_state_clear_period_ms_; }
+  void set_unwind_state_clear_period_ms(uint32_t value) { unwind_state_clear_period_ms_ = value; _has_field_.set(10); }
+
+  const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
+  std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
+  int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
+  void clear_target_installed_by() { target_installed_by_.clear(); }
+  void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
+  std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
+
+  bool has_all_cpus() const { return _has_field_[1]; }
+  bool all_cpus() const { return all_cpus_; }
+  void set_all_cpus(bool value) { all_cpus_ = value; _has_field_.set(1); }
+
+  bool has_sampling_frequency() const { return _has_field_[2]; }
+  uint32_t sampling_frequency() const { return sampling_frequency_; }
+  void set_sampling_frequency(uint32_t value) { sampling_frequency_ = value; _has_field_.set(2); }
+
+  bool has_kernel_frames() const { return _has_field_[12]; }
+  bool kernel_frames() const { return kernel_frames_; }
+  void set_kernel_frames(bool value) { kernel_frames_ = value; _has_field_.set(12); }
+
+  const std::vector<int32_t>& target_pid() const { return target_pid_; }
+  std::vector<int32_t>* mutable_target_pid() { return &target_pid_; }
+  int target_pid_size() const { return static_cast<int>(target_pid_.size()); }
+  void clear_target_pid() { target_pid_.clear(); }
+  void add_target_pid(int32_t value) { target_pid_.emplace_back(value); }
+  int32_t* add_target_pid() { target_pid_.emplace_back(); return &target_pid_.back(); }
+
+  const std::vector<std::string>& target_cmdline() const { return target_cmdline_; }
+  std::vector<std::string>* mutable_target_cmdline() { return &target_cmdline_; }
+  int target_cmdline_size() const { return static_cast<int>(target_cmdline_.size()); }
+  void clear_target_cmdline() { target_cmdline_.clear(); }
+  void add_target_cmdline(std::string value) { target_cmdline_.emplace_back(value); }
+  std::string* add_target_cmdline() { target_cmdline_.emplace_back(); return &target_cmdline_.back(); }
+
+  const std::vector<int32_t>& exclude_pid() const { return exclude_pid_; }
+  std::vector<int32_t>* mutable_exclude_pid() { return &exclude_pid_; }
+  int exclude_pid_size() const { return static_cast<int>(exclude_pid_.size()); }
+  void clear_exclude_pid() { exclude_pid_.clear(); }
+  void add_exclude_pid(int32_t value) { exclude_pid_.emplace_back(value); }
+  int32_t* add_exclude_pid() { exclude_pid_.emplace_back(); return &exclude_pid_.back(); }
+
+  const std::vector<std::string>& exclude_cmdline() const { return exclude_cmdline_; }
+  std::vector<std::string>* mutable_exclude_cmdline() { return &exclude_cmdline_; }
+  int exclude_cmdline_size() const { return static_cast<int>(exclude_cmdline_.size()); }
+  void clear_exclude_cmdline() { exclude_cmdline_.clear(); }
+  void add_exclude_cmdline(std::string value) { exclude_cmdline_.emplace_back(value); }
+  std::string* add_exclude_cmdline() { exclude_cmdline_.emplace_back(); return &exclude_cmdline_.back(); }
+
+  bool has_additional_cmdline_count() const { return _has_field_[11]; }
+  uint32_t additional_cmdline_count() const { return additional_cmdline_count_; }
+  void set_additional_cmdline_count(uint32_t value) { additional_cmdline_count_ = value; _has_field_.set(11); }
+
+ private:
+  ::protozero::CopyablePtr<PerfEvents_Timebase> timebase_;
+  ::protozero::CopyablePtr<PerfEventConfig_CallstackSampling> callstack_sampling_;
+  uint32_t ring_buffer_read_period_ms_{};
+  uint32_t ring_buffer_pages_{};
+  uint64_t max_enqueued_footprint_kb_{};
+  uint32_t max_daemon_memory_kb_{};
+  uint32_t remote_descriptor_timeout_ms_{};
+  uint32_t unwind_state_clear_period_ms_{};
+  std::vector<std::string> target_installed_by_;
+  bool all_cpus_{};
+  uint32_t sampling_frequency_{};
+  bool kernel_frames_{};
+  std::vector<int32_t> target_pid_;
+  std::vector<std::string> target_cmdline_;
+  std::vector<int32_t> exclude_pid_;
+  std::vector<std::string> exclude_cmdline_;
+  uint32_t additional_cmdline_count_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<19> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT PerfEventConfig_CallstackSampling : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kScopeFieldNumber = 1,
+    kKernelFramesFieldNumber = 2,
+    kUserFramesFieldNumber = 3,
+  };
+
+  PerfEventConfig_CallstackSampling();
+  ~PerfEventConfig_CallstackSampling() override;
+  PerfEventConfig_CallstackSampling(PerfEventConfig_CallstackSampling&&) noexcept;
+  PerfEventConfig_CallstackSampling& operator=(PerfEventConfig_CallstackSampling&&);
+  PerfEventConfig_CallstackSampling(const PerfEventConfig_CallstackSampling&);
+  PerfEventConfig_CallstackSampling& operator=(const PerfEventConfig_CallstackSampling&);
+  bool operator==(const PerfEventConfig_CallstackSampling&) const;
+  bool operator!=(const PerfEventConfig_CallstackSampling& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_scope() const { return _has_field_[1]; }
+  const PerfEventConfig_Scope& scope() const { return *scope_; }
+  PerfEventConfig_Scope* mutable_scope() { _has_field_.set(1); return scope_.get(); }
+
+  bool has_kernel_frames() const { return _has_field_[2]; }
+  bool kernel_frames() const { return kernel_frames_; }
+  void set_kernel_frames(bool value) { kernel_frames_ = value; _has_field_.set(2); }
+
+  bool has_user_frames() const { return _has_field_[3]; }
+  PerfEventConfig_UnwindMode user_frames() const { return user_frames_; }
+  void set_user_frames(PerfEventConfig_UnwindMode value) { user_frames_ = value; _has_field_.set(3); }
+
+ private:
+  ::protozero::CopyablePtr<PerfEventConfig_Scope> scope_;
+  bool kernel_frames_{};
+  PerfEventConfig_UnwindMode user_frames_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT PerfEventConfig_Scope : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTargetPidFieldNumber = 1,
+    kTargetCmdlineFieldNumber = 2,
+    kExcludePidFieldNumber = 3,
+    kExcludeCmdlineFieldNumber = 4,
+    kAdditionalCmdlineCountFieldNumber = 5,
+    kProcessShardCountFieldNumber = 6,
+  };
+
+  PerfEventConfig_Scope();
+  ~PerfEventConfig_Scope() override;
+  PerfEventConfig_Scope(PerfEventConfig_Scope&&) noexcept;
+  PerfEventConfig_Scope& operator=(PerfEventConfig_Scope&&);
+  PerfEventConfig_Scope(const PerfEventConfig_Scope&);
+  PerfEventConfig_Scope& operator=(const PerfEventConfig_Scope&);
+  bool operator==(const PerfEventConfig_Scope&) const;
+  bool operator!=(const PerfEventConfig_Scope& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<int32_t>& target_pid() const { return target_pid_; }
+  std::vector<int32_t>* mutable_target_pid() { return &target_pid_; }
+  int target_pid_size() const { return static_cast<int>(target_pid_.size()); }
+  void clear_target_pid() { target_pid_.clear(); }
+  void add_target_pid(int32_t value) { target_pid_.emplace_back(value); }
+  int32_t* add_target_pid() { target_pid_.emplace_back(); return &target_pid_.back(); }
+
+  const std::vector<std::string>& target_cmdline() const { return target_cmdline_; }
+  std::vector<std::string>* mutable_target_cmdline() { return &target_cmdline_; }
+  int target_cmdline_size() const { return static_cast<int>(target_cmdline_.size()); }
+  void clear_target_cmdline() { target_cmdline_.clear(); }
+  void add_target_cmdline(std::string value) { target_cmdline_.emplace_back(value); }
+  std::string* add_target_cmdline() { target_cmdline_.emplace_back(); return &target_cmdline_.back(); }
+
+  const std::vector<int32_t>& exclude_pid() const { return exclude_pid_; }
+  std::vector<int32_t>* mutable_exclude_pid() { return &exclude_pid_; }
+  int exclude_pid_size() const { return static_cast<int>(exclude_pid_.size()); }
+  void clear_exclude_pid() { exclude_pid_.clear(); }
+  void add_exclude_pid(int32_t value) { exclude_pid_.emplace_back(value); }
+  int32_t* add_exclude_pid() { exclude_pid_.emplace_back(); return &exclude_pid_.back(); }
+
+  const std::vector<std::string>& exclude_cmdline() const { return exclude_cmdline_; }
+  std::vector<std::string>* mutable_exclude_cmdline() { return &exclude_cmdline_; }
+  int exclude_cmdline_size() const { return static_cast<int>(exclude_cmdline_.size()); }
+  void clear_exclude_cmdline() { exclude_cmdline_.clear(); }
+  void add_exclude_cmdline(std::string value) { exclude_cmdline_.emplace_back(value); }
+  std::string* add_exclude_cmdline() { exclude_cmdline_.emplace_back(); return &exclude_cmdline_.back(); }
+
+  bool has_additional_cmdline_count() const { return _has_field_[5]; }
+  uint32_t additional_cmdline_count() const { return additional_cmdline_count_; }
+  void set_additional_cmdline_count(uint32_t value) { additional_cmdline_count_ = value; _has_field_.set(5); }
+
+  bool has_process_shard_count() const { return _has_field_[6]; }
+  uint32_t process_shard_count() const { return process_shard_count_; }
+  void set_process_shard_count(uint32_t value) { process_shard_count_ = value; _has_field_.set(6); }
+
+ private:
+  std::vector<int32_t> target_pid_;
+  std::vector<std::string> target_cmdline_;
+  std::vector<int32_t> exclude_pid_;
+  std::vector<std::string> exclude_cmdline_;
+  uint32_t additional_cmdline_count_{};
+  uint32_t process_shard_count_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/statsd/atom_ids.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AtomId : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum AtomId : int {
+  ATOM_UNSPECIFIED = 0,
+  ATOM_BLE_SCAN_STATE_CHANGED = 2,
+  ATOM_PROCESS_STATE_CHANGED = 3,
+  ATOM_BLE_SCAN_RESULT_RECEIVED = 4,
+  ATOM_SENSOR_STATE_CHANGED = 5,
+  ATOM_GPS_SCAN_STATE_CHANGED = 6,
+  ATOM_SYNC_STATE_CHANGED = 7,
+  ATOM_SCHEDULED_JOB_STATE_CHANGED = 8,
+  ATOM_SCREEN_BRIGHTNESS_CHANGED = 9,
+  ATOM_WAKELOCK_STATE_CHANGED = 10,
+  ATOM_LONG_PARTIAL_WAKELOCK_STATE_CHANGED = 11,
+  ATOM_MOBILE_RADIO_POWER_STATE_CHANGED = 12,
+  ATOM_WIFI_RADIO_POWER_STATE_CHANGED = 13,
+  ATOM_ACTIVITY_MANAGER_SLEEP_STATE_CHANGED = 14,
+  ATOM_MEMORY_FACTOR_STATE_CHANGED = 15,
+  ATOM_EXCESSIVE_CPU_USAGE_REPORTED = 16,
+  ATOM_CACHED_KILL_REPORTED = 17,
+  ATOM_PROCESS_MEMORY_STAT_REPORTED = 18,
+  ATOM_LAUNCHER_EVENT = 19,
+  ATOM_BATTERY_SAVER_MODE_STATE_CHANGED = 20,
+  ATOM_DEVICE_IDLE_MODE_STATE_CHANGED = 21,
+  ATOM_DEVICE_IDLING_MODE_STATE_CHANGED = 22,
+  ATOM_AUDIO_STATE_CHANGED = 23,
+  ATOM_MEDIA_CODEC_STATE_CHANGED = 24,
+  ATOM_CAMERA_STATE_CHANGED = 25,
+  ATOM_FLASHLIGHT_STATE_CHANGED = 26,
+  ATOM_UID_PROCESS_STATE_CHANGED = 27,
+  ATOM_PROCESS_LIFE_CYCLE_STATE_CHANGED = 28,
+  ATOM_SCREEN_STATE_CHANGED = 29,
+  ATOM_BATTERY_LEVEL_CHANGED = 30,
+  ATOM_CHARGING_STATE_CHANGED = 31,
+  ATOM_PLUGGED_STATE_CHANGED = 32,
+  ATOM_INTERACTIVE_STATE_CHANGED = 33,
+  ATOM_TOUCH_EVENT_REPORTED = 34,
+  ATOM_WAKEUP_ALARM_OCCURRED = 35,
+  ATOM_KERNEL_WAKEUP_REPORTED = 36,
+  ATOM_WIFI_LOCK_STATE_CHANGED = 37,
+  ATOM_WIFI_SIGNAL_STRENGTH_CHANGED = 38,
+  ATOM_WIFI_SCAN_STATE_CHANGED = 39,
+  ATOM_PHONE_SIGNAL_STRENGTH_CHANGED = 40,
+  ATOM_SETTING_CHANGED = 41,
+  ATOM_ACTIVITY_FOREGROUND_STATE_CHANGED = 42,
+  ATOM_ISOLATED_UID_CHANGED = 43,
+  ATOM_PACKET_WAKEUP_OCCURRED = 44,
+  ATOM_WALL_CLOCK_TIME_SHIFTED = 45,
+  ATOM_ANOMALY_DETECTED = 46,
+  ATOM_APP_BREADCRUMB_REPORTED = 47,
+  ATOM_APP_START_OCCURRED = 48,
+  ATOM_APP_START_CANCELED = 49,
+  ATOM_APP_START_FULLY_DRAWN = 50,
+  ATOM_LMK_KILL_OCCURRED = 51,
+  ATOM_PICTURE_IN_PICTURE_STATE_CHANGED = 52,
+  ATOM_WIFI_MULTICAST_LOCK_STATE_CHANGED = 53,
+  ATOM_LMK_STATE_CHANGED = 54,
+  ATOM_APP_START_MEMORY_STATE_CAPTURED = 55,
+  ATOM_SHUTDOWN_SEQUENCE_REPORTED = 56,
+  ATOM_BOOT_SEQUENCE_REPORTED = 57,
+  ATOM_DAVEY_OCCURRED = 58,
+  ATOM_OVERLAY_STATE_CHANGED = 59,
+  ATOM_FOREGROUND_SERVICE_STATE_CHANGED = 60,
+  ATOM_CALL_STATE_CHANGED = 61,
+  ATOM_KEYGUARD_STATE_CHANGED = 62,
+  ATOM_KEYGUARD_BOUNCER_STATE_CHANGED = 63,
+  ATOM_KEYGUARD_BOUNCER_PASSWORD_ENTERED = 64,
+  ATOM_APP_DIED = 65,
+  ATOM_RESOURCE_CONFIGURATION_CHANGED = 66,
+  ATOM_BLUETOOTH_ENABLED_STATE_CHANGED = 67,
+  ATOM_BLUETOOTH_CONNECTION_STATE_CHANGED = 68,
+  ATOM_GPS_SIGNAL_QUALITY_CHANGED = 69,
+  ATOM_USB_CONNECTOR_STATE_CHANGED = 70,
+  ATOM_SPEAKER_IMPEDANCE_REPORTED = 71,
+  ATOM_HARDWARE_FAILED = 72,
+  ATOM_PHYSICAL_DROP_DETECTED = 73,
+  ATOM_CHARGE_CYCLES_REPORTED = 74,
+  ATOM_MOBILE_CONNECTION_STATE_CHANGED = 75,
+  ATOM_MOBILE_RADIO_TECHNOLOGY_CHANGED = 76,
+  ATOM_USB_DEVICE_ATTACHED = 77,
+  ATOM_APP_CRASH_OCCURRED = 78,
+  ATOM_ANR_OCCURRED = 79,
+  ATOM_WTF_OCCURRED = 80,
+  ATOM_LOW_MEM_REPORTED = 81,
+  ATOM_GENERIC_ATOM = 82,
+  ATOM_VIBRATOR_STATE_CHANGED = 84,
+  ATOM_DEFERRED_JOB_STATS_REPORTED = 85,
+  ATOM_THERMAL_THROTTLING = 86,
+  ATOM_BIOMETRIC_ACQUIRED = 87,
+  ATOM_BIOMETRIC_AUTHENTICATED = 88,
+  ATOM_BIOMETRIC_ERROR_OCCURRED = 89,
+  ATOM_UI_EVENT_REPORTED = 90,
+  ATOM_BATTERY_HEALTH_SNAPSHOT = 91,
+  ATOM_SLOW_IO = 92,
+  ATOM_BATTERY_CAUSED_SHUTDOWN = 93,
+  ATOM_PHONE_SERVICE_STATE_CHANGED = 94,
+  ATOM_PHONE_STATE_CHANGED = 95,
+  ATOM_USER_RESTRICTION_CHANGED = 96,
+  ATOM_SETTINGS_UI_CHANGED = 97,
+  ATOM_CONNECTIVITY_STATE_CHANGED = 98,
+  ATOM_SERVICE_STATE_CHANGED = 99,
+  ATOM_SERVICE_LAUNCH_REPORTED = 100,
+  ATOM_FLAG_FLIP_UPDATE_OCCURRED = 101,
+  ATOM_BINARY_PUSH_STATE_CHANGED = 102,
+  ATOM_DEVICE_POLICY_EVENT = 103,
+  ATOM_DOCS_UI_FILE_OP_CANCELED = 104,
+  ATOM_DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED = 105,
+  ATOM_DOCS_UI_FILE_OP_FAILURE = 106,
+  ATOM_DOCS_UI_PROVIDER_FILE_OP = 107,
+  ATOM_DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST = 108,
+  ATOM_DOCS_UI_LAUNCH_REPORTED = 109,
+  ATOM_DOCS_UI_ROOT_VISITED = 110,
+  ATOM_DOCS_UI_STARTUP_MS = 111,
+  ATOM_DOCS_UI_USER_ACTION_REPORTED = 112,
+  ATOM_WIFI_ENABLED_STATE_CHANGED = 113,
+  ATOM_WIFI_RUNNING_STATE_CHANGED = 114,
+  ATOM_APP_COMPACTED = 115,
+  ATOM_NETWORK_DNS_EVENT_REPORTED = 116,
+  ATOM_DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED = 117,
+  ATOM_DOCS_UI_PICK_RESULT_REPORTED = 118,
+  ATOM_DOCS_UI_SEARCH_MODE_REPORTED = 119,
+  ATOM_DOCS_UI_SEARCH_TYPE_REPORTED = 120,
+  ATOM_DATA_STALL_EVENT = 121,
+  ATOM_RESCUE_PARTY_RESET_REPORTED = 122,
+  ATOM_SIGNED_CONFIG_REPORTED = 123,
+  ATOM_GNSS_NI_EVENT_REPORTED = 124,
+  ATOM_BLUETOOTH_LINK_LAYER_CONNECTION_EVENT = 125,
+  ATOM_BLUETOOTH_ACL_CONNECTION_STATE_CHANGED = 126,
+  ATOM_BLUETOOTH_SCO_CONNECTION_STATE_CHANGED = 127,
+  ATOM_APP_DOWNGRADED = 128,
+  ATOM_APP_OPTIMIZED_AFTER_DOWNGRADED = 129,
+  ATOM_LOW_STORAGE_STATE_CHANGED = 130,
+  ATOM_GNSS_NFW_NOTIFICATION_REPORTED = 131,
+  ATOM_GNSS_CONFIGURATION_REPORTED = 132,
+  ATOM_USB_PORT_OVERHEAT_EVENT_REPORTED = 133,
+  ATOM_NFC_ERROR_OCCURRED = 134,
+  ATOM_NFC_STATE_CHANGED = 135,
+  ATOM_NFC_BEAM_OCCURRED = 136,
+  ATOM_NFC_CARDEMULATION_OCCURRED = 137,
+  ATOM_NFC_TAG_OCCURRED = 138,
+  ATOM_NFC_HCE_TRANSACTION_OCCURRED = 139,
+  ATOM_SE_STATE_CHANGED = 140,
+  ATOM_SE_OMAPI_REPORTED = 141,
+  ATOM_BROADCAST_DISPATCH_LATENCY_REPORTED = 142,
+  ATOM_ATTENTION_MANAGER_SERVICE_RESULT_REPORTED = 143,
+  ATOM_ADB_CONNECTION_CHANGED = 144,
+  ATOM_SPEECH_DSP_STAT_REPORTED = 145,
+  ATOM_USB_CONTAMINANT_REPORTED = 146,
+  ATOM_WATCHDOG_ROLLBACK_OCCURRED = 147,
+  ATOM_BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED = 148,
+  ATOM_BUBBLE_UI_CHANGED = 149,
+  ATOM_SCHEDULED_JOB_CONSTRAINT_CHANGED = 150,
+  ATOM_BLUETOOTH_ACTIVE_DEVICE_CHANGED = 151,
+  ATOM_BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED = 152,
+  ATOM_BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED = 153,
+  ATOM_BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED = 154,
+  ATOM_BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED = 155,
+  ATOM_BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED = 156,
+  ATOM_BLUETOOTH_DEVICE_RSSI_REPORTED = 157,
+  ATOM_BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED = 158,
+  ATOM_BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED = 159,
+  ATOM_BLUETOOTH_HCI_TIMEOUT_REPORTED = 160,
+  ATOM_BLUETOOTH_QUALITY_REPORT_REPORTED = 161,
+  ATOM_BLUETOOTH_DEVICE_INFO_REPORTED = 162,
+  ATOM_BLUETOOTH_REMOTE_VERSION_INFO_REPORTED = 163,
+  ATOM_BLUETOOTH_SDP_ATTRIBUTE_REPORTED = 164,
+  ATOM_BLUETOOTH_BOND_STATE_CHANGED = 165,
+  ATOM_BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED = 166,
+  ATOM_BLUETOOTH_SMP_PAIRING_EVENT_REPORTED = 167,
+  ATOM_SCREEN_TIMEOUT_EXTENSION_REPORTED = 168,
+  ATOM_PROCESS_START_TIME = 169,
+  ATOM_PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170,
+  ATOM_BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED = 171,
+  ATOM_DEVICE_IDENTIFIER_ACCESS_DENIED = 172,
+  ATOM_BUBBLE_DEVELOPER_ERROR_REPORTED = 173,
+  ATOM_ASSIST_GESTURE_STAGE_REPORTED = 174,
+  ATOM_ASSIST_GESTURE_FEEDBACK_REPORTED = 175,
+  ATOM_ASSIST_GESTURE_PROGRESS_REPORTED = 176,
+  ATOM_TOUCH_GESTURE_CLASSIFIED = 177,
+  ATOM_HIDDEN_API_USED = 178,
+  ATOM_STYLE_UI_CHANGED = 179,
+  ATOM_PRIVACY_INDICATORS_INTERACTED = 180,
+  ATOM_APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED = 181,
+  ATOM_NETWORK_STACK_REPORTED = 182,
+  ATOM_APP_MOVED_STORAGE_REPORTED = 183,
+  ATOM_BIOMETRIC_ENROLLED = 184,
+  ATOM_SYSTEM_SERVER_WATCHDOG_OCCURRED = 185,
+  ATOM_TOMB_STONE_OCCURRED = 186,
+  ATOM_BLUETOOTH_CLASS_OF_DEVICE_REPORTED = 187,
+  ATOM_INTELLIGENCE_EVENT_REPORTED = 188,
+  ATOM_THERMAL_THROTTLING_SEVERITY_STATE_CHANGED = 189,
+  ATOM_ROLE_REQUEST_RESULT_REPORTED = 190,
+  ATOM_MEDIAMETRICS_AUDIOPOLICY_REPORTED = 191,
+  ATOM_MEDIAMETRICS_AUDIORECORD_REPORTED = 192,
+  ATOM_MEDIAMETRICS_AUDIOTHREAD_REPORTED = 193,
+  ATOM_MEDIAMETRICS_AUDIOTRACK_REPORTED = 194,
+  ATOM_MEDIAMETRICS_CODEC_REPORTED = 195,
+  ATOM_MEDIAMETRICS_DRM_WIDEVINE_REPORTED = 196,
+  ATOM_MEDIAMETRICS_EXTRACTOR_REPORTED = 197,
+  ATOM_MEDIAMETRICS_MEDIADRM_REPORTED = 198,
+  ATOM_MEDIAMETRICS_NUPLAYER_REPORTED = 199,
+  ATOM_MEDIAMETRICS_RECORDER_REPORTED = 200,
+  ATOM_MEDIAMETRICS_DRMMANAGER_REPORTED = 201,
+  ATOM_CAR_POWER_STATE_CHANGED = 203,
+  ATOM_GARAGE_MODE_INFO = 204,
+  ATOM_TEST_ATOM_REPORTED = 205,
+  ATOM_CONTENT_CAPTURE_CALLER_MISMATCH_REPORTED = 206,
+  ATOM_CONTENT_CAPTURE_SERVICE_EVENTS = 207,
+  ATOM_CONTENT_CAPTURE_SESSION_EVENTS = 208,
+  ATOM_CONTENT_CAPTURE_FLUSHED = 209,
+  ATOM_LOCATION_MANAGER_API_USAGE_REPORTED = 210,
+  ATOM_REVIEW_PERMISSIONS_FRAGMENT_RESULT_REPORTED = 211,
+  ATOM_RUNTIME_PERMISSIONS_UPGRADE_RESULT = 212,
+  ATOM_GRANT_PERMISSIONS_ACTIVITY_BUTTON_ACTIONS = 213,
+  ATOM_LOCATION_ACCESS_CHECK_NOTIFICATION_ACTION = 214,
+  ATOM_APP_PERMISSION_FRAGMENT_ACTION_REPORTED = 215,
+  ATOM_APP_PERMISSION_FRAGMENT_VIEWED = 216,
+  ATOM_APP_PERMISSIONS_FRAGMENT_VIEWED = 217,
+  ATOM_PERMISSION_APPS_FRAGMENT_VIEWED = 218,
+  ATOM_TEXT_SELECTION_EVENT = 219,
+  ATOM_TEXT_LINKIFY_EVENT = 220,
+  ATOM_CONVERSATION_ACTIONS_EVENT = 221,
+  ATOM_LANGUAGE_DETECTION_EVENT = 222,
+  ATOM_EXCLUSION_RECT_STATE_CHANGED = 223,
+  ATOM_BACK_GESTURE_REPORTED_REPORTED = 224,
+  ATOM_UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED = 225,
+  ATOM_UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED = 226,
+  ATOM_CAMERA_ACTION_EVENT = 227,
+  ATOM_APP_COMPATIBILITY_CHANGE_REPORTED = 228,
+  ATOM_PERFETTO_UPLOADED = 229,
+  ATOM_VMS_CLIENT_CONNECTION_STATE_CHANGED = 230,
+  ATOM_MEDIA_PROVIDER_SCAN_OCCURRED = 233,
+  ATOM_MEDIA_CONTENT_DELETED = 234,
+  ATOM_MEDIA_PROVIDER_PERMISSION_REQUESTED = 235,
+  ATOM_MEDIA_PROVIDER_SCHEMA_CHANGED = 236,
+  ATOM_MEDIA_PROVIDER_IDLE_MAINTENANCE_FINISHED = 237,
+  ATOM_REBOOT_ESCROW_RECOVERY_REPORTED = 238,
+  ATOM_BOOT_TIME_EVENT_DURATION_REPORTED = 239,
+  ATOM_BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED = 240,
+  ATOM_BOOT_TIME_EVENT_UTC_TIME_REPORTED = 241,
+  ATOM_BOOT_TIME_EVENT_ERROR_CODE_REPORTED = 242,
+  ATOM_USERSPACE_REBOOT_REPORTED = 243,
+  ATOM_NOTIFICATION_REPORTED = 244,
+  ATOM_NOTIFICATION_PANEL_REPORTED = 245,
+  ATOM_NOTIFICATION_CHANNEL_MODIFIED = 246,
+  ATOM_INTEGRITY_CHECK_RESULT_REPORTED = 247,
+  ATOM_INTEGRITY_RULES_PUSHED = 248,
+  ATOM_CB_MESSAGE_REPORTED = 249,
+  ATOM_CB_MESSAGE_ERROR = 250,
+  ATOM_WIFI_HEALTH_STAT_REPORTED = 251,
+  ATOM_WIFI_FAILURE_STAT_REPORTED = 252,
+  ATOM_WIFI_CONNECTION_RESULT_REPORTED = 253,
+  ATOM_APP_FREEZE_CHANGED = 254,
+  ATOM_SNAPSHOT_MERGE_REPORTED = 255,
+  ATOM_FOREGROUND_SERVICE_APP_OP_SESSION_ENDED = 256,
+  ATOM_DISPLAY_JANK_REPORTED = 257,
+  ATOM_APP_STANDBY_BUCKET_CHANGED = 258,
+  ATOM_SHARESHEET_STARTED = 259,
+  ATOM_RANKING_SELECTED = 260,
+  ATOM_TVSETTINGS_UI_INTERACTED = 261,
+  ATOM_LAUNCHER_SNAPSHOT = 262,
+  ATOM_PACKAGE_INSTALLER_V2_REPORTED = 263,
+  ATOM_USER_LIFECYCLE_JOURNEY_REPORTED = 264,
+  ATOM_USER_LIFECYCLE_EVENT_OCCURRED = 265,
+  ATOM_ACCESSIBILITY_SHORTCUT_REPORTED = 266,
+  ATOM_ACCESSIBILITY_SERVICE_REPORTED = 267,
+  ATOM_DOCS_UI_DRAG_AND_DROP_REPORTED = 268,
+  ATOM_APP_USAGE_EVENT_OCCURRED = 269,
+  ATOM_AUTO_REVOKE_NOTIFICATION_CLICKED = 270,
+  ATOM_AUTO_REVOKE_FRAGMENT_APP_VIEWED = 271,
+  ATOM_AUTO_REVOKED_APP_INTERACTION = 272,
+  ATOM_APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION = 273,
+  ATOM_EVS_USAGE_STATS_REPORTED = 274,
+  ATOM_AUDIO_POWER_USAGE_DATA_REPORTED = 275,
+  ATOM_TV_TUNER_STATE_CHANGED = 276,
+  ATOM_MEDIAOUTPUT_OP_SWITCH_REPORTED = 277,
+  ATOM_CB_MESSAGE_FILTERED = 278,
+  ATOM_TV_TUNER_DVR_STATUS = 279,
+  ATOM_TV_CAS_SESSION_OPEN_STATUS = 280,
+  ATOM_ASSISTANT_INVOCATION_REPORTED = 281,
+  ATOM_DISPLAY_WAKE_REPORTED = 282,
+  ATOM_CAR_USER_HAL_MODIFY_USER_REQUEST_REPORTED = 283,
+  ATOM_CAR_USER_HAL_MODIFY_USER_RESPONSE_REPORTED = 284,
+  ATOM_CAR_USER_HAL_POST_SWITCH_RESPONSE_REPORTED = 285,
+  ATOM_CAR_USER_HAL_INITIAL_USER_INFO_REQUEST_REPORTED = 286,
+  ATOM_CAR_USER_HAL_INITIAL_USER_INFO_RESPONSE_REPORTED = 287,
+  ATOM_CAR_USER_HAL_USER_ASSOCIATION_REQUEST_REPORTED = 288,
+  ATOM_CAR_USER_HAL_SET_USER_ASSOCIATION_RESPONSE_REPORTED = 289,
+  ATOM_NETWORK_IP_PROVISIONING_REPORTED = 290,
+  ATOM_NETWORK_DHCP_RENEW_REPORTED = 291,
+  ATOM_NETWORK_VALIDATION_REPORTED = 292,
+  ATOM_NETWORK_STACK_QUIRK_REPORTED = 293,
+  ATOM_MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED = 294,
+  ATOM_MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED = 295,
+  ATOM_MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED = 296,
+  ATOM_MEDIAMETRICS_AUDIODEVICECONNECTION_REPORTED = 297,
+  ATOM_BLOB_COMMITTED = 298,
+  ATOM_BLOB_LEASED = 299,
+  ATOM_BLOB_OPENED = 300,
+  ATOM_CONTACTS_PROVIDER_STATUS_REPORTED = 301,
+  ATOM_KEYSTORE_KEY_EVENT_REPORTED = 302,
+  ATOM_NETWORK_TETHERING_REPORTED = 303,
+  ATOM_IME_TOUCH_REPORTED = 304,
+  ATOM_UI_INTERACTION_FRAME_INFO_REPORTED = 305,
+  ATOM_UI_ACTION_LATENCY_REPORTED = 306,
+  ATOM_WIFI_DISCONNECT_REPORTED = 307,
+  ATOM_WIFI_CONNECTION_STATE_CHANGED = 308,
+  ATOM_HDMI_CEC_ACTIVE_SOURCE_CHANGED = 309,
+  ATOM_HDMI_CEC_MESSAGE_REPORTED = 310,
+  ATOM_AIRPLANE_MODE = 311,
+  ATOM_MODEM_RESTART = 312,
+  ATOM_CARRIER_ID_MISMATCH_REPORTED = 313,
+  ATOM_CARRIER_ID_TABLE_UPDATED = 314,
+  ATOM_DATA_STALL_RECOVERY_REPORTED = 315,
+  ATOM_MEDIAMETRICS_MEDIAPARSER_REPORTED = 316,
+  ATOM_TLS_HANDSHAKE_REPORTED = 317,
+  ATOM_TEXT_CLASSIFIER_API_USAGE_REPORTED = 318,
+  ATOM_CAR_WATCHDOG_KILL_STATS_REPORTED = 319,
+  ATOM_MEDIAMETRICS_PLAYBACK_REPORTED = 320,
+  ATOM_MEDIA_NETWORK_INFO_CHANGED = 321,
+  ATOM_MEDIA_PLAYBACK_STATE_CHANGED = 322,
+  ATOM_MEDIA_PLAYBACK_ERROR_REPORTED = 323,
+  ATOM_MEDIA_PLAYBACK_TRACK_CHANGED = 324,
+  ATOM_WIFI_SCAN_REPORTED = 325,
+  ATOM_WIFI_PNO_SCAN_REPORTED = 326,
+  ATOM_TIF_TUNE_CHANGED = 327,
+  ATOM_AUTO_ROTATE_REPORTED = 328,
+  ATOM_PERFETTO_TRIGGER = 329,
+  ATOM_TRANSCODING_DATA = 330,
+  ATOM_IMS_SERVICE_ENTITLEMENT_UPDATED = 331,
+  ATOM_DEVICE_ROTATED = 333,
+  ATOM_SIM_SPECIFIC_SETTINGS_RESTORED = 334,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_REPORTED = 335,
+  ATOM_PIN_STORAGE_EVENT = 336,
+  ATOM_FACE_DOWN_REPORTED = 337,
+  ATOM_BLUETOOTH_HAL_CRASH_REASON_REPORTED = 338,
+  ATOM_REBOOT_ESCROW_PREPARATION_REPORTED = 339,
+  ATOM_REBOOT_ESCROW_LSKF_CAPTURE_REPORTED = 340,
+  ATOM_REBOOT_ESCROW_REBOOT_REPORTED = 341,
+  ATOM_BINDER_LATENCY_REPORTED = 342,
+  ATOM_MEDIAMETRICS_AAUDIOSTREAM_REPORTED = 343,
+  ATOM_MEDIA_TRANSCODING_SESSION_ENDED = 344,
+  ATOM_MAGNIFICATION_USAGE_REPORTED = 345,
+  ATOM_MAGNIFICATION_MODE_WITH_IME_ON_REPORTED = 346,
+  ATOM_APP_SEARCH_CALL_STATS_REPORTED = 347,
+  ATOM_APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED = 348,
+  ATOM_DEVICE_CONTROL_CHANGED = 349,
+  ATOM_DEVICE_STATE_CHANGED = 350,
+  ATOM_INPUTDEVICE_REGISTERED = 351,
+  ATOM_SMARTSPACE_CARD_REPORTED = 352,
+  ATOM_AUTH_PROMPT_AUTHENTICATE_INVOKED = 353,
+  ATOM_AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED = 354,
+  ATOM_AUTH_ENROLL_ACTION_INVOKED = 355,
+  ATOM_AUTH_DEPRECATED_API_USED = 356,
+  ATOM_UNATTENDED_REBOOT_OCCURRED = 357,
+  ATOM_LONG_REBOOT_BLOCKING_REPORTED = 358,
+  ATOM_LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED = 359,
+  ATOM_FDTRACK_EVENT_OCCURRED = 364,
+  ATOM_TIMEOUT_AUTO_EXTENDED_REPORTED = 365,
+  ATOM_ALARM_BATCH_DELIVERED = 367,
+  ATOM_ALARM_SCHEDULED = 368,
+  ATOM_CAR_WATCHDOG_IO_OVERUSE_STATS_REPORTED = 369,
+  ATOM_USER_LEVEL_HIBERNATION_STATE_CHANGED = 370,
+  ATOM_APP_SEARCH_INITIALIZE_STATS_REPORTED = 371,
+  ATOM_APP_SEARCH_QUERY_STATS_REPORTED = 372,
+  ATOM_APP_PROCESS_DIED = 373,
+  ATOM_NETWORK_IP_REACHABILITY_MONITOR_REPORTED = 374,
+  ATOM_SLOW_INPUT_EVENT_REPORTED = 375,
+  ATOM_ANR_OCCURRED_PROCESSING_STARTED = 376,
+  ATOM_APP_SEARCH_REMOVE_STATS_REPORTED = 377,
+  ATOM_MEDIA_CODEC_REPORTED = 378,
+  ATOM_PERMISSION_USAGE_FRAGMENT_INTERACTION = 379,
+  ATOM_PERMISSION_DETAILS_INTERACTION = 380,
+  ATOM_PRIVACY_SENSOR_TOGGLE_INTERACTION = 381,
+  ATOM_PRIVACY_TOGGLE_DIALOG_INTERACTION = 382,
+  ATOM_APP_SEARCH_OPTIMIZE_STATS_REPORTED = 383,
+  ATOM_NON_A11Y_TOOL_SERVICE_WARNING_REPORT = 384,
+  ATOM_APP_SEARCH_SET_SCHEMA_STATS_REPORTED = 385,
+  ATOM_APP_COMPAT_STATE_CHANGED = 386,
+  ATOM_SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED = 387,
+  ATOM_SPLITSCREEN_UI_CHANGED = 388,
+  ATOM_NETWORK_DNS_HANDSHAKE_REPORTED = 389,
+  ATOM_BLUETOOTH_CODE_PATH_COUNTER = 390,
+  ATOM_BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY = 392,
+  ATOM_ACCESSIBILITY_FLOATING_MENU_UI_CHANGED = 393,
+  ATOM_NEURALNETWORKS_COMPILATION_COMPLETED = 394,
+  ATOM_NEURALNETWORKS_EXECUTION_COMPLETED = 395,
+  ATOM_NEURALNETWORKS_COMPILATION_FAILED = 396,
+  ATOM_NEURALNETWORKS_EXECUTION_FAILED = 397,
+  ATOM_CONTEXT_HUB_BOOTED = 398,
+  ATOM_CONTEXT_HUB_RESTARTED = 399,
+  ATOM_CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED = 400,
+  ATOM_CHRE_CODE_DOWNLOAD_TRANSACTED = 401,
+  ATOM_UWB_SESSION_INITED = 402,
+  ATOM_UWB_SESSION_CLOSED = 403,
+  ATOM_UWB_FIRST_RANGING_RECEIVED = 404,
+  ATOM_UWB_RANGING_MEASUREMENT_RECEIVED = 405,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED = 406,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED = 407,
+  ATOM_CLIPBOARD_CLEARED = 408,
+  ATOM_VM_CREATION_REQUESTED = 409,
+  ATOM_NEARBY_DEVICE_SCAN_STATE_CHANGED = 410,
+  ATOM_CAMERA_COMPAT_CONTROL_EVENT_REPORTED = 411,
+  ATOM_APPLICATION_LOCALES_CHANGED = 412,
+  ATOM_MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED = 413,
+  ATOM_FOLD_STATE_DURATION_REPORTED = 414,
+  ATOM_LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED = 415,
+  ATOM_DISPLAY_HBM_STATE_CHANGED = 416,
+  ATOM_DISPLAY_HBM_BRIGHTNESS_CHANGED = 417,
+  ATOM_PERSISTENT_URI_PERMISSIONS_FLUSHED = 418,
+  ATOM_EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED = 419,
+  ATOM_VBMETA_DIGEST_REPORTED = 420,
+  ATOM_APEX_INFO_GATHERED = 421,
+  ATOM_PVM_INFO_GATHERED = 422,
+  ATOM_WEAR_SETTINGS_UI_INTERACTED = 423,
+  ATOM_TRACING_SERVICE_REPORT_EVENT = 424,
+  ATOM_MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED = 425,
+  ATOM_LAUNCHER_LATENCY = 426,
+  ATOM_DROPBOX_ENTRY_DROPPED = 427,
+  ATOM_WIFI_P2P_CONNECTION_REPORTED = 428,
+  ATOM_GAME_STATE_CHANGED = 429,
+  ATOM_HOTWORD_DETECTOR_CREATE_REQUESTED = 430,
+  ATOM_HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED = 431,
+  ATOM_HOTWORD_DETECTION_SERVICE_RESTARTED = 432,
+  ATOM_HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED = 433,
+  ATOM_HOTWORD_DETECTOR_EVENTS = 434,
+  ATOM_AD_SERVICES_API_CALLED = 435,
+  ATOM_AD_SERVICES_MESUREMENT_REPORTS_UPLOADED = 436,
+  ATOM_BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED = 437,
+  ATOM_CONTACTS_INDEXER_UPDATE_STATS_REPORTED = 440,
+  ATOM_APP_BACKGROUND_RESTRICTIONS_INFO = 441,
+  ATOM_MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED = 442,
+  ATOM_MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED = 443,
+  ATOM_PERMISSION_REMINDER_NOTIFICATION_INTERACTED = 444,
+  ATOM_RECENT_PERMISSION_DECISIONS_INTERACTED = 445,
+  ATOM_GNSS_PSDS_DOWNLOAD_REPORTED = 446,
+  ATOM_LE_AUDIO_CONNECTION_SESSION_REPORTED = 447,
+  ATOM_LE_AUDIO_BROADCAST_SESSION_REPORTED = 448,
+  ATOM_DREAM_UI_EVENT_REPORTED = 449,
+  ATOM_TASK_MANAGER_EVENT_REPORTED = 450,
+  ATOM_CDM_ASSOCIATION_ACTION = 451,
+  ATOM_MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED = 452,
+  ATOM_MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED = 453,
+  ATOM_ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED = 454,
+  ATOM_WIFI_SETUP_FAILURE_CRASH_REPORTED = 455,
+  ATOM_UWB_DEVICE_ERROR_REPORTED = 456,
+  ATOM_ISOLATED_COMPILATION_SCHEDULED = 457,
+  ATOM_ISOLATED_COMPILATION_ENDED = 458,
+  ATOM_ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE = 459,
+  ATOM_SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED = 460,
+  ATOM_TELEPHONY_ANOMALY_DETECTED = 461,
+  ATOM_LETTERBOX_POSITION_CHANGED = 462,
+  ATOM_REMOTE_KEY_PROVISIONING_ATTEMPT = 463,
+  ATOM_REMOTE_KEY_PROVISIONING_NETWORK_INFO = 464,
+  ATOM_REMOTE_KEY_PROVISIONING_TIMING = 465,
+  ATOM_MEDIAOUTPUT_OP_INTERACTION_REPORT = 466,
+  ATOM_SYNC_EXEMPTION_OCCURRED = 468,
+  ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED = 469,
+  ATOM_DOCK_STATE_CHANGED = 470,
+  ATOM_SAFETY_SOURCE_STATE_COLLECTED = 471,
+  ATOM_SAFETY_CENTER_SYSTEM_EVENT_REPORTED = 472,
+  ATOM_SAFETY_CENTER_INTERACTION_REPORTED = 473,
+  ATOM_SETTINGS_PROVIDER_SETTING_CHANGED = 474,
+  ATOM_BROADCAST_DELIVERY_EVENT_REPORTED = 475,
+  ATOM_SERVICE_REQUEST_EVENT_REPORTED = 476,
+  ATOM_PROVIDER_ACQUISITION_EVENT_REPORTED = 477,
+  ATOM_BLUETOOTH_DEVICE_NAME_REPORTED = 478,
+  ATOM_CB_CONFIG_UPDATED = 479,
+  ATOM_CB_MODULE_ERROR_REPORTED = 480,
+  ATOM_CB_SERVICE_FEATURE_CHANGED = 481,
+  ATOM_CB_RECEIVER_FEATURE_CHANGED = 482,
+  ATOM_JSSCRIPTENGINE_LATENCY_REPORTED = 483,
+  ATOM_PRIVACY_SIGNAL_NOTIFICATION_INTERACTION = 484,
+  ATOM_PRIVACY_SIGNAL_ISSUE_CARD_INTERACTION = 485,
+  ATOM_PRIVACY_SIGNALS_JOB_FAILURE = 486,
+  ATOM_VIBRATION_REPORTED = 487,
+  ATOM_UWB_RANGING_START = 489,
+  ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED = 490,
+  ATOM_APP_COMPACTED_V2 = 491,
+  ATOM_AD_SERVICES_SETTINGS_USAGE_REPORTED = 493,
+  ATOM_DISPLAY_BRIGHTNESS_CHANGED = 494,
+  ATOM_ACTIVITY_ACTION_BLOCKED = 495,
+  ATOM_BACKGROUND_FETCH_PROCESS_REPORTED = 496,
+  ATOM_UPDATE_CUSTOM_AUDIENCE_PROCESS_REPORTED = 497,
+  ATOM_RUN_AD_BIDDING_PROCESS_REPORTED = 498,
+  ATOM_RUN_AD_SCORING_PROCESS_REPORTED = 499,
+  ATOM_RUN_AD_SELECTION_PROCESS_REPORTED = 500,
+  ATOM_RUN_AD_BIDDING_PER_CA_PROCESS_REPORTED = 501,
+  ATOM_MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED = 502,
+  ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED = 503,
+  ATOM_NETWORK_DNS_SERVER_SUPPORT_REPORTED = 504,
+  ATOM_VM_BOOTED = 505,
+  ATOM_VM_EXITED = 506,
+  ATOM_AMBIENT_BRIGHTNESS_STATS_REPORTED = 507,
+  ATOM_MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED = 508,
+  ATOM_MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED = 509,
+  ATOM_MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED = 510,
+  ATOM_MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED = 511,
+  ATOM_AD_SERVICES_MEASUREMENT_REGISTRATIONS = 512,
+  ATOM_HEARING_AID_INFO_REPORTED = 513,
+  ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED = 514,
+  ATOM_AMBIENT_MODE_CHANGED = 515,
+  ATOM_ANR_LATENCY_REPORTED = 516,
+  ATOM_RESOURCE_API_INFO = 517,
+  ATOM_SYSTEM_DEFAULT_NETWORK_CHANGED = 518,
+  ATOM_IWLAN_SETUP_DATA_CALL_RESULT_REPORTED = 519,
+  ATOM_IWLAN_PDN_DISCONNECTED_REASON_REPORTED = 520,
+  ATOM_AIRPLANE_MODE_SESSION_REPORTED = 521,
+  ATOM_VM_CPU_STATUS_REPORTED = 522,
+  ATOM_VM_MEM_STATUS_REPORTED = 523,
+  ATOM_PACKAGE_INSTALLATION_SESSION_REPORTED = 524,
+  ATOM_DEFAULT_NETWORK_REMATCH_INFO = 525,
+  ATOM_NETWORK_SELECTION_PERFORMANCE = 526,
+  ATOM_NETWORK_NSD_REPORTED = 527,
+  ATOM_BLUETOOTH_DISCONNECTION_REASON_REPORTED = 529,
+  ATOM_BLUETOOTH_LOCAL_VERSIONS_REPORTED = 530,
+  ATOM_BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED = 531,
+  ATOM_BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED = 532,
+  ATOM_BLUETOOTH_GATT_APP_INFO = 533,
+  ATOM_BRIGHTNESS_CONFIGURATION_UPDATED = 534,
+  ATOM_AD_SERVICES_GET_TOPICS_REPORTED = 535,
+  ATOM_AD_SERVICES_EPOCH_COMPUTATION_GET_TOP_TOPICS_REPORTED = 536,
+  ATOM_AD_SERVICES_EPOCH_COMPUTATION_CLASSIFIER_REPORTED = 537,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_LAUNCHED = 538,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FINISHED = 539,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECTION_REPORTED = 540,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_TRIGGERED = 541,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FIRST_DEVICE_SCAN_LATENCY = 542,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECT_DEVICE_LATENCY = 543,
+  ATOM_PACKAGE_MANAGER_SNAPSHOT_REPORTED = 544,
+  ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED = 545,
+  ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED = 546,
+  ATOM_LAUNCHER_IMPRESSION_EVENT = 547,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_ALL_DEVICES_SCAN_LATENCY = 549,
+  ATOM_WS_WATCH_FACE_EDITED = 551,
+  ATOM_WS_WATCH_FACE_FAVORITE_ACTION_REPORTED = 552,
+  ATOM_WS_WATCH_FACE_SET_ACTION_REPORTED = 553,
+  ATOM_PACKAGE_UNINSTALLATION_REPORTED = 554,
+  ATOM_GAME_MODE_CHANGED = 555,
+  ATOM_GAME_MODE_CONFIGURATION_CHANGED = 556,
+  ATOM_BEDTIME_MODE_STATE_CHANGED = 557,
+  ATOM_NETWORK_SLICE_SESSION_ENDED = 558,
+  ATOM_NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED = 559,
+  ATOM_NFC_TAG_TYPE_OCCURRED = 560,
+  ATOM_NFC_AID_CONFLICT_OCCURRED = 561,
+  ATOM_NFC_READER_CONFLICT_OCCURRED = 562,
+  ATOM_WS_TILE_LIST_CHANGED = 563,
+  ATOM_GET_TYPE_ACCESSED_WITHOUT_PERMISSION = 564,
+  ATOM_MOBILE_BUNDLED_APP_INFO_GATHERED = 566,
+  ATOM_WS_WATCH_FACE_COMPLICATION_SET_CHANGED = 567,
+  ATOM_MEDIA_DRM_CREATED = 568,
+  ATOM_MEDIA_DRM_ERRORED = 569,
+  ATOM_MEDIA_DRM_SESSION_OPENED = 570,
+  ATOM_MEDIA_DRM_SESSION_CLOSED = 571,
+  ATOM_USER_SELECTED_RESOLUTION = 572,
+  ATOM_UNSAFE_INTENT_EVENT_REPORTED = 573,
+  ATOM_PERFORMANCE_HINT_SESSION_REPORTED = 574,
+  ATOM_MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED = 576,
+  ATOM_BIOMETRIC_TOUCH_REPORTED = 577,
+  ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED = 578,
+  ATOM_APP_SEARCH_SCHEMA_MIGRATION_STATS_REPORTED = 579,
+  ATOM_LOCATION_ENABLED_STATE_CHANGED = 580,
+  ATOM_IME_REQUEST_FINISHED = 581,
+  ATOM_USB_COMPLIANCE_WARNINGS_REPORTED = 582,
+  ATOM_APP_SUPPORTED_LOCALES_CHANGED = 583,
+  ATOM_GRAMMATICAL_INFLECTION_CHANGED = 584,
+  ATOM_MEDIA_PROVIDER_VOLUME_RECOVERY_REPORTED = 586,
+  ATOM_BIOMETRIC_PROPERTIES_COLLECTED = 587,
+  ATOM_KERNEL_WAKEUP_ATTRIBUTED = 588,
+  ATOM_SCREEN_STATE_CHANGED_V2 = 589,
+  ATOM_WS_BACKUP_ACTION_REPORTED = 590,
+  ATOM_WS_RESTORE_ACTION_REPORTED = 591,
+  ATOM_DEVICE_LOG_ACCESS_EVENT_REPORTED = 592,
+  ATOM_MEDIA_SESSION_UPDATED = 594,
+  ATOM_WEAR_OOBE_STATE_CHANGED = 595,
+  ATOM_WS_NOTIFICATION_UPDATED = 596,
+  ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED = 601,
+  ATOM_WS_COMPLICATION_TAPPED = 602,
+  ATOM_WS_WEAR_TIME_SESSION = 610,
+  ATOM_WIFI_BYTES_TRANSFER = 10000,
+  ATOM_WIFI_BYTES_TRANSFER_BY_FG_BG = 10001,
+  ATOM_MOBILE_BYTES_TRANSFER = 10002,
+  ATOM_MOBILE_BYTES_TRANSFER_BY_FG_BG = 10003,
+  ATOM_BLUETOOTH_BYTES_TRANSFER = 10006,
+  ATOM_KERNEL_WAKELOCK = 10004,
+  ATOM_SUBSYSTEM_SLEEP_STATE = 10005,
+  ATOM_CPU_TIME_PER_UID = 10009,
+  ATOM_CPU_TIME_PER_UID_FREQ = 10010,
+  ATOM_WIFI_ACTIVITY_INFO = 10011,
+  ATOM_MODEM_ACTIVITY_INFO = 10012,
+  ATOM_BLUETOOTH_ACTIVITY_INFO = 10007,
+  ATOM_PROCESS_MEMORY_STATE = 10013,
+  ATOM_SYSTEM_ELAPSED_REALTIME = 10014,
+  ATOM_SYSTEM_UPTIME = 10015,
+  ATOM_CPU_ACTIVE_TIME = 10016,
+  ATOM_CPU_CLUSTER_TIME = 10017,
+  ATOM_DISK_SPACE = 10018,
+  ATOM_REMAINING_BATTERY_CAPACITY = 10019,
+  ATOM_FULL_BATTERY_CAPACITY = 10020,
+  ATOM_TEMPERATURE = 10021,
+  ATOM_BINDER_CALLS = 10022,
+  ATOM_BINDER_CALLS_EXCEPTIONS = 10023,
+  ATOM_LOOPER_STATS = 10024,
+  ATOM_DISK_STATS = 10025,
+  ATOM_DIRECTORY_USAGE = 10026,
+  ATOM_APP_SIZE = 10027,
+  ATOM_CATEGORY_SIZE = 10028,
+  ATOM_PROC_STATS = 10029,
+  ATOM_BATTERY_VOLTAGE = 10030,
+  ATOM_NUM_FINGERPRINTS_ENROLLED = 10031,
+  ATOM_DISK_IO = 10032,
+  ATOM_POWER_PROFILE = 10033,
+  ATOM_PROC_STATS_PKG_PROC = 10034,
+  ATOM_PROCESS_CPU_TIME = 10035,
+  ATOM_CPU_TIME_PER_THREAD_FREQ = 10037,
+  ATOM_ON_DEVICE_POWER_MEASUREMENT = 10038,
+  ATOM_DEVICE_CALCULATED_POWER_USE = 10039,
+  ATOM_PROCESS_MEMORY_HIGH_WATER_MARK = 10042,
+  ATOM_BATTERY_LEVEL = 10043,
+  ATOM_BUILD_INFORMATION = 10044,
+  ATOM_BATTERY_CYCLE_COUNT = 10045,
+  ATOM_DEBUG_ELAPSED_CLOCK = 10046,
+  ATOM_DEBUG_FAILING_ELAPSED_CLOCK = 10047,
+  ATOM_NUM_FACES_ENROLLED = 10048,
+  ATOM_ROLE_HOLDER = 10049,
+  ATOM_DANGEROUS_PERMISSION_STATE = 10050,
+  ATOM_TRAIN_INFO = 10051,
+  ATOM_TIME_ZONE_DATA_INFO = 10052,
+  ATOM_EXTERNAL_STORAGE_INFO = 10053,
+  ATOM_GPU_STATS_GLOBAL_INFO = 10054,
+  ATOM_GPU_STATS_APP_INFO = 10055,
+  ATOM_SYSTEM_ION_HEAP_SIZE = 10056,
+  ATOM_APPS_ON_EXTERNAL_STORAGE_INFO = 10057,
+  ATOM_FACE_SETTINGS = 10058,
+  ATOM_COOLING_DEVICE = 10059,
+  ATOM_APP_OPS = 10060,
+  ATOM_PROCESS_SYSTEM_ION_HEAP_SIZE = 10061,
+  ATOM_SURFACEFLINGER_STATS_GLOBAL_INFO = 10062,
+  ATOM_SURFACEFLINGER_STATS_LAYER_INFO = 10063,
+  ATOM_PROCESS_MEMORY_SNAPSHOT = 10064,
+  ATOM_VMS_CLIENT_STATS = 10065,
+  ATOM_NOTIFICATION_REMOTE_VIEWS = 10066,
+  ATOM_DANGEROUS_PERMISSION_STATE_SAMPLED = 10067,
+  ATOM_GRAPHICS_STATS = 10068,
+  ATOM_RUNTIME_APP_OP_ACCESS = 10069,
+  ATOM_ION_HEAP_SIZE = 10070,
+  ATOM_PACKAGE_NOTIFICATION_PREFERENCES = 10071,
+  ATOM_PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES = 10072,
+  ATOM_PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES = 10073,
+  ATOM_GNSS_STATS = 10074,
+  ATOM_ATTRIBUTED_APP_OPS = 10075,
+  ATOM_VOICE_CALL_SESSION = 10076,
+  ATOM_VOICE_CALL_RAT_USAGE = 10077,
+  ATOM_SIM_SLOT_STATE = 10078,
+  ATOM_SUPPORTED_RADIO_ACCESS_FAMILY = 10079,
+  ATOM_SETTING_SNAPSHOT = 10080,
+  ATOM_BLOB_INFO = 10081,
+  ATOM_DATA_USAGE_BYTES_TRANSFER = 10082,
+  ATOM_BYTES_TRANSFER_BY_TAG_AND_METERED = 10083,
+  ATOM_DND_MODE_RULE = 10084,
+  ATOM_GENERAL_EXTERNAL_STORAGE_ACCESS_STATS = 10085,
+  ATOM_INCOMING_SMS = 10086,
+  ATOM_OUTGOING_SMS = 10087,
+  ATOM_CARRIER_ID_TABLE_VERSION = 10088,
+  ATOM_DATA_CALL_SESSION = 10089,
+  ATOM_CELLULAR_SERVICE_STATE = 10090,
+  ATOM_CELLULAR_DATA_SERVICE_SWITCH = 10091,
+  ATOM_SYSTEM_MEMORY = 10092,
+  ATOM_IMS_REGISTRATION_TERMINATION = 10093,
+  ATOM_IMS_REGISTRATION_STATS = 10094,
+  ATOM_CPU_TIME_PER_CLUSTER_FREQ = 10095,
+  ATOM_CPU_CYCLES_PER_UID_CLUSTER = 10096,
+  ATOM_DEVICE_ROTATED_DATA = 10097,
+  ATOM_CPU_CYCLES_PER_THREAD_GROUP_CLUSTER = 10098,
+  ATOM_MEDIA_DRM_ACTIVITY_INFO = 10099,
+  ATOM_OEM_MANAGED_BYTES_TRANSFER = 10100,
+  ATOM_GNSS_POWER_STATS = 10101,
+  ATOM_TIME_ZONE_DETECTOR_STATE = 10102,
+  ATOM_KEYSTORE2_STORAGE_STATS = 10103,
+  ATOM_RKP_POOL_STATS = 10104,
+  ATOM_PROCESS_DMABUF_MEMORY = 10105,
+  ATOM_PENDING_ALARM_INFO = 10106,
+  ATOM_USER_LEVEL_HIBERNATED_APPS = 10107,
+  ATOM_LAUNCHER_LAYOUT_SNAPSHOT = 10108,
+  ATOM_GLOBAL_HIBERNATED_APPS = 10109,
+  ATOM_INPUT_EVENT_LATENCY_SKETCH = 10110,
+  ATOM_BATTERY_USAGE_STATS_BEFORE_RESET = 10111,
+  ATOM_BATTERY_USAGE_STATS_SINCE_RESET = 10112,
+  ATOM_BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL = 10113,
+  ATOM_INSTALLED_INCREMENTAL_PACKAGE = 10114,
+  ATOM_TELEPHONY_NETWORK_REQUESTS = 10115,
+  ATOM_APP_SEARCH_STORAGE_INFO = 10116,
+  ATOM_VMSTAT = 10117,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO = 10118,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO = 10119,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO = 10120,
+  ATOM_KEYSTORE2_ATOM_WITH_OVERFLOW = 10121,
+  ATOM_KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO = 10122,
+  ATOM_KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO = 10123,
+  ATOM_RKP_ERROR_STATS = 10124,
+  ATOM_KEYSTORE2_CRASH_STATS = 10125,
+  ATOM_VENDOR_APEX_INFO = 10126,
+  ATOM_ACCESSIBILITY_SHORTCUT_STATS = 10127,
+  ATOM_ACCESSIBILITY_FLOATING_MENU_STATS = 10128,
+  ATOM_DATA_USAGE_BYTES_TRANSFER_V2 = 10129,
+  ATOM_MEDIA_CAPABILITIES = 10130,
+  ATOM_CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY = 10131,
+  ATOM_CAR_WATCHDOG_UID_IO_USAGE_SUMMARY = 10132,
+  ATOM_IMS_REGISTRATION_FEATURE_TAG_STATS = 10133,
+  ATOM_RCS_CLIENT_PROVISIONING_STATS = 10134,
+  ATOM_RCS_ACS_PROVISIONING_STATS = 10135,
+  ATOM_SIP_DELEGATE_STATS = 10136,
+  ATOM_SIP_TRANSPORT_FEATURE_TAG_STATS = 10137,
+  ATOM_SIP_MESSAGE_RESPONSE = 10138,
+  ATOM_SIP_TRANSPORT_SESSION = 10139,
+  ATOM_IMS_DEDICATED_BEARER_LISTENER_EVENT = 10140,
+  ATOM_IMS_DEDICATED_BEARER_EVENT = 10141,
+  ATOM_IMS_REGISTRATION_SERVICE_DESC_STATS = 10142,
+  ATOM_UCE_EVENT_STATS = 10143,
+  ATOM_PRESENCE_NOTIFY_EVENT = 10144,
+  ATOM_GBA_EVENT = 10145,
+  ATOM_PER_SIM_STATUS = 10146,
+  ATOM_GPU_WORK_PER_UID = 10147,
+  ATOM_PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE = 10148,
+  ATOM_SIGNED_PARTITION_INFO = 10149,
+  ATOM_PINNED_FILE_SIZES_PER_PACKAGE = 10150,
+  ATOM_PENDING_INTENTS_PER_PACKAGE = 10151,
+  ATOM_USER_INFO = 10152,
+  ATOM_TELEPHONY_NETWORK_REQUESTS_V2 = 10153,
+  ATOM_DEVICE_TELEPHONY_PROPERTIES = 10154,
+  ATOM_REMOTE_KEY_PROVISIONING_ERROR_COUNTS = 10155,
+  ATOM_SAFETY_STATE = 10156,
+  ATOM_INCOMING_MMS = 10157,
+  ATOM_OUTGOING_MMS = 10158,
+  ATOM_MULTI_USER_INFO = 10160,
+  ATOM_NETWORK_BPF_MAP_INFO = 10161,
+  ATOM_OUTGOING_SHORT_CODE_SMS = 10162,
+  ATOM_CONNECTIVITY_STATE_SAMPLE = 10163,
+  ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO = 10164,
+  ATOM_GAME_MODE_INFO = 10165,
+  ATOM_GAME_MODE_CONFIGURATION = 10166,
+  ATOM_GAME_MODE_LISTENER = 10167,
+  ATOM_NETWORK_SLICE_REQUEST_COUNT = 10168,
+  ATOM_WS_TILE_SNAPSHOT = 10169,
+  ATOM_WS_ACTIVE_WATCH_FACE_COMPLICATION_SET_SNAPSHOT = 10170,
+  ATOM_PROCESS_STATE = 10171,
+  ATOM_PROCESS_ASSOCIATION = 10172,
+  ATOM_ADPF_SYSTEM_COMPONENT_INFO = 10173,
+  ATOM_NOTIFICATION_MEMORY_USE = 10174,
+  ATOM_HDR_CAPABILITIES = 10175,
+  ATOM_WS_FAVOURITE_WATCH_FACE_LIST_SNAPSHOT = 10176,
+  ATOM_WIFI_AWARE_NDP_REPORTED = 638,
+  ATOM_WIFI_AWARE_ATTACH_REPORTED = 639,
+  ATOM_WIFI_SELF_RECOVERY_TRIGGERED = 661,
+  ATOM_SOFT_AP_STARTED = 680,
+  ATOM_SOFT_AP_STOPPED = 681,
+  ATOM_WIFI_LOCK_RELEASED = 687,
+  ATOM_WIFI_LOCK_DEACTIVATED = 688,
+  ATOM_WIFI_CONFIG_SAVED = 689,
+  ATOM_WIFI_AWARE_RESOURCE_USING_CHANGED = 690,
+  ATOM_WIFI_AWARE_HAL_API_CALLED = 691,
+  ATOM_WIFI_LOCAL_ONLY_REQUEST_RECEIVED = 692,
+  ATOM_WIFI_LOCAL_ONLY_REQUEST_SCAN_TRIGGERED = 693,
+  ATOM_WIFI_THREAD_TASK_EXECUTED = 694,
+  ATOM_WIFI_STATE_CHANGED = 700,
+  ATOM_WIFI_AWARE_CAPABILITIES = 10190,
+  ATOM_WIFI_MODULE_INFO = 10193,
+  ATOM_SETTINGS_SPA_REPORTED = 622,
+  ATOM_EXPRESS_EVENT_REPORTED = 528,
+  ATOM_EXPRESS_HISTOGRAM_SAMPLE_REPORTED = 593,
+  ATOM_EXPRESS_UID_EVENT_REPORTED = 644,
+  ATOM_EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED = 658,
+  ATOM_PERMISSION_RATIONALE_DIALOG_VIEWED = 645,
+  ATOM_PERMISSION_RATIONALE_DIALOG_ACTION_REPORTED = 646,
+  ATOM_APP_DATA_SHARING_UPDATES_NOTIFICATION_INTERACTION = 647,
+  ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_VIEWED = 648,
+  ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_ACTION_REPORTED = 649,
+  ATOM_WS_INCOMING_CALL_ACTION_REPORTED = 626,
+  ATOM_WS_CALL_DISCONNECTION_REPORTED = 627,
+  ATOM_WS_CALL_DURATION_REPORTED = 628,
+  ATOM_WS_CALL_USER_EXPERIENCE_LATENCY_REPORTED = 629,
+  ATOM_WS_CALL_INTERACTION_REPORTED = 630,
+  ATOM_FULL_SCREEN_INTENT_LAUNCHED = 631,
+  ATOM_BAL_ALLOWED = 632,
+  ATOM_IN_TASK_ACTIVITY_STARTED = 685,
+  ATOM_CACHED_APPS_HIGH_WATERMARK = 10189,
+  ATOM_ODREFRESH_REPORTED = 366,
+  ATOM_ODSIGN_REPORTED = 548,
+  ATOM_ART_DATUM_REPORTED = 332,
+  ATOM_ART_DEVICE_DATUM_REPORTED = 550,
+  ATOM_ART_DATUM_DELTA_REPORTED = 565,
+  ATOM_BACKGROUND_DEXOPT_JOB_ENDED = 467,
+  ATOM_WEAR_ADAPTIVE_SUSPEND_STATS_REPORTED = 619,
+  ATOM_WEAR_POWER_ANOMALY_SERVICE_OPERATIONAL_STATS_REPORTED = 620,
+  ATOM_WEAR_POWER_ANOMALY_SERVICE_EVENT_STATS_REPORTED = 621,
+  ATOM_EMERGENCY_STATE_CHANGED = 633,
+  ATOM_DND_STATE_CHANGED = 657,
+  ATOM_MTE_STATE = 10181,
+  ATOM_AD_SERVICES_BACK_COMPAT_GET_TOPICS_REPORTED = 598,
+  ATOM_AD_SERVICES_BACK_COMPAT_EPOCH_COMPUTATION_CLASSIFIER_REPORTED = 599,
+  ATOM_AD_SERVICES_MEASUREMENT_DEBUG_KEYS = 640,
+  ATOM_AD_SERVICES_ERROR_REPORTED = 662,
+  ATOM_AD_SERVICES_BACKGROUND_JOBS_EXECUTION_REPORTED = 663,
+  ATOM_AD_SERVICES_MEASUREMENT_DELAYED_SOURCE_REGISTRATION = 673,
+  ATOM_AD_SERVICES_MEASUREMENT_ATTRIBUTION = 674,
+  ATOM_AD_SERVICES_MEASUREMENT_JOBS = 675,
+  ATOM_AD_SERVICES_MEASUREMENT_WIPEOUT = 676,
+  ATOM_AD_SERVICES_CONSENT_MIGRATED = 702,
+  ATOM_RKPD_POOL_STATS = 664,
+  ATOM_RKPD_CLIENT_OPERATION = 665,
+  ATOM_AUTOFILL_UI_EVENT_REPORTED = 603,
+  ATOM_AUTOFILL_FILL_REQUEST_REPORTED = 604,
+  ATOM_AUTOFILL_FILL_RESPONSE_REPORTED = 605,
+  ATOM_AUTOFILL_SAVE_EVENT_REPORTED = 606,
+  ATOM_AUTOFILL_SESSION_COMMITTED = 607,
+  ATOM_AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED = 659,
+  ATOM_TEST_EXTENSION_ATOM_REPORTED = 660,
+  ATOM_TEST_RESTRICTED_ATOM_REPORTED = 672,
+  ATOM_STATS_SOCKET_LOSS_REPORTED = 752,
+  ATOM_PLUGIN_INITIALIZED = 655,
+  ATOM_TV_LOW_POWER_STANDBY_POLICY = 679,
+  ATOM_LOCKSCREEN_SHORTCUT_SELECTED = 611,
+  ATOM_LOCKSCREEN_SHORTCUT_TRIGGERED = 612,
+  ATOM_EMERGENCY_NUMBERS_INFO = 10180,
+  ATOM_QUALIFIED_RAT_LIST_CHANGED = 634,
+  ATOM_QNS_IMS_CALL_DROP_STATS = 635,
+  ATOM_QNS_FALLBACK_RESTRICTION_CHANGED = 636,
+  ATOM_QNS_RAT_PREFERENCE_MISMATCH_INFO = 10177,
+  ATOM_QNS_HANDOVER_TIME_MILLIS = 10178,
+  ATOM_QNS_HANDOVER_PINGPONG = 10179,
+  ATOM_SATELLITE_CONTROLLER = 10182,
+  ATOM_SATELLITE_SESSION = 10183,
+  ATOM_SATELLITE_INCOMING_DATAGRAM = 10184,
+  ATOM_SATELLITE_OUTGOING_DATAGRAM = 10185,
+  ATOM_SATELLITE_PROVISION = 10186,
+  ATOM_SATELLITE_SOS_MESSAGE_RECOMMENDER = 10187,
+  ATOM_IKE_SESSION_TERMINATED = 678,
+  ATOM_IKE_LIVENESS_CHECK_SESSION_VALIDATED = 760,
+  ATOM_BLUETOOTH_HASHED_DEVICE_NAME_REPORTED = 613,
+  ATOM_BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION = 614,
+  ATOM_BLUETOOTH_L2CAP_COC_SERVER_CONNECTION = 615,
+  ATOM_BLUETOOTH_LE_SESSION_CONNECTED = 656,
+  ATOM_RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED = 666,
+  ATOM_BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED = 696,
+  ATOM_HEALTH_CONNECT_UI_IMPRESSION = 623,
+  ATOM_HEALTH_CONNECT_UI_INTERACTION = 624,
+  ATOM_HEALTH_CONNECT_APP_OPENED_REPORTED = 625,
+  ATOM_HEALTH_CONNECT_API_CALLED = 616,
+  ATOM_HEALTH_CONNECT_USAGE_STATS = 617,
+  ATOM_HEALTH_CONNECT_STORAGE_STATS = 618,
+  ATOM_HEALTH_CONNECT_API_INVOKED = 643,
+  ATOM_EXERCISE_ROUTE_API_CALLED = 654,
+  ATOM_ATOM_9999 = 9999,
+  ATOM_ATOM_99999 = 99999,
+  ATOM_THREADNETWORK_TELEMETRY_DATA_REPORTED = 738,
+  ATOM_THREADNETWORK_TOPO_ENTRY_REPEATED = 739,
+  ATOM_THREADNETWORK_DEVICE_INFO_REPORTED = 740,
+  ATOM_EMERGENCY_NUMBER_DIALED = 637,
+  ATOM_SANDBOX_API_CALLED = 488,
+  ATOM_SANDBOX_ACTIVITY_EVENT_OCCURRED = 735,
+  ATOM_SANDBOX_SDK_STORAGE = 10159,
+  ATOM_CRONET_ENGINE_CREATED = 703,
+  ATOM_CRONET_TRAFFIC_REPORTED = 704,
+  ATOM_CRONET_ENGINE_BUILDER_INITIALIZED = 762,
+  ATOM_CRONET_HTTP_FLAGS_INITIALIZED = 763,
+  ATOM_CRONET_INITIALIZED = 764,
+  ATOM_DAILY_KEEPALIVE_INFO_REPORTED = 650,
+  ATOM_IP_CLIENT_RA_INFO_REPORTED = 778,
+  ATOM_APF_SESSION_INFO_REPORTED = 777,
+  ATOM_CREDENTIAL_MANAGER_API_CALLED = 585,
+  ATOM_CREDENTIAL_MANAGER_INIT_PHASE_REPORTED = 651,
+  ATOM_CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED = 652,
+  ATOM_CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED = 653,
+  ATOM_CREDENTIAL_MANAGER_TOTAL_REPORTED = 667,
+  ATOM_CREDENTIAL_MANAGER_FINALNOUID_REPORTED = 668,
+  ATOM_CREDENTIAL_MANAGER_GET_REPORTED = 669,
+  ATOM_CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED = 670,
+  ATOM_CREDENTIAL_MANAGER_APIV2_CALLED = 671,
+  ATOM_UWB_ACTIVITY_INFO = 10188,
+  ATOM_MEDIA_ACTION_REPORTED = 608,
+  ATOM_MEDIA_CONTROLS_LAUNCHED = 609,
+  ATOM_MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED = 600,
+  ATOM_MEDIA_CODEC_STARTED = 641,
+  ATOM_MEDIA_CODEC_STOPPED = 642,
+  ATOM_MEDIA_CODEC_RENDERED = 684,
+};
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/statsd/statsd_tracing_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_STATSD_TRACING_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_STATSD_TRACING_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class StatsdPullAtomConfig;
+class StatsdTracingConfig;
+enum AtomId : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT StatsdPullAtomConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPullAtomIdFieldNumber = 1,
+    kRawPullAtomIdFieldNumber = 2,
+    kPullFrequencyMsFieldNumber = 3,
+    kPackagesFieldNumber = 4,
+  };
+
+  StatsdPullAtomConfig();
+  ~StatsdPullAtomConfig() override;
+  StatsdPullAtomConfig(StatsdPullAtomConfig&&) noexcept;
+  StatsdPullAtomConfig& operator=(StatsdPullAtomConfig&&);
+  StatsdPullAtomConfig(const StatsdPullAtomConfig&);
+  StatsdPullAtomConfig& operator=(const StatsdPullAtomConfig&);
+  bool operator==(const StatsdPullAtomConfig&) const;
+  bool operator!=(const StatsdPullAtomConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<AtomId>& pull_atom_id() const { return pull_atom_id_; }
+  std::vector<AtomId>* mutable_pull_atom_id() { return &pull_atom_id_; }
+  int pull_atom_id_size() const { return static_cast<int>(pull_atom_id_.size()); }
+  void clear_pull_atom_id() { pull_atom_id_.clear(); }
+  void add_pull_atom_id(AtomId value) { pull_atom_id_.emplace_back(value); }
+  AtomId* add_pull_atom_id() { pull_atom_id_.emplace_back(); return &pull_atom_id_.back(); }
+
+  const std::vector<int32_t>& raw_pull_atom_id() const { return raw_pull_atom_id_; }
+  std::vector<int32_t>* mutable_raw_pull_atom_id() { return &raw_pull_atom_id_; }
+  int raw_pull_atom_id_size() const { return static_cast<int>(raw_pull_atom_id_.size()); }
+  void clear_raw_pull_atom_id() { raw_pull_atom_id_.clear(); }
+  void add_raw_pull_atom_id(int32_t value) { raw_pull_atom_id_.emplace_back(value); }
+  int32_t* add_raw_pull_atom_id() { raw_pull_atom_id_.emplace_back(); return &raw_pull_atom_id_.back(); }
+
+  bool has_pull_frequency_ms() const { return _has_field_[3]; }
+  int32_t pull_frequency_ms() const { return pull_frequency_ms_; }
+  void set_pull_frequency_ms(int32_t value) { pull_frequency_ms_ = value; _has_field_.set(3); }
+
+  const std::vector<std::string>& packages() const { return packages_; }
+  std::vector<std::string>* mutable_packages() { return &packages_; }
+  int packages_size() const { return static_cast<int>(packages_.size()); }
+  void clear_packages() { packages_.clear(); }
+  void add_packages(std::string value) { packages_.emplace_back(value); }
+  std::string* add_packages() { packages_.emplace_back(); return &packages_.back(); }
+
+ private:
+  std::vector<AtomId> pull_atom_id_;
+  std::vector<int32_t> raw_pull_atom_id_;
+  int32_t pull_frequency_ms_{};
+  std::vector<std::string> packages_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT StatsdTracingConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPushAtomIdFieldNumber = 1,
+    kRawPushAtomIdFieldNumber = 2,
+    kPullConfigFieldNumber = 3,
+  };
+
+  StatsdTracingConfig();
+  ~StatsdTracingConfig() override;
+  StatsdTracingConfig(StatsdTracingConfig&&) noexcept;
+  StatsdTracingConfig& operator=(StatsdTracingConfig&&);
+  StatsdTracingConfig(const StatsdTracingConfig&);
+  StatsdTracingConfig& operator=(const StatsdTracingConfig&);
+  bool operator==(const StatsdTracingConfig&) const;
+  bool operator!=(const StatsdTracingConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<AtomId>& push_atom_id() const { return push_atom_id_; }
+  std::vector<AtomId>* mutable_push_atom_id() { return &push_atom_id_; }
+  int push_atom_id_size() const { return static_cast<int>(push_atom_id_.size()); }
+  void clear_push_atom_id() { push_atom_id_.clear(); }
+  void add_push_atom_id(AtomId value) { push_atom_id_.emplace_back(value); }
+  AtomId* add_push_atom_id() { push_atom_id_.emplace_back(); return &push_atom_id_.back(); }
+
+  const std::vector<int32_t>& raw_push_atom_id() const { return raw_push_atom_id_; }
+  std::vector<int32_t>* mutable_raw_push_atom_id() { return &raw_push_atom_id_; }
+  int raw_push_atom_id_size() const { return static_cast<int>(raw_push_atom_id_.size()); }
+  void clear_raw_push_atom_id() { raw_push_atom_id_.clear(); }
+  void add_raw_push_atom_id(int32_t value) { raw_push_atom_id_.emplace_back(value); }
+  int32_t* add_raw_push_atom_id() { raw_push_atom_id_.emplace_back(); return &raw_push_atom_id_.back(); }
+
+  const std::vector<StatsdPullAtomConfig>& pull_config() const { return pull_config_; }
+  std::vector<StatsdPullAtomConfig>* mutable_pull_config() { return &pull_config_; }
+  int pull_config_size() const;
+  void clear_pull_config();
+  StatsdPullAtomConfig* add_pull_config();
+
+ private:
+  std::vector<AtomId> push_atom_id_;
+  std::vector<int32_t> raw_push_atom_id_;
+  std::vector<StatsdPullAtomConfig> pull_config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_STATSD_TRACING_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SysStatsConfig;
+enum SysStatsConfig_StatCounters : int;
+enum MeminfoCounters : int;
+enum VmstatCounters : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum SysStatsConfig_StatCounters : int {
+  SysStatsConfig_StatCounters_STAT_UNSPECIFIED = 0,
+  SysStatsConfig_StatCounters_STAT_CPU_TIMES = 1,
+  SysStatsConfig_StatCounters_STAT_IRQ_COUNTS = 2,
+  SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS = 3,
+  SysStatsConfig_StatCounters_STAT_FORK_COUNT = 4,
+};
+
+class PERFETTO_EXPORT_COMPONENT SysStatsConfig : public ::protozero::CppMessageObj {
+ public:
+  using StatCounters = SysStatsConfig_StatCounters;
+  static constexpr auto STAT_UNSPECIFIED = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
+  static constexpr auto STAT_CPU_TIMES = SysStatsConfig_StatCounters_STAT_CPU_TIMES;
+  static constexpr auto STAT_IRQ_COUNTS = SysStatsConfig_StatCounters_STAT_IRQ_COUNTS;
+  static constexpr auto STAT_SOFTIRQ_COUNTS = SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS;
+  static constexpr auto STAT_FORK_COUNT = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
+  static constexpr auto StatCounters_MIN = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
+  static constexpr auto StatCounters_MAX = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
+  enum FieldNumbers {
+    kMeminfoPeriodMsFieldNumber = 1,
+    kMeminfoCountersFieldNumber = 2,
+    kVmstatPeriodMsFieldNumber = 3,
+    kVmstatCountersFieldNumber = 4,
+    kStatPeriodMsFieldNumber = 5,
+    kStatCountersFieldNumber = 6,
+    kDevfreqPeriodMsFieldNumber = 7,
+    kCpufreqPeriodMsFieldNumber = 8,
+    kBuddyinfoPeriodMsFieldNumber = 9,
+    kDiskstatPeriodMsFieldNumber = 10,
+    kPsiPeriodMsFieldNumber = 11,
+  };
+
+  SysStatsConfig();
+  ~SysStatsConfig() override;
+  SysStatsConfig(SysStatsConfig&&) noexcept;
+  SysStatsConfig& operator=(SysStatsConfig&&);
+  SysStatsConfig(const SysStatsConfig&);
+  SysStatsConfig& operator=(const SysStatsConfig&);
+  bool operator==(const SysStatsConfig&) const;
+  bool operator!=(const SysStatsConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_meminfo_period_ms() const { return _has_field_[1]; }
+  uint32_t meminfo_period_ms() const { return meminfo_period_ms_; }
+  void set_meminfo_period_ms(uint32_t value) { meminfo_period_ms_ = value; _has_field_.set(1); }
+
+  const std::vector<MeminfoCounters>& meminfo_counters() const { return meminfo_counters_; }
+  std::vector<MeminfoCounters>* mutable_meminfo_counters() { return &meminfo_counters_; }
+  int meminfo_counters_size() const { return static_cast<int>(meminfo_counters_.size()); }
+  void clear_meminfo_counters() { meminfo_counters_.clear(); }
+  void add_meminfo_counters(MeminfoCounters value) { meminfo_counters_.emplace_back(value); }
+  MeminfoCounters* add_meminfo_counters() { meminfo_counters_.emplace_back(); return &meminfo_counters_.back(); }
+
+  bool has_vmstat_period_ms() const { return _has_field_[3]; }
+  uint32_t vmstat_period_ms() const { return vmstat_period_ms_; }
+  void set_vmstat_period_ms(uint32_t value) { vmstat_period_ms_ = value; _has_field_.set(3); }
+
+  const std::vector<VmstatCounters>& vmstat_counters() const { return vmstat_counters_; }
+  std::vector<VmstatCounters>* mutable_vmstat_counters() { return &vmstat_counters_; }
+  int vmstat_counters_size() const { return static_cast<int>(vmstat_counters_.size()); }
+  void clear_vmstat_counters() { vmstat_counters_.clear(); }
+  void add_vmstat_counters(VmstatCounters value) { vmstat_counters_.emplace_back(value); }
+  VmstatCounters* add_vmstat_counters() { vmstat_counters_.emplace_back(); return &vmstat_counters_.back(); }
+
+  bool has_stat_period_ms() const { return _has_field_[5]; }
+  uint32_t stat_period_ms() const { return stat_period_ms_; }
+  void set_stat_period_ms(uint32_t value) { stat_period_ms_ = value; _has_field_.set(5); }
+
+  const std::vector<SysStatsConfig_StatCounters>& stat_counters() const { return stat_counters_; }
+  std::vector<SysStatsConfig_StatCounters>* mutable_stat_counters() { return &stat_counters_; }
+  int stat_counters_size() const { return static_cast<int>(stat_counters_.size()); }
+  void clear_stat_counters() { stat_counters_.clear(); }
+  void add_stat_counters(SysStatsConfig_StatCounters value) { stat_counters_.emplace_back(value); }
+  SysStatsConfig_StatCounters* add_stat_counters() { stat_counters_.emplace_back(); return &stat_counters_.back(); }
+
+  bool has_devfreq_period_ms() const { return _has_field_[7]; }
+  uint32_t devfreq_period_ms() const { return devfreq_period_ms_; }
+  void set_devfreq_period_ms(uint32_t value) { devfreq_period_ms_ = value; _has_field_.set(7); }
+
+  bool has_cpufreq_period_ms() const { return _has_field_[8]; }
+  uint32_t cpufreq_period_ms() const { return cpufreq_period_ms_; }
+  void set_cpufreq_period_ms(uint32_t value) { cpufreq_period_ms_ = value; _has_field_.set(8); }
+
+  bool has_buddyinfo_period_ms() const { return _has_field_[9]; }
+  uint32_t buddyinfo_period_ms() const { return buddyinfo_period_ms_; }
+  void set_buddyinfo_period_ms(uint32_t value) { buddyinfo_period_ms_ = value; _has_field_.set(9); }
+
+  bool has_diskstat_period_ms() const { return _has_field_[10]; }
+  uint32_t diskstat_period_ms() const { return diskstat_period_ms_; }
+  void set_diskstat_period_ms(uint32_t value) { diskstat_period_ms_ = value; _has_field_.set(10); }
+
+  bool has_psi_period_ms() const { return _has_field_[11]; }
+  uint32_t psi_period_ms() const { return psi_period_ms_; }
+  void set_psi_period_ms(uint32_t value) { psi_period_ms_ = value; _has_field_.set(11); }
+
+ private:
+  uint32_t meminfo_period_ms_{};
+  std::vector<MeminfoCounters> meminfo_counters_;
+  uint32_t vmstat_period_ms_{};
+  std::vector<VmstatCounters> vmstat_counters_;
+  uint32_t stat_period_ms_{};
+  std::vector<SysStatsConfig_StatCounters> stat_counters_;
+  uint32_t devfreq_period_ms_{};
+  uint32_t cpufreq_period_ms_{};
+  uint32_t buddyinfo_period_ms_{};
+  uint32_t diskstat_period_ms_{};
+  uint32_t psi_period_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<12> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/system_info/system_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYSTEM_INFO_SYSTEM_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYSTEM_INFO_SYSTEM_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SystemInfoConfig;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT SystemInfoConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  SystemInfoConfig();
+  ~SystemInfoConfig() override;
+  SystemInfoConfig(SystemInfoConfig&&) noexcept;
+  SystemInfoConfig& operator=(SystemInfoConfig&&);
+  SystemInfoConfig(const SystemInfoConfig&);
+  SystemInfoConfig& operator=(const SystemInfoConfig&);
+  bool operator==(const SystemInfoConfig&) const;
+  bool operator!=(const SystemInfoConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYSTEM_INFO_SYSTEM_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/chrome/chrome_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeConfig;
+enum ChromeConfig_ClientPriority : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeConfig_ClientPriority : int {
+  ChromeConfig_ClientPriority_UNKNOWN = 0,
+  ChromeConfig_ClientPriority_BACKGROUND = 1,
+  ChromeConfig_ClientPriority_USER_INITIATED = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeConfig : public ::protozero::CppMessageObj {
+ public:
+  using ClientPriority = ChromeConfig_ClientPriority;
+  static constexpr auto UNKNOWN = ChromeConfig_ClientPriority_UNKNOWN;
+  static constexpr auto BACKGROUND = ChromeConfig_ClientPriority_BACKGROUND;
+  static constexpr auto USER_INITIATED = ChromeConfig_ClientPriority_USER_INITIATED;
+  static constexpr auto ClientPriority_MIN = ChromeConfig_ClientPriority_UNKNOWN;
+  static constexpr auto ClientPriority_MAX = ChromeConfig_ClientPriority_USER_INITIATED;
+  enum FieldNumbers {
+    kTraceConfigFieldNumber = 1,
+    kPrivacyFilteringEnabledFieldNumber = 2,
+    kConvertToLegacyJsonFieldNumber = 3,
+    kClientPriorityFieldNumber = 4,
+    kJsonAgentLabelFilterFieldNumber = 5,
+  };
+
+  ChromeConfig();
+  ~ChromeConfig() override;
+  ChromeConfig(ChromeConfig&&) noexcept;
+  ChromeConfig& operator=(ChromeConfig&&);
+  ChromeConfig(const ChromeConfig&);
+  ChromeConfig& operator=(const ChromeConfig&);
+  bool operator==(const ChromeConfig&) const;
+  bool operator!=(const ChromeConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_config() const { return _has_field_[1]; }
+  const std::string& trace_config() const { return trace_config_; }
+  void set_trace_config(const std::string& value) { trace_config_ = value; _has_field_.set(1); }
+
+  bool has_privacy_filtering_enabled() const { return _has_field_[2]; }
+  bool privacy_filtering_enabled() const { return privacy_filtering_enabled_; }
+  void set_privacy_filtering_enabled(bool value) { privacy_filtering_enabled_ = value; _has_field_.set(2); }
+
+  bool has_convert_to_legacy_json() const { return _has_field_[3]; }
+  bool convert_to_legacy_json() const { return convert_to_legacy_json_; }
+  void set_convert_to_legacy_json(bool value) { convert_to_legacy_json_ = value; _has_field_.set(3); }
+
+  bool has_client_priority() const { return _has_field_[4]; }
+  ChromeConfig_ClientPriority client_priority() const { return client_priority_; }
+  void set_client_priority(ChromeConfig_ClientPriority value) { client_priority_ = value; _has_field_.set(4); }
+
+  bool has_json_agent_label_filter() const { return _has_field_[5]; }
+  const std::string& json_agent_label_filter() const { return json_agent_label_filter_; }
+  void set_json_agent_label_filter(const std::string& value) { json_agent_label_filter_ = value; _has_field_.set(5); }
+
+ private:
+  std::string trace_config_{};
+  bool privacy_filtering_enabled_{};
+  bool convert_to_legacy_json_{};
+  ChromeConfig_ClientPriority client_priority_{};
+  std::string json_agent_label_filter_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/chrome/scenario_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_SCENARIO_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_SCENARIO_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeFieldTracingConfig;
+class ScenarioConfig;
+class NestedScenarioConfig;
+class TriggerRule;
+class TriggerRule_RepeatingInterval;
+class TriggerRule_HistogramTrigger;
+class TraceConfig;
+class TraceConfig_CmdTraceStartDelay;
+class TraceConfig_AndroidReportConfig;
+class TraceConfig_TraceFilter;
+class TraceConfig_TraceFilter_StringFilterChain;
+class TraceConfig_TraceFilter_StringFilterRule;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_ProducerConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_DataSource;
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+class TraceConfig_BufferConfig;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TraceFilter_StringFilterPolicy : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+enum TraceConfig_BufferConfig_FillPolicy : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeFieldTracingConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kScenariosFieldNumber = 1,
+  };
+
+  ChromeFieldTracingConfig();
+  ~ChromeFieldTracingConfig() override;
+  ChromeFieldTracingConfig(ChromeFieldTracingConfig&&) noexcept;
+  ChromeFieldTracingConfig& operator=(ChromeFieldTracingConfig&&);
+  ChromeFieldTracingConfig(const ChromeFieldTracingConfig&);
+  ChromeFieldTracingConfig& operator=(const ChromeFieldTracingConfig&);
+  bool operator==(const ChromeFieldTracingConfig&) const;
+  bool operator!=(const ChromeFieldTracingConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ScenarioConfig>& scenarios() const { return scenarios_; }
+  std::vector<ScenarioConfig>* mutable_scenarios() { return &scenarios_; }
+  int scenarios_size() const;
+  void clear_scenarios();
+  ScenarioConfig* add_scenarios();
+
+ private:
+  std::vector<ScenarioConfig> scenarios_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ScenarioConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kScenarioNameFieldNumber = 1,
+    kStartRulesFieldNumber = 2,
+    kStopRulesFieldNumber = 3,
+    kUploadRulesFieldNumber = 4,
+    kSetupRulesFieldNumber = 5,
+    kTraceConfigFieldNumber = 6,
+    kNestedScenariosFieldNumber = 7,
+  };
+
+  ScenarioConfig();
+  ~ScenarioConfig() override;
+  ScenarioConfig(ScenarioConfig&&) noexcept;
+  ScenarioConfig& operator=(ScenarioConfig&&);
+  ScenarioConfig(const ScenarioConfig&);
+  ScenarioConfig& operator=(const ScenarioConfig&);
+  bool operator==(const ScenarioConfig&) const;
+  bool operator!=(const ScenarioConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_scenario_name() const { return _has_field_[1]; }
+  const std::string& scenario_name() const { return scenario_name_; }
+  void set_scenario_name(const std::string& value) { scenario_name_ = value; _has_field_.set(1); }
+
+  const std::vector<TriggerRule>& start_rules() const { return start_rules_; }
+  std::vector<TriggerRule>* mutable_start_rules() { return &start_rules_; }
+  int start_rules_size() const;
+  void clear_start_rules();
+  TriggerRule* add_start_rules();
+
+  const std::vector<TriggerRule>& stop_rules() const { return stop_rules_; }
+  std::vector<TriggerRule>* mutable_stop_rules() { return &stop_rules_; }
+  int stop_rules_size() const;
+  void clear_stop_rules();
+  TriggerRule* add_stop_rules();
+
+  const std::vector<TriggerRule>& upload_rules() const { return upload_rules_; }
+  std::vector<TriggerRule>* mutable_upload_rules() { return &upload_rules_; }
+  int upload_rules_size() const;
+  void clear_upload_rules();
+  TriggerRule* add_upload_rules();
+
+  const std::vector<TriggerRule>& setup_rules() const { return setup_rules_; }
+  std::vector<TriggerRule>* mutable_setup_rules() { return &setup_rules_; }
+  int setup_rules_size() const;
+  void clear_setup_rules();
+  TriggerRule* add_setup_rules();
+
+  bool has_trace_config() const { return _has_field_[6]; }
+  const TraceConfig& trace_config() const { return *trace_config_; }
+  TraceConfig* mutable_trace_config() { _has_field_.set(6); return trace_config_.get(); }
+
+  const std::vector<NestedScenarioConfig>& nested_scenarios() const { return nested_scenarios_; }
+  std::vector<NestedScenarioConfig>* mutable_nested_scenarios() { return &nested_scenarios_; }
+  int nested_scenarios_size() const;
+  void clear_nested_scenarios();
+  NestedScenarioConfig* add_nested_scenarios();
+
+ private:
+  std::string scenario_name_{};
+  std::vector<TriggerRule> start_rules_;
+  std::vector<TriggerRule> stop_rules_;
+  std::vector<TriggerRule> upload_rules_;
+  std::vector<TriggerRule> setup_rules_;
+  ::protozero::CopyablePtr<TraceConfig> trace_config_;
+  std::vector<NestedScenarioConfig> nested_scenarios_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT NestedScenarioConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kScenarioNameFieldNumber = 1,
+    kStartRulesFieldNumber = 2,
+    kStopRulesFieldNumber = 3,
+    kUploadRulesFieldNumber = 4,
+  };
+
+  NestedScenarioConfig();
+  ~NestedScenarioConfig() override;
+  NestedScenarioConfig(NestedScenarioConfig&&) noexcept;
+  NestedScenarioConfig& operator=(NestedScenarioConfig&&);
+  NestedScenarioConfig(const NestedScenarioConfig&);
+  NestedScenarioConfig& operator=(const NestedScenarioConfig&);
+  bool operator==(const NestedScenarioConfig&) const;
+  bool operator!=(const NestedScenarioConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_scenario_name() const { return _has_field_[1]; }
+  const std::string& scenario_name() const { return scenario_name_; }
+  void set_scenario_name(const std::string& value) { scenario_name_ = value; _has_field_.set(1); }
+
+  const std::vector<TriggerRule>& start_rules() const { return start_rules_; }
+  std::vector<TriggerRule>* mutable_start_rules() { return &start_rules_; }
+  int start_rules_size() const;
+  void clear_start_rules();
+  TriggerRule* add_start_rules();
+
+  const std::vector<TriggerRule>& stop_rules() const { return stop_rules_; }
+  std::vector<TriggerRule>* mutable_stop_rules() { return &stop_rules_; }
+  int stop_rules_size() const;
+  void clear_stop_rules();
+  TriggerRule* add_stop_rules();
+
+  const std::vector<TriggerRule>& upload_rules() const { return upload_rules_; }
+  std::vector<TriggerRule>* mutable_upload_rules() { return &upload_rules_; }
+  int upload_rules_size() const;
+  void clear_upload_rules();
+  TriggerRule* add_upload_rules();
+
+ private:
+  std::string scenario_name_{};
+  std::vector<TriggerRule> start_rules_;
+  std::vector<TriggerRule> stop_rules_;
+  std::vector<TriggerRule> upload_rules_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TriggerRule : public ::protozero::CppMessageObj {
+ public:
+  using HistogramTrigger = TriggerRule_HistogramTrigger;
+  using RepeatingInterval = TriggerRule_RepeatingInterval;
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kTriggerChanceFieldNumber = 2,
+    kDelayMsFieldNumber = 3,
+    kActivationDelayMsFieldNumber = 8,
+    kManualTriggerNameFieldNumber = 4,
+    kHistogramFieldNumber = 5,
+    kRepeatingIntervalFieldNumber = 6,
+  };
+
+  TriggerRule();
+  ~TriggerRule() override;
+  TriggerRule(TriggerRule&&) noexcept;
+  TriggerRule& operator=(TriggerRule&&);
+  TriggerRule(const TriggerRule&);
+  TriggerRule& operator=(const TriggerRule&);
+  bool operator==(const TriggerRule&) const;
+  bool operator!=(const TriggerRule& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_trigger_chance() const { return _has_field_[2]; }
+  float trigger_chance() const { return trigger_chance_; }
+  void set_trigger_chance(float value) { trigger_chance_ = value; _has_field_.set(2); }
+
+  bool has_delay_ms() const { return _has_field_[3]; }
+  uint64_t delay_ms() const { return delay_ms_; }
+  void set_delay_ms(uint64_t value) { delay_ms_ = value; _has_field_.set(3); }
+
+  bool has_activation_delay_ms() const { return _has_field_[8]; }
+  uint64_t activation_delay_ms() const { return activation_delay_ms_; }
+  void set_activation_delay_ms(uint64_t value) { activation_delay_ms_ = value; _has_field_.set(8); }
+
+  bool has_manual_trigger_name() const { return _has_field_[4]; }
+  const std::string& manual_trigger_name() const { return manual_trigger_name_; }
+  void set_manual_trigger_name(const std::string& value) { manual_trigger_name_ = value; _has_field_.set(4); }
+
+  bool has_histogram() const { return _has_field_[5]; }
+  const TriggerRule_HistogramTrigger& histogram() const { return *histogram_; }
+  TriggerRule_HistogramTrigger* mutable_histogram() { _has_field_.set(5); return histogram_.get(); }
+
+  bool has_repeating_interval() const { return _has_field_[6]; }
+  const TriggerRule_RepeatingInterval& repeating_interval() const { return *repeating_interval_; }
+  TriggerRule_RepeatingInterval* mutable_repeating_interval() { _has_field_.set(6); return repeating_interval_.get(); }
+
+ private:
+  std::string name_{};
+  float trigger_chance_{};
+  uint64_t delay_ms_{};
+  uint64_t activation_delay_ms_{};
+  std::string manual_trigger_name_{};
+  ::protozero::CopyablePtr<TriggerRule_HistogramTrigger> histogram_;
+  ::protozero::CopyablePtr<TriggerRule_RepeatingInterval> repeating_interval_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TriggerRule_RepeatingInterval : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPeriodMsFieldNumber = 1,
+    kRandomizedFieldNumber = 2,
+  };
+
+  TriggerRule_RepeatingInterval();
+  ~TriggerRule_RepeatingInterval() override;
+  TriggerRule_RepeatingInterval(TriggerRule_RepeatingInterval&&) noexcept;
+  TriggerRule_RepeatingInterval& operator=(TriggerRule_RepeatingInterval&&);
+  TriggerRule_RepeatingInterval(const TriggerRule_RepeatingInterval&);
+  TriggerRule_RepeatingInterval& operator=(const TriggerRule_RepeatingInterval&);
+  bool operator==(const TriggerRule_RepeatingInterval&) const;
+  bool operator!=(const TriggerRule_RepeatingInterval& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_period_ms() const { return _has_field_[1]; }
+  uint64_t period_ms() const { return period_ms_; }
+  void set_period_ms(uint64_t value) { period_ms_ = value; _has_field_.set(1); }
+
+  bool has_randomized() const { return _has_field_[2]; }
+  bool randomized() const { return randomized_; }
+  void set_randomized(bool value) { randomized_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t period_ms_{};
+  bool randomized_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TriggerRule_HistogramTrigger : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kHistogramNameFieldNumber = 1,
+    kMinValueFieldNumber = 2,
+    kMaxValueFieldNumber = 3,
+  };
+
+  TriggerRule_HistogramTrigger();
+  ~TriggerRule_HistogramTrigger() override;
+  TriggerRule_HistogramTrigger(TriggerRule_HistogramTrigger&&) noexcept;
+  TriggerRule_HistogramTrigger& operator=(TriggerRule_HistogramTrigger&&);
+  TriggerRule_HistogramTrigger(const TriggerRule_HistogramTrigger&);
+  TriggerRule_HistogramTrigger& operator=(const TriggerRule_HistogramTrigger&);
+  bool operator==(const TriggerRule_HistogramTrigger&) const;
+  bool operator!=(const TriggerRule_HistogramTrigger& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_histogram_name() const { return _has_field_[1]; }
+  const std::string& histogram_name() const { return histogram_name_; }
+  void set_histogram_name(const std::string& value) { histogram_name_ = value; _has_field_.set(1); }
+
+  bool has_min_value() const { return _has_field_[2]; }
+  int64_t min_value() const { return min_value_; }
+  void set_min_value(int64_t value) { min_value_ = value; _has_field_.set(2); }
+
+  bool has_max_value() const { return _has_field_[3]; }
+  int64_t max_value() const { return max_value_; }
+  void set_max_value(int64_t value) { max_value_ = value; _has_field_.set(3); }
+
+ private:
+  std::string histogram_name_{};
+  int64_t min_value_{};
+  int64_t max_value_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_SCENARIO_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/etw/etw_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ETW_ETW_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ETW_ETW_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class EtwConfig;
+enum EtwConfig_KernelFlag : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum EtwConfig_KernelFlag : int {
+  EtwConfig_KernelFlag_CSWITCH = 0,
+  EtwConfig_KernelFlag_DISPATCHER = 1,
+};
+
+class PERFETTO_EXPORT_COMPONENT EtwConfig : public ::protozero::CppMessageObj {
+ public:
+  using KernelFlag = EtwConfig_KernelFlag;
+  static constexpr auto CSWITCH = EtwConfig_KernelFlag_CSWITCH;
+  static constexpr auto DISPATCHER = EtwConfig_KernelFlag_DISPATCHER;
+  static constexpr auto KernelFlag_MIN = EtwConfig_KernelFlag_CSWITCH;
+  static constexpr auto KernelFlag_MAX = EtwConfig_KernelFlag_DISPATCHER;
+  enum FieldNumbers {
+    kKernelFlagsFieldNumber = 1,
+  };
+
+  EtwConfig();
+  ~EtwConfig() override;
+  EtwConfig(EtwConfig&&) noexcept;
+  EtwConfig& operator=(EtwConfig&&);
+  EtwConfig(const EtwConfig&);
+  EtwConfig& operator=(const EtwConfig&);
+  bool operator==(const EtwConfig&) const;
+  bool operator!=(const EtwConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<EtwConfig_KernelFlag>& kernel_flags() const { return kernel_flags_; }
+  std::vector<EtwConfig_KernelFlag>* mutable_kernel_flags() { return &kernel_flags_; }
+  int kernel_flags_size() const { return static_cast<int>(kernel_flags_.size()); }
+  void clear_kernel_flags() { kernel_flags_.clear(); }
+  void add_kernel_flags(EtwConfig_KernelFlag value) { kernel_flags_.emplace_back(value); }
+  EtwConfig_KernelFlag* add_kernel_flags() { kernel_flags_.emplace_back(); return &kernel_flags_.back(); }
+
+ private:
+  std::vector<EtwConfig_KernelFlag> kernel_flags_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ETW_ETW_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/interceptor_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class InterceptorConfig;
+class ConsoleConfig;
+enum ConsoleConfig_Output : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT InterceptorConfig : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+    kConsoleConfigFieldNumber = 100,
+  };
+
+  InterceptorConfig();
+  ~InterceptorConfig() override;
+  InterceptorConfig(InterceptorConfig&&) noexcept;
+  InterceptorConfig& operator=(InterceptorConfig&&);
+  InterceptorConfig(const InterceptorConfig&);
+  InterceptorConfig& operator=(const InterceptorConfig&);
+  bool operator==(const InterceptorConfig&) const;
+  bool operator!=(const InterceptorConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+  bool has_console_config() const { return _has_field_[100]; }
+  const ConsoleConfig& console_config() const { return *console_config_; }
+  ConsoleConfig* mutable_console_config() { _has_field_.set(100); return console_config_.get(); }
+
+ private:
+  std::string name_{};
+  ::protozero::CopyablePtr<ConsoleConfig> console_config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<101> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/stress_test_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class StressTestConfig;
+class StressTestConfig_WriterTiming;
+class TraceConfig;
+class TraceConfig_CmdTraceStartDelay;
+class TraceConfig_AndroidReportConfig;
+class TraceConfig_TraceFilter;
+class TraceConfig_TraceFilter_StringFilterChain;
+class TraceConfig_TraceFilter_StringFilterRule;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_ProducerConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_DataSource;
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+class TraceConfig_BufferConfig;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TraceFilter_StringFilterPolicy : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+enum TraceConfig_BufferConfig_FillPolicy : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT StressTestConfig : public ::protozero::CppMessageObj {
+ public:
+  using WriterTiming = StressTestConfig_WriterTiming;
+  enum FieldNumbers {
+    kTraceConfigFieldNumber = 1,
+    kShmemSizeKbFieldNumber = 2,
+    kShmemPageSizeKbFieldNumber = 3,
+    kNumProcessesFieldNumber = 4,
+    kNumThreadsFieldNumber = 5,
+    kMaxEventsFieldNumber = 6,
+    kNestingFieldNumber = 7,
+    kSteadyStateTimingsFieldNumber = 8,
+    kBurstPeriodMsFieldNumber = 9,
+    kBurstDurationMsFieldNumber = 10,
+    kBurstTimingsFieldNumber = 11,
+  };
+
+  StressTestConfig();
+  ~StressTestConfig() override;
+  StressTestConfig(StressTestConfig&&) noexcept;
+  StressTestConfig& operator=(StressTestConfig&&);
+  StressTestConfig(const StressTestConfig&);
+  StressTestConfig& operator=(const StressTestConfig&);
+  bool operator==(const StressTestConfig&) const;
+  bool operator!=(const StressTestConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_config() const { return _has_field_[1]; }
+  const TraceConfig& trace_config() const { return *trace_config_; }
+  TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
+
+  bool has_shmem_size_kb() const { return _has_field_[2]; }
+  uint32_t shmem_size_kb() const { return shmem_size_kb_; }
+  void set_shmem_size_kb(uint32_t value) { shmem_size_kb_ = value; _has_field_.set(2); }
+
+  bool has_shmem_page_size_kb() const { return _has_field_[3]; }
+  uint32_t shmem_page_size_kb() const { return shmem_page_size_kb_; }
+  void set_shmem_page_size_kb(uint32_t value) { shmem_page_size_kb_ = value; _has_field_.set(3); }
+
+  bool has_num_processes() const { return _has_field_[4]; }
+  uint32_t num_processes() const { return num_processes_; }
+  void set_num_processes(uint32_t value) { num_processes_ = value; _has_field_.set(4); }
+
+  bool has_num_threads() const { return _has_field_[5]; }
+  uint32_t num_threads() const { return num_threads_; }
+  void set_num_threads(uint32_t value) { num_threads_ = value; _has_field_.set(5); }
+
+  bool has_max_events() const { return _has_field_[6]; }
+  uint32_t max_events() const { return max_events_; }
+  void set_max_events(uint32_t value) { max_events_ = value; _has_field_.set(6); }
+
+  bool has_nesting() const { return _has_field_[7]; }
+  uint32_t nesting() const { return nesting_; }
+  void set_nesting(uint32_t value) { nesting_ = value; _has_field_.set(7); }
+
+  bool has_steady_state_timings() const { return _has_field_[8]; }
+  const StressTestConfig_WriterTiming& steady_state_timings() const { return *steady_state_timings_; }
+  StressTestConfig_WriterTiming* mutable_steady_state_timings() { _has_field_.set(8); return steady_state_timings_.get(); }
+
+  bool has_burst_period_ms() const { return _has_field_[9]; }
+  uint32_t burst_period_ms() const { return burst_period_ms_; }
+  void set_burst_period_ms(uint32_t value) { burst_period_ms_ = value; _has_field_.set(9); }
+
+  bool has_burst_duration_ms() const { return _has_field_[10]; }
+  uint32_t burst_duration_ms() const { return burst_duration_ms_; }
+  void set_burst_duration_ms(uint32_t value) { burst_duration_ms_ = value; _has_field_.set(10); }
+
+  bool has_burst_timings() const { return _has_field_[11]; }
+  const StressTestConfig_WriterTiming& burst_timings() const { return *burst_timings_; }
+  StressTestConfig_WriterTiming* mutable_burst_timings() { _has_field_.set(11); return burst_timings_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TraceConfig> trace_config_;
+  uint32_t shmem_size_kb_{};
+  uint32_t shmem_page_size_kb_{};
+  uint32_t num_processes_{};
+  uint32_t num_threads_{};
+  uint32_t max_events_{};
+  uint32_t nesting_{};
+  ::protozero::CopyablePtr<StressTestConfig_WriterTiming> steady_state_timings_;
+  uint32_t burst_period_ms_{};
+  uint32_t burst_duration_ms_{};
+  ::protozero::CopyablePtr<StressTestConfig_WriterTiming> burst_timings_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<12> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT StressTestConfig_WriterTiming : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPayloadMeanFieldNumber = 1,
+    kPayloadStddevFieldNumber = 2,
+    kRateMeanFieldNumber = 3,
+    kRateStddevFieldNumber = 4,
+    kPayloadWriteTimeMsFieldNumber = 5,
+  };
+
+  StressTestConfig_WriterTiming();
+  ~StressTestConfig_WriterTiming() override;
+  StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept;
+  StressTestConfig_WriterTiming& operator=(StressTestConfig_WriterTiming&&);
+  StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&);
+  StressTestConfig_WriterTiming& operator=(const StressTestConfig_WriterTiming&);
+  bool operator==(const StressTestConfig_WriterTiming&) const;
+  bool operator!=(const StressTestConfig_WriterTiming& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_payload_mean() const { return _has_field_[1]; }
+  double payload_mean() const { return payload_mean_; }
+  void set_payload_mean(double value) { payload_mean_ = value; _has_field_.set(1); }
+
+  bool has_payload_stddev() const { return _has_field_[2]; }
+  double payload_stddev() const { return payload_stddev_; }
+  void set_payload_stddev(double value) { payload_stddev_ = value; _has_field_.set(2); }
+
+  bool has_rate_mean() const { return _has_field_[3]; }
+  double rate_mean() const { return rate_mean_; }
+  void set_rate_mean(double value) { rate_mean_ = value; _has_field_.set(3); }
+
+  bool has_rate_stddev() const { return _has_field_[4]; }
+  double rate_stddev() const { return rate_stddev_; }
+  void set_rate_stddev(double value) { rate_stddev_ = value; _has_field_.set(4); }
+
+  bool has_payload_write_time_ms() const { return _has_field_[5]; }
+  uint32_t payload_write_time_ms() const { return payload_write_time_ms_; }
+  void set_payload_write_time_ms(uint32_t value) { payload_write_time_ms_ = value; _has_field_.set(5); }
+
+ private:
+  double payload_mean_{};
+  double payload_stddev_{};
+  double rate_mean_{};
+  double rate_stddev_{};
+  uint32_t payload_write_time_ms_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/test_config.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TestConfig;
+class TestConfig_DummyFields;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TestConfig : public ::protozero::CppMessageObj {
+ public:
+  using DummyFields = TestConfig_DummyFields;
+  enum FieldNumbers {
+    kMessageCountFieldNumber = 1,
+    kMaxMessagesPerSecondFieldNumber = 2,
+    kSeedFieldNumber = 3,
+    kMessageSizeFieldNumber = 4,
+    kSendBatchOnRegisterFieldNumber = 5,
+    kDummyFieldsFieldNumber = 6,
+  };
+
+  TestConfig();
+  ~TestConfig() override;
+  TestConfig(TestConfig&&) noexcept;
+  TestConfig& operator=(TestConfig&&);
+  TestConfig(const TestConfig&);
+  TestConfig& operator=(const TestConfig&);
+  bool operator==(const TestConfig&) const;
+  bool operator!=(const TestConfig& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_message_count() const { return _has_field_[1]; }
+  uint32_t message_count() const { return message_count_; }
+  void set_message_count(uint32_t value) { message_count_ = value; _has_field_.set(1); }
+
+  bool has_max_messages_per_second() const { return _has_field_[2]; }
+  uint32_t max_messages_per_second() const { return max_messages_per_second_; }
+  void set_max_messages_per_second(uint32_t value) { max_messages_per_second_ = value; _has_field_.set(2); }
+
+  bool has_seed() const { return _has_field_[3]; }
+  uint32_t seed() const { return seed_; }
+  void set_seed(uint32_t value) { seed_ = value; _has_field_.set(3); }
+
+  bool has_message_size() const { return _has_field_[4]; }
+  uint32_t message_size() const { return message_size_; }
+  void set_message_size(uint32_t value) { message_size_ = value; _has_field_.set(4); }
+
+  bool has_send_batch_on_register() const { return _has_field_[5]; }
+  bool send_batch_on_register() const { return send_batch_on_register_; }
+  void set_send_batch_on_register(bool value) { send_batch_on_register_ = value; _has_field_.set(5); }
+
+  bool has_dummy_fields() const { return _has_field_[6]; }
+  const TestConfig_DummyFields& dummy_fields() const { return *dummy_fields_; }
+  TestConfig_DummyFields* mutable_dummy_fields() { _has_field_.set(6); return dummy_fields_.get(); }
+
+ private:
+  uint32_t message_count_{};
+  uint32_t max_messages_per_second_{};
+  uint32_t seed_{};
+  uint32_t message_size_{};
+  bool send_batch_on_register_{};
+  ::protozero::CopyablePtr<TestConfig_DummyFields> dummy_fields_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TestConfig_DummyFields : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kFieldUint32FieldNumber = 1,
+    kFieldInt32FieldNumber = 2,
+    kFieldUint64FieldNumber = 3,
+    kFieldInt64FieldNumber = 4,
+    kFieldFixed64FieldNumber = 5,
+    kFieldSfixed64FieldNumber = 6,
+    kFieldFixed32FieldNumber = 7,
+    kFieldSfixed32FieldNumber = 8,
+    kFieldDoubleFieldNumber = 9,
+    kFieldFloatFieldNumber = 10,
+    kFieldSint64FieldNumber = 11,
+    kFieldSint32FieldNumber = 12,
+    kFieldStringFieldNumber = 13,
+    kFieldBytesFieldNumber = 14,
+  };
+
+  TestConfig_DummyFields();
+  ~TestConfig_DummyFields() override;
+  TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept;
+  TestConfig_DummyFields& operator=(TestConfig_DummyFields&&);
+  TestConfig_DummyFields(const TestConfig_DummyFields&);
+  TestConfig_DummyFields& operator=(const TestConfig_DummyFields&);
+  bool operator==(const TestConfig_DummyFields&) const;
+  bool operator!=(const TestConfig_DummyFields& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_field_uint32() const { return _has_field_[1]; }
+  uint32_t field_uint32() const { return field_uint32_; }
+  void set_field_uint32(uint32_t value) { field_uint32_ = value; _has_field_.set(1); }
+
+  bool has_field_int32() const { return _has_field_[2]; }
+  int32_t field_int32() const { return field_int32_; }
+  void set_field_int32(int32_t value) { field_int32_ = value; _has_field_.set(2); }
+
+  bool has_field_uint64() const { return _has_field_[3]; }
+  uint64_t field_uint64() const { return field_uint64_; }
+  void set_field_uint64(uint64_t value) { field_uint64_ = value; _has_field_.set(3); }
+
+  bool has_field_int64() const { return _has_field_[4]; }
+  int64_t field_int64() const { return field_int64_; }
+  void set_field_int64(int64_t value) { field_int64_ = value; _has_field_.set(4); }
+
+  bool has_field_fixed64() const { return _has_field_[5]; }
+  uint64_t field_fixed64() const { return field_fixed64_; }
+  void set_field_fixed64(uint64_t value) { field_fixed64_ = value; _has_field_.set(5); }
+
+  bool has_field_sfixed64() const { return _has_field_[6]; }
+  int64_t field_sfixed64() const { return field_sfixed64_; }
+  void set_field_sfixed64(int64_t value) { field_sfixed64_ = value; _has_field_.set(6); }
+
+  bool has_field_fixed32() const { return _has_field_[7]; }
+  uint32_t field_fixed32() const { return field_fixed32_; }
+  void set_field_fixed32(uint32_t value) { field_fixed32_ = value; _has_field_.set(7); }
+
+  bool has_field_sfixed32() const { return _has_field_[8]; }
+  int32_t field_sfixed32() const { return field_sfixed32_; }
+  void set_field_sfixed32(int32_t value) { field_sfixed32_ = value; _has_field_.set(8); }
+
+  bool has_field_double() const { return _has_field_[9]; }
+  double field_double() const { return field_double_; }
+  void set_field_double(double value) { field_double_ = value; _has_field_.set(9); }
+
+  bool has_field_float() const { return _has_field_[10]; }
+  float field_float() const { return field_float_; }
+  void set_field_float(float value) { field_float_ = value; _has_field_.set(10); }
+
+  bool has_field_sint64() const { return _has_field_[11]; }
+  int64_t field_sint64() const { return field_sint64_; }
+  void set_field_sint64(int64_t value) { field_sint64_ = value; _has_field_.set(11); }
+
+  bool has_field_sint32() const { return _has_field_[12]; }
+  int32_t field_sint32() const { return field_sint32_; }
+  void set_field_sint32(int32_t value) { field_sint32_ = value; _has_field_.set(12); }
+
+  bool has_field_string() const { return _has_field_[13]; }
+  const std::string& field_string() const { return field_string_; }
+  void set_field_string(const std::string& value) { field_string_ = value; _has_field_.set(13); }
+
+  bool has_field_bytes() const { return _has_field_[14]; }
+  const std::string& field_bytes() const { return field_bytes_; }
+  void set_field_bytes(const std::string& value) { field_bytes_ = value; _has_field_.set(14); }
+  void set_field_bytes(const void* p, size_t s) { field_bytes_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(14); }
+
+ private:
+  uint32_t field_uint32_{};
+  int32_t field_int32_{};
+  uint64_t field_uint64_{};
+  int64_t field_int64_{};
+  uint64_t field_fixed64_{};
+  int64_t field_sfixed64_{};
+  uint32_t field_fixed32_{};
+  int32_t field_sfixed32_{};
+  double field_double_{};
+  float field_float_{};
+  int64_t field_sint64_{};
+  int32_t field_sint32_{};
+  std::string field_string_{};
+  std::string field_bytes_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<15> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_game_intervention_list_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_GAME_INTERVENTION_LIST_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_GAME_INTERVENTION_LIST_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class AndroidGameInterventionListConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidGameInterventionListConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidGameInterventionListConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidGameInterventionListConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_package_name_filter() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> package_name_filter() const { return GetRepeated<::protozero::ConstChars>(1); }
+};
+
+class AndroidGameInterventionListConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidGameInterventionListConfig_Decoder;
+  enum : int32_t {
+    kPackageNameFilterFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidGameInterventionListConfig"; }
+
+
+  using FieldMetadata_PackageNameFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidGameInterventionListConfig>;
+
+  static constexpr FieldMetadata_PackageNameFilter kPackageNameFilter{};
+  void add_package_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PackageNameFilter::kFieldId, data, size);
+  }
+  void add_package_name_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PackageNameFilter::kFieldId, chars.data, chars.size);
+  }
+  void add_package_name_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PackageNameFilter::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_log_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum AndroidLogId : int32_t;
+enum AndroidLogPriority : int32_t;
+
+class AndroidLogConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidLogConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidLogConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidLogConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_log_ids() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> log_ids() const { return GetRepeated<int32_t>(1); }
+  bool has_min_prio() const { return at<3>().valid(); }
+  int32_t min_prio() const { return at<3>().as_int32(); }
+  bool has_filter_tags() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> filter_tags() const { return GetRepeated<::protozero::ConstChars>(4); }
+};
+
+class AndroidLogConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidLogConfig_Decoder;
+  enum : int32_t {
+    kLogIdsFieldNumber = 1,
+    kMinPrioFieldNumber = 3,
+    kFilterTagsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidLogConfig"; }
+
+
+  using FieldMetadata_LogIds =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::AndroidLogId,
+      AndroidLogConfig>;
+
+  static constexpr FieldMetadata_LogIds kLogIds{};
+  void add_log_ids(::perfetto::protos::pbzero::AndroidLogId value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MinPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::AndroidLogPriority,
+      AndroidLogConfig>;
+
+  static constexpr FieldMetadata_MinPrio kMinPrio{};
+  void set_min_prio(::perfetto::protos::pbzero::AndroidLogPriority value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinPrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FilterTags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogConfig>;
+
+  static constexpr FieldMetadata_FilterTags kFilterTags{};
+  void add_filter_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FilterTags::kFieldId, data, size);
+  }
+  void add_filter_tags(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FilterTags::kFieldId, chars.data, chars.size);
+  }
+  void add_filter_tags(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FilterTags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_polled_state_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class AndroidPolledStateConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidPolledStateConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidPolledStateConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidPolledStateConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_poll_ms() const { return at<1>().valid(); }
+  uint32_t poll_ms() const { return at<1>().as_uint32(); }
+};
+
+class AndroidPolledStateConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidPolledStateConfig_Decoder;
+  enum : int32_t {
+    kPollMsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidPolledStateConfig"; }
+
+
+  using FieldMetadata_PollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidPolledStateConfig>;
+
+  static constexpr FieldMetadata_PollMs kPollMs{};
+  void set_poll_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PollMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_sdk_sysprop_guard_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SDK_SYSPROP_GUARD_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SDK_SYSPROP_GUARD_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class AndroidSdkSyspropGuardConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidSdkSyspropGuardConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidSdkSyspropGuardConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidSdkSyspropGuardConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_surfaceflinger_skia_track_events() const { return at<1>().valid(); }
+  bool surfaceflinger_skia_track_events() const { return at<1>().as_bool(); }
+  bool has_hwui_skia_track_events() const { return at<2>().valid(); }
+  bool hwui_skia_track_events() const { return at<2>().as_bool(); }
+  bool has_hwui_package_name_filter() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> hwui_package_name_filter() const { return GetRepeated<::protozero::ConstChars>(3); }
+};
+
+class AndroidSdkSyspropGuardConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidSdkSyspropGuardConfig_Decoder;
+  enum : int32_t {
+    kSurfaceflingerSkiaTrackEventsFieldNumber = 1,
+    kHwuiSkiaTrackEventsFieldNumber = 2,
+    kHwuiPackageNameFilterFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidSdkSyspropGuardConfig"; }
+
+
+  using FieldMetadata_SurfaceflingerSkiaTrackEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidSdkSyspropGuardConfig>;
+
+  static constexpr FieldMetadata_SurfaceflingerSkiaTrackEvents kSurfaceflingerSkiaTrackEvents{};
+  void set_surfaceflinger_skia_track_events(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SurfaceflingerSkiaTrackEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HwuiSkiaTrackEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidSdkSyspropGuardConfig>;
+
+  static constexpr FieldMetadata_HwuiSkiaTrackEvents kHwuiSkiaTrackEvents{};
+  void set_hwui_skia_track_events(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwuiSkiaTrackEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HwuiPackageNameFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidSdkSyspropGuardConfig>;
+
+  static constexpr FieldMetadata_HwuiPackageNameFilter kHwuiPackageNameFilter{};
+  void add_hwui_package_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HwuiPackageNameFilter::kFieldId, data, size);
+  }
+  void add_hwui_package_name_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HwuiPackageNameFilter::kFieldId, chars.data, chars.size);
+  }
+  void add_hwui_package_name_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwuiPackageNameFilter::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/android_system_property_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SYSTEM_PROPERTY_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_SYSTEM_PROPERTY_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class AndroidSystemPropertyConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidSystemPropertyConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidSystemPropertyConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidSystemPropertyConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_poll_ms() const { return at<1>().valid(); }
+  uint32_t poll_ms() const { return at<1>().as_uint32(); }
+  bool has_property_name() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> property_name() const { return GetRepeated<::protozero::ConstChars>(2); }
+};
+
+class AndroidSystemPropertyConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidSystemPropertyConfig_Decoder;
+  enum : int32_t {
+    kPollMsFieldNumber = 1,
+    kPropertyNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidSystemPropertyConfig"; }
+
+
+  using FieldMetadata_PollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidSystemPropertyConfig>;
+
+  static constexpr FieldMetadata_PollMs kPollMs{};
+  void set_poll_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PollMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PropertyName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidSystemPropertyConfig>;
+
+  static constexpr FieldMetadata_PropertyName kPropertyName{};
+  void add_property_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PropertyName::kFieldId, data, size);
+  }
+  void add_property_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PropertyName::kFieldId, chars.data, chars.size);
+  }
+  void add_property_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PropertyName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/network_trace_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_NETWORK_TRACE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_NETWORK_TRACE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class NetworkPacketTraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetworkPacketTraceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetworkPacketTraceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetworkPacketTraceConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_poll_ms() const { return at<1>().valid(); }
+  uint32_t poll_ms() const { return at<1>().as_uint32(); }
+  bool has_aggregation_threshold() const { return at<2>().valid(); }
+  uint32_t aggregation_threshold() const { return at<2>().as_uint32(); }
+  bool has_intern_limit() const { return at<3>().valid(); }
+  uint32_t intern_limit() const { return at<3>().as_uint32(); }
+  bool has_drop_local_port() const { return at<4>().valid(); }
+  bool drop_local_port() const { return at<4>().as_bool(); }
+  bool has_drop_remote_port() const { return at<5>().valid(); }
+  bool drop_remote_port() const { return at<5>().as_bool(); }
+  bool has_drop_tcp_flags() const { return at<6>().valid(); }
+  bool drop_tcp_flags() const { return at<6>().as_bool(); }
+};
+
+class NetworkPacketTraceConfig : public ::protozero::Message {
+ public:
+  using Decoder = NetworkPacketTraceConfig_Decoder;
+  enum : int32_t {
+    kPollMsFieldNumber = 1,
+    kAggregationThresholdFieldNumber = 2,
+    kInternLimitFieldNumber = 3,
+    kDropLocalPortFieldNumber = 4,
+    kDropRemotePortFieldNumber = 5,
+    kDropTcpFlagsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetworkPacketTraceConfig"; }
+
+
+  using FieldMetadata_PollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_PollMs kPollMs{};
+  void set_poll_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PollMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AggregationThreshold =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_AggregationThreshold kAggregationThreshold{};
+  void set_aggregation_threshold(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AggregationThreshold::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InternLimit =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_InternLimit kInternLimit{};
+  void set_intern_limit(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InternLimit::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DropLocalPort =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_DropLocalPort kDropLocalPort{};
+  void set_drop_local_port(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DropLocalPort::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DropRemotePort =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_DropRemotePort kDropRemotePort{};
+  void set_drop_remote_port(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DropRemotePort::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DropTcpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      NetworkPacketTraceConfig>;
+
+  static constexpr FieldMetadata_DropTcpFlags kDropTcpFlags{};
+  void set_drop_tcp_flags(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DropTcpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/packages_list_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class PackagesListConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PackagesListConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PackagesListConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PackagesListConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_package_name_filter() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> package_name_filter() const { return GetRepeated<::protozero::ConstChars>(1); }
+};
+
+class PackagesListConfig : public ::protozero::Message {
+ public:
+  using Decoder = PackagesListConfig_Decoder;
+  enum : int32_t {
+    kPackageNameFilterFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PackagesListConfig"; }
+
+
+  using FieldMetadata_PackageNameFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PackagesListConfig>;
+
+  static constexpr FieldMetadata_PackageNameFilter kPackageNameFilter{};
+  void add_package_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PackageNameFilter::kFieldId, data, size);
+  }
+  void add_package_name_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PackageNameFilter::kFieldId, chars.data, chars.size);
+  }
+  void add_package_name_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PackageNameFilter::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/surfaceflinger_layers_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_LAYERS_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_LAYERS_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig {
+enum Mode : int32_t;
+}  // namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig
+using SurfaceFlingerLayersConfig_Mode = perfetto_pbzero_enum_SurfaceFlingerLayersConfig::Mode;
+namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig {
+enum TraceFlag : int32_t;
+}  // namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig
+using SurfaceFlingerLayersConfig_TraceFlag = perfetto_pbzero_enum_SurfaceFlingerLayersConfig::TraceFlag;
+
+namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig {
+enum Mode : int32_t {
+  MODE_UNSPECIFIED = 0,
+  MODE_ACTIVE = 1,
+  MODE_GENERATED = 2,
+  MODE_DUMP = 3,
+  MODE_GENERATED_BUGREPORT_ONLY = 4,
+};
+} // namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig
+using SurfaceFlingerLayersConfig_Mode = perfetto_pbzero_enum_SurfaceFlingerLayersConfig::Mode;
+
+
+constexpr SurfaceFlingerLayersConfig_Mode SurfaceFlingerLayersConfig_Mode_MIN = SurfaceFlingerLayersConfig_Mode::MODE_UNSPECIFIED;
+constexpr SurfaceFlingerLayersConfig_Mode SurfaceFlingerLayersConfig_Mode_MAX = SurfaceFlingerLayersConfig_Mode::MODE_GENERATED_BUGREPORT_ONLY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* SurfaceFlingerLayersConfig_Mode_Name(::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode::MODE_UNSPECIFIED:
+    return "MODE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode::MODE_ACTIVE:
+    return "MODE_ACTIVE";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode::MODE_GENERATED:
+    return "MODE_GENERATED";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode::MODE_DUMP:
+    return "MODE_DUMP";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode::MODE_GENERATED_BUGREPORT_ONLY:
+    return "MODE_GENERATED_BUGREPORT_ONLY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig {
+enum TraceFlag : int32_t {
+  TRACE_FLAG_UNSPECIFIED = 0,
+  TRACE_FLAG_INPUT = 2,
+  TRACE_FLAG_COMPOSITION = 4,
+  TRACE_FLAG_EXTRA = 8,
+  TRACE_FLAG_HWC = 16,
+  TRACE_FLAG_BUFFERS = 32,
+  TRACE_FLAG_VIRTUAL_DISPLAYS = 64,
+  TRACE_FLAG_ALL = 14,
+};
+} // namespace perfetto_pbzero_enum_SurfaceFlingerLayersConfig
+using SurfaceFlingerLayersConfig_TraceFlag = perfetto_pbzero_enum_SurfaceFlingerLayersConfig::TraceFlag;
+
+
+constexpr SurfaceFlingerLayersConfig_TraceFlag SurfaceFlingerLayersConfig_TraceFlag_MIN = SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_UNSPECIFIED;
+constexpr SurfaceFlingerLayersConfig_TraceFlag SurfaceFlingerLayersConfig_TraceFlag_MAX = SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_VIRTUAL_DISPLAYS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* SurfaceFlingerLayersConfig_TraceFlag_Name(::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_UNSPECIFIED:
+    return "TRACE_FLAG_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_INPUT:
+    return "TRACE_FLAG_INPUT";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_COMPOSITION:
+    return "TRACE_FLAG_COMPOSITION";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_EXTRA:
+    return "TRACE_FLAG_EXTRA";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_HWC:
+    return "TRACE_FLAG_HWC";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_BUFFERS:
+    return "TRACE_FLAG_BUFFERS";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_VIRTUAL_DISPLAYS:
+    return "TRACE_FLAG_VIRTUAL_DISPLAYS";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag::TRACE_FLAG_ALL:
+    return "TRACE_FLAG_ALL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class SurfaceFlingerLayersConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SurfaceFlingerLayersConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SurfaceFlingerLayersConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SurfaceFlingerLayersConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+  bool has_trace_flags() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> trace_flags() const { return GetRepeated<int32_t>(2); }
+};
+
+class SurfaceFlingerLayersConfig : public ::protozero::Message {
+ public:
+  using Decoder = SurfaceFlingerLayersConfig_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+    kTraceFlagsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SurfaceFlingerLayersConfig"; }
+
+
+  using Mode = ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode;
+  static inline const char* Mode_Name(Mode value) {
+    return ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode_Name(value);
+  }
+
+  using TraceFlag = ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag;
+  static inline const char* TraceFlag_Name(TraceFlag value) {
+    return ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag_Name(value);
+  }
+  static inline const Mode MODE_UNSPECIFIED = Mode::MODE_UNSPECIFIED;
+  static inline const Mode MODE_ACTIVE = Mode::MODE_ACTIVE;
+  static inline const Mode MODE_GENERATED = Mode::MODE_GENERATED;
+  static inline const Mode MODE_DUMP = Mode::MODE_DUMP;
+  static inline const Mode MODE_GENERATED_BUGREPORT_ONLY = Mode::MODE_GENERATED_BUGREPORT_ONLY;
+  static inline const TraceFlag TRACE_FLAG_UNSPECIFIED = TraceFlag::TRACE_FLAG_UNSPECIFIED;
+  static inline const TraceFlag TRACE_FLAG_INPUT = TraceFlag::TRACE_FLAG_INPUT;
+  static inline const TraceFlag TRACE_FLAG_COMPOSITION = TraceFlag::TRACE_FLAG_COMPOSITION;
+  static inline const TraceFlag TRACE_FLAG_EXTRA = TraceFlag::TRACE_FLAG_EXTRA;
+  static inline const TraceFlag TRACE_FLAG_HWC = TraceFlag::TRACE_FLAG_HWC;
+  static inline const TraceFlag TRACE_FLAG_BUFFERS = TraceFlag::TRACE_FLAG_BUFFERS;
+  static inline const TraceFlag TRACE_FLAG_VIRTUAL_DISPLAYS = TraceFlag::TRACE_FLAG_VIRTUAL_DISPLAYS;
+  static inline const TraceFlag TRACE_FLAG_ALL = TraceFlag::TRACE_FLAG_ALL;
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode,
+      SurfaceFlingerLayersConfig>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_Mode value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag,
+      SurfaceFlingerLayersConfig>;
+
+  static constexpr FieldMetadata_TraceFlags kTraceFlags{};
+  void add_trace_flags(::perfetto::protos::pbzero::SurfaceFlingerLayersConfig_TraceFlag value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/android/surfaceflinger_transactions_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_TRANSACTIONS_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_SURFACEFLINGER_TRANSACTIONS_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig {
+enum Mode : int32_t;
+}  // namespace perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig
+using SurfaceFlingerTransactionsConfig_Mode = perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig::Mode;
+
+namespace perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig {
+enum Mode : int32_t {
+  MODE_UNSPECIFIED = 0,
+  MODE_CONTINUOUS = 1,
+  MODE_ACTIVE = 2,
+};
+} // namespace perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig
+using SurfaceFlingerTransactionsConfig_Mode = perfetto_pbzero_enum_SurfaceFlingerTransactionsConfig::Mode;
+
+
+constexpr SurfaceFlingerTransactionsConfig_Mode SurfaceFlingerTransactionsConfig_Mode_MIN = SurfaceFlingerTransactionsConfig_Mode::MODE_UNSPECIFIED;
+constexpr SurfaceFlingerTransactionsConfig_Mode SurfaceFlingerTransactionsConfig_Mode_MAX = SurfaceFlingerTransactionsConfig_Mode::MODE_ACTIVE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* SurfaceFlingerTransactionsConfig_Mode_Name(::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode::MODE_UNSPECIFIED:
+    return "MODE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode::MODE_CONTINUOUS:
+    return "MODE_CONTINUOUS";
+
+  case ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode::MODE_ACTIVE:
+    return "MODE_ACTIVE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class SurfaceFlingerTransactionsConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SurfaceFlingerTransactionsConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SurfaceFlingerTransactionsConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SurfaceFlingerTransactionsConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+};
+
+class SurfaceFlingerTransactionsConfig : public ::protozero::Message {
+ public:
+  using Decoder = SurfaceFlingerTransactionsConfig_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SurfaceFlingerTransactionsConfig"; }
+
+
+  using Mode = ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode;
+  static inline const char* Mode_Name(Mode value) {
+    return ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode_Name(value);
+  }
+  static inline const Mode MODE_UNSPECIFIED = Mode::MODE_UNSPECIFIED;
+  static inline const Mode MODE_CONTINUOUS = Mode::MODE_CONTINUOUS;
+  static inline const Mode MODE_ACTIVE = Mode::MODE_ACTIVE;
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode,
+      SurfaceFlingerTransactionsConfig>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(::perfetto::protos::pbzero::SurfaceFlingerTransactionsConfig_Mode value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/ftrace/ftrace_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FtraceConfig_CompactSchedConfig;
+class FtraceConfig_PrintFilter;
+class FtraceConfig_PrintFilter_Rule;
+class FtraceConfig_PrintFilter_Rule_AtraceMessage;
+namespace perfetto_pbzero_enum_FtraceConfig {
+enum KsymsMemPolicy : int32_t;
+}  // namespace perfetto_pbzero_enum_FtraceConfig
+using FtraceConfig_KsymsMemPolicy = perfetto_pbzero_enum_FtraceConfig::KsymsMemPolicy;
+
+namespace perfetto_pbzero_enum_FtraceConfig {
+enum KsymsMemPolicy : int32_t {
+  KSYMS_UNSPECIFIED = 0,
+  KSYMS_CLEANUP_ON_STOP = 1,
+  KSYMS_RETAIN = 2,
+};
+} // namespace perfetto_pbzero_enum_FtraceConfig
+using FtraceConfig_KsymsMemPolicy = perfetto_pbzero_enum_FtraceConfig::KsymsMemPolicy;
+
+
+constexpr FtraceConfig_KsymsMemPolicy FtraceConfig_KsymsMemPolicy_MIN = FtraceConfig_KsymsMemPolicy::KSYMS_UNSPECIFIED;
+constexpr FtraceConfig_KsymsMemPolicy FtraceConfig_KsymsMemPolicy_MAX = FtraceConfig_KsymsMemPolicy::KSYMS_RETAIN;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FtraceConfig_KsymsMemPolicy_Name(::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy::KSYMS_UNSPECIFIED:
+    return "KSYMS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy::KSYMS_CLEANUP_ON_STOP:
+    return "KSYMS_CLEANUP_ON_STOP";
+
+  case ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy::KSYMS_RETAIN:
+    return "KSYMS_RETAIN";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class FtraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/25, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ftrace_events() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> ftrace_events() const { return GetRepeated<::protozero::ConstChars>(1); }
+  bool has_atrace_categories() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> atrace_categories() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_atrace_apps() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> atrace_apps() const { return GetRepeated<::protozero::ConstChars>(3); }
+  bool has_buffer_size_kb() const { return at<10>().valid(); }
+  uint32_t buffer_size_kb() const { return at<10>().as_uint32(); }
+  bool has_drain_period_ms() const { return at<11>().valid(); }
+  uint32_t drain_period_ms() const { return at<11>().as_uint32(); }
+  bool has_compact_sched() const { return at<12>().valid(); }
+  ::protozero::ConstBytes compact_sched() const { return at<12>().as_bytes(); }
+  bool has_print_filter() const { return at<22>().valid(); }
+  ::protozero::ConstBytes print_filter() const { return at<22>().as_bytes(); }
+  bool has_symbolize_ksyms() const { return at<13>().valid(); }
+  bool symbolize_ksyms() const { return at<13>().as_bool(); }
+  bool has_ksyms_mem_policy() const { return at<17>().valid(); }
+  int32_t ksyms_mem_policy() const { return at<17>().as_int32(); }
+  bool has_initialize_ksyms_synchronously_for_testing() const { return at<14>().valid(); }
+  bool initialize_ksyms_synchronously_for_testing() const { return at<14>().as_bool(); }
+  bool has_throttle_rss_stat() const { return at<15>().valid(); }
+  bool throttle_rss_stat() const { return at<15>().as_bool(); }
+  bool has_disable_generic_events() const { return at<16>().valid(); }
+  bool disable_generic_events() const { return at<16>().as_bool(); }
+  bool has_syscall_events() const { return at<18>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> syscall_events() const { return GetRepeated<::protozero::ConstChars>(18); }
+  bool has_enable_function_graph() const { return at<19>().valid(); }
+  bool enable_function_graph() const { return at<19>().as_bool(); }
+  bool has_function_filters() const { return at<20>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> function_filters() const { return GetRepeated<::protozero::ConstChars>(20); }
+  bool has_function_graph_roots() const { return at<21>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> function_graph_roots() const { return GetRepeated<::protozero::ConstChars>(21); }
+  bool has_preserve_ftrace_buffer() const { return at<23>().valid(); }
+  bool preserve_ftrace_buffer() const { return at<23>().as_bool(); }
+  bool has_use_monotonic_raw_clock() const { return at<24>().valid(); }
+  bool use_monotonic_raw_clock() const { return at<24>().as_bool(); }
+  bool has_instance_name() const { return at<25>().valid(); }
+  ::protozero::ConstChars instance_name() const { return at<25>().as_string(); }
+};
+
+class FtraceConfig : public ::protozero::Message {
+ public:
+  using Decoder = FtraceConfig_Decoder;
+  enum : int32_t {
+    kFtraceEventsFieldNumber = 1,
+    kAtraceCategoriesFieldNumber = 2,
+    kAtraceAppsFieldNumber = 3,
+    kBufferSizeKbFieldNumber = 10,
+    kDrainPeriodMsFieldNumber = 11,
+    kCompactSchedFieldNumber = 12,
+    kPrintFilterFieldNumber = 22,
+    kSymbolizeKsymsFieldNumber = 13,
+    kKsymsMemPolicyFieldNumber = 17,
+    kInitializeKsymsSynchronouslyForTestingFieldNumber = 14,
+    kThrottleRssStatFieldNumber = 15,
+    kDisableGenericEventsFieldNumber = 16,
+    kSyscallEventsFieldNumber = 18,
+    kEnableFunctionGraphFieldNumber = 19,
+    kFunctionFiltersFieldNumber = 20,
+    kFunctionGraphRootsFieldNumber = 21,
+    kPreserveFtraceBufferFieldNumber = 23,
+    kUseMonotonicRawClockFieldNumber = 24,
+    kInstanceNameFieldNumber = 25,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceConfig"; }
+
+  using CompactSchedConfig = ::perfetto::protos::pbzero::FtraceConfig_CompactSchedConfig;
+  using PrintFilter = ::perfetto::protos::pbzero::FtraceConfig_PrintFilter;
+
+  using KsymsMemPolicy = ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy;
+  static inline const char* KsymsMemPolicy_Name(KsymsMemPolicy value) {
+    return ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy_Name(value);
+  }
+  static inline const KsymsMemPolicy KSYMS_UNSPECIFIED = KsymsMemPolicy::KSYMS_UNSPECIFIED;
+  static inline const KsymsMemPolicy KSYMS_CLEANUP_ON_STOP = KsymsMemPolicy::KSYMS_CLEANUP_ON_STOP;
+  static inline const KsymsMemPolicy KSYMS_RETAIN = KsymsMemPolicy::KSYMS_RETAIN;
+
+  using FieldMetadata_FtraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_FtraceEvents kFtraceEvents{};
+  void add_ftrace_events(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FtraceEvents::kFieldId, data, size);
+  }
+  void add_ftrace_events(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FtraceEvents::kFieldId, chars.data, chars.size);
+  }
+  void add_ftrace_events(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FtraceEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AtraceCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_AtraceCategories kAtraceCategories{};
+  void add_atrace_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AtraceCategories::kFieldId, data, size);
+  }
+  void add_atrace_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AtraceCategories::kFieldId, chars.data, chars.size);
+  }
+  void add_atrace_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AtraceCategories::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AtraceApps =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_AtraceApps kAtraceApps{};
+  void add_atrace_apps(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AtraceApps::kFieldId, data, size);
+  }
+  void add_atrace_apps(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AtraceApps::kFieldId, chars.data, chars.size);
+  }
+  void add_atrace_apps(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AtraceApps::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BufferSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_BufferSizeKb kBufferSizeKb{};
+  void set_buffer_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferSizeKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DrainPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_DrainPeriodMs kDrainPeriodMs{};
+  void set_drain_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DrainPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CompactSched =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceConfig_CompactSchedConfig,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_CompactSched kCompactSched{};
+  template <typename T = FtraceConfig_CompactSchedConfig> T* set_compact_sched() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_PrintFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceConfig_PrintFilter,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_PrintFilter kPrintFilter{};
+  template <typename T = FtraceConfig_PrintFilter> T* set_print_filter() {
+    return BeginNestedMessage<T>(22);
+  }
+
+
+  using FieldMetadata_SymbolizeKsyms =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_SymbolizeKsyms kSymbolizeKsyms{};
+  void set_symbolize_ksyms(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SymbolizeKsyms::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KsymsMemPolicy =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_KsymsMemPolicy kKsymsMemPolicy{};
+  void set_ksyms_mem_policy(::perfetto::protos::pbzero::FtraceConfig_KsymsMemPolicy value) {
+    static constexpr uint32_t field_id = FieldMetadata_KsymsMemPolicy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InitializeKsymsSynchronouslyForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_InitializeKsymsSynchronouslyForTesting kInitializeKsymsSynchronouslyForTesting{};
+  void set_initialize_ksyms_synchronously_for_testing(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_InitializeKsymsSynchronouslyForTesting::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThrottleRssStat =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_ThrottleRssStat kThrottleRssStat{};
+  void set_throttle_rss_stat(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThrottleRssStat::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisableGenericEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_DisableGenericEvents kDisableGenericEvents{};
+  void set_disable_generic_events(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableGenericEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SyscallEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_SyscallEvents kSyscallEvents{};
+  void add_syscall_events(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SyscallEvents::kFieldId, data, size);
+  }
+  void add_syscall_events(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SyscallEvents::kFieldId, chars.data, chars.size);
+  }
+  void add_syscall_events(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SyscallEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnableFunctionGraph =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_EnableFunctionGraph kEnableFunctionGraph{};
+  void set_enable_function_graph(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnableFunctionGraph::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FunctionFilters =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_FunctionFilters kFunctionFilters{};
+  void add_function_filters(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionFilters::kFieldId, data, size);
+  }
+  void add_function_filters(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FunctionFilters::kFieldId, chars.data, chars.size);
+  }
+  void add_function_filters(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionFilters::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FunctionGraphRoots =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_FunctionGraphRoots kFunctionGraphRoots{};
+  void add_function_graph_roots(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionGraphRoots::kFieldId, data, size);
+  }
+  void add_function_graph_roots(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FunctionGraphRoots::kFieldId, chars.data, chars.size);
+  }
+  void add_function_graph_roots(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionGraphRoots::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PreserveFtraceBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_PreserveFtraceBuffer kPreserveFtraceBuffer{};
+  void set_preserve_ftrace_buffer(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreserveFtraceBuffer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UseMonotonicRawClock =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_UseMonotonicRawClock kUseMonotonicRawClock{};
+  void set_use_monotonic_raw_clock(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_UseMonotonicRawClock::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InstanceName =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig>;
+
+  static constexpr FieldMetadata_InstanceName kInstanceName{};
+  void set_instance_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_InstanceName::kFieldId, data, size);
+  }
+  void set_instance_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_InstanceName::kFieldId, chars.data, chars.size);
+  }
+  void set_instance_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstanceName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FtraceConfig_PrintFilter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceConfig_PrintFilter_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceConfig_PrintFilter_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceConfig_PrintFilter_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rules() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> rules() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class FtraceConfig_PrintFilter : public ::protozero::Message {
+ public:
+  using Decoder = FtraceConfig_PrintFilter_Decoder;
+  enum : int32_t {
+    kRulesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceConfig.PrintFilter"; }
+
+  using Rule = ::perfetto::protos::pbzero::FtraceConfig_PrintFilter_Rule;
+
+  using FieldMetadata_Rules =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceConfig_PrintFilter_Rule,
+      FtraceConfig_PrintFilter>;
+
+  static constexpr FieldMetadata_Rules kRules{};
+  template <typename T = FtraceConfig_PrintFilter_Rule> T* add_rules() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class FtraceConfig_PrintFilter_Rule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceConfig_PrintFilter_Rule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceConfig_PrintFilter_Rule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceConfig_PrintFilter_Rule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_prefix() const { return at<1>().valid(); }
+  ::protozero::ConstChars prefix() const { return at<1>().as_string(); }
+  bool has_atrace_msg() const { return at<3>().valid(); }
+  ::protozero::ConstBytes atrace_msg() const { return at<3>().as_bytes(); }
+  bool has_allow() const { return at<2>().valid(); }
+  bool allow() const { return at<2>().as_bool(); }
+};
+
+class FtraceConfig_PrintFilter_Rule : public ::protozero::Message {
+ public:
+  using Decoder = FtraceConfig_PrintFilter_Rule_Decoder;
+  enum : int32_t {
+    kPrefixFieldNumber = 1,
+    kAtraceMsgFieldNumber = 3,
+    kAllowFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceConfig.PrintFilter.Rule"; }
+
+  using AtraceMessage = ::perfetto::protos::pbzero::FtraceConfig_PrintFilter_Rule_AtraceMessage;
+
+  using FieldMetadata_Prefix =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig_PrintFilter_Rule>;
+
+  static constexpr FieldMetadata_Prefix kPrefix{};
+  void set_prefix(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Prefix::kFieldId, data, size);
+  }
+  void set_prefix(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Prefix::kFieldId, chars.data, chars.size);
+  }
+  void set_prefix(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prefix::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AtraceMsg =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceConfig_PrintFilter_Rule_AtraceMessage,
+      FtraceConfig_PrintFilter_Rule>;
+
+  static constexpr FieldMetadata_AtraceMsg kAtraceMsg{};
+  template <typename T = FtraceConfig_PrintFilter_Rule_AtraceMessage> T* set_atrace_msg() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_Allow =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig_PrintFilter_Rule>;
+
+  static constexpr FieldMetadata_Allow kAllow{};
+  void set_allow(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Allow::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FtraceConfig_PrintFilter_Rule_AtraceMessage_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceConfig_PrintFilter_Rule_AtraceMessage_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceConfig_PrintFilter_Rule_AtraceMessage_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceConfig_PrintFilter_Rule_AtraceMessage_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  ::protozero::ConstChars type() const { return at<1>().as_string(); }
+  bool has_prefix() const { return at<2>().valid(); }
+  ::protozero::ConstChars prefix() const { return at<2>().as_string(); }
+};
+
+class FtraceConfig_PrintFilter_Rule_AtraceMessage : public ::protozero::Message {
+ public:
+  using Decoder = FtraceConfig_PrintFilter_Rule_AtraceMessage_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kPrefixFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceConfig.PrintFilter.Rule.AtraceMessage"; }
+
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig_PrintFilter_Rule_AtraceMessage>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Type::kFieldId, data, size);
+  }
+  void set_type(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Type::kFieldId, chars.data, chars.size);
+  }
+  void set_type(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prefix =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceConfig_PrintFilter_Rule_AtraceMessage>;
+
+  static constexpr FieldMetadata_Prefix kPrefix{};
+  void set_prefix(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Prefix::kFieldId, data, size);
+  }
+  void set_prefix(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Prefix::kFieldId, chars.data, chars.size);
+  }
+  void set_prefix(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prefix::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FtraceConfig_CompactSchedConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceConfig_CompactSchedConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceConfig_CompactSchedConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceConfig_CompactSchedConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_enabled() const { return at<1>().valid(); }
+  bool enabled() const { return at<1>().as_bool(); }
+};
+
+class FtraceConfig_CompactSchedConfig : public ::protozero::Message {
+ public:
+  using Decoder = FtraceConfig_CompactSchedConfig_Decoder;
+  enum : int32_t {
+    kEnabledFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceConfig.CompactSchedConfig"; }
+
+
+  using FieldMetadata_Enabled =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceConfig_CompactSchedConfig>;
+
+  static constexpr FieldMetadata_Enabled kEnabled{};
+  void set_enabled(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Enabled::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/gpu/gpu_counter_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class GpuCounterConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuCounterConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_counter_period_ns() const { return at<1>().valid(); }
+  uint64_t counter_period_ns() const { return at<1>().as_uint64(); }
+  bool has_counter_ids() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> counter_ids() const { return GetRepeated<uint32_t>(2); }
+  bool has_instrumented_sampling() const { return at<3>().valid(); }
+  bool instrumented_sampling() const { return at<3>().as_bool(); }
+  bool has_fix_gpu_clock() const { return at<4>().valid(); }
+  bool fix_gpu_clock() const { return at<4>().as_bool(); }
+};
+
+class GpuCounterConfig : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterConfig_Decoder;
+  enum : int32_t {
+    kCounterPeriodNsFieldNumber = 1,
+    kCounterIdsFieldNumber = 2,
+    kInstrumentedSamplingFieldNumber = 3,
+    kFixGpuClockFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterConfig"; }
+
+
+  using FieldMetadata_CounterPeriodNs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuCounterConfig>;
+
+  static constexpr FieldMetadata_CounterPeriodNs kCounterPeriodNs{};
+  void set_counter_period_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterPeriodNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CounterIds =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterConfig>;
+
+  static constexpr FieldMetadata_CounterIds kCounterIds{};
+  void add_counter_ids(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InstrumentedSampling =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      GpuCounterConfig>;
+
+  static constexpr FieldMetadata_InstrumentedSampling kInstrumentedSampling{};
+  void set_instrumented_sampling(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_InstrumentedSampling::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FixGpuClock =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      GpuCounterConfig>;
+
+  static constexpr FieldMetadata_FixGpuClock kFixGpuClock{};
+  void set_fix_gpu_clock(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_FixGpuClock::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class VulkanMemoryConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VulkanMemoryConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanMemoryConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanMemoryConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_track_driver_memory_usage() const { return at<1>().valid(); }
+  bool track_driver_memory_usage() const { return at<1>().as_bool(); }
+  bool has_track_device_memory_usage() const { return at<2>().valid(); }
+  bool track_device_memory_usage() const { return at<2>().as_bool(); }
+};
+
+class VulkanMemoryConfig : public ::protozero::Message {
+ public:
+  using Decoder = VulkanMemoryConfig_Decoder;
+  enum : int32_t {
+    kTrackDriverMemoryUsageFieldNumber = 1,
+    kTrackDeviceMemoryUsageFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanMemoryConfig"; }
+
+
+  using FieldMetadata_TrackDriverMemoryUsage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      VulkanMemoryConfig>;
+
+  static constexpr FieldMetadata_TrackDriverMemoryUsage kTrackDriverMemoryUsage{};
+  void set_track_driver_memory_usage(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrackDriverMemoryUsage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TrackDeviceMemoryUsage =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      VulkanMemoryConfig>;
+
+  static constexpr FieldMetadata_TrackDeviceMemoryUsage kTrackDeviceMemoryUsage{};
+  void set_track_device_memory_usage(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrackDeviceMemoryUsage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/inode_file/inode_file_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class InodeFileConfig_MountPointMappingEntry;
+
+class InodeFileConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  InodeFileConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InodeFileConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InodeFileConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_scan_interval_ms() const { return at<1>().valid(); }
+  uint32_t scan_interval_ms() const { return at<1>().as_uint32(); }
+  bool has_scan_delay_ms() const { return at<2>().valid(); }
+  uint32_t scan_delay_ms() const { return at<2>().as_uint32(); }
+  bool has_scan_batch_size() const { return at<3>().valid(); }
+  uint32_t scan_batch_size() const { return at<3>().as_uint32(); }
+  bool has_do_not_scan() const { return at<4>().valid(); }
+  bool do_not_scan() const { return at<4>().as_bool(); }
+  bool has_scan_mount_points() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> scan_mount_points() const { return GetRepeated<::protozero::ConstChars>(5); }
+  bool has_mount_point_mapping() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mount_point_mapping() const { return GetRepeated<::protozero::ConstBytes>(6); }
+};
+
+class InodeFileConfig : public ::protozero::Message {
+ public:
+  using Decoder = InodeFileConfig_Decoder;
+  enum : int32_t {
+    kScanIntervalMsFieldNumber = 1,
+    kScanDelayMsFieldNumber = 2,
+    kScanBatchSizeFieldNumber = 3,
+    kDoNotScanFieldNumber = 4,
+    kScanMountPointsFieldNumber = 5,
+    kMountPointMappingFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InodeFileConfig"; }
+
+  using MountPointMappingEntry = ::perfetto::protos::pbzero::InodeFileConfig_MountPointMappingEntry;
+
+  using FieldMetadata_ScanIntervalMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_ScanIntervalMs kScanIntervalMs{};
+  void set_scan_interval_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanIntervalMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ScanDelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_ScanDelayMs kScanDelayMs{};
+  void set_scan_delay_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanDelayMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ScanBatchSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_ScanBatchSize kScanBatchSize{};
+  void set_scan_batch_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanBatchSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoNotScan =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_DoNotScan kDoNotScan{};
+  void set_do_not_scan(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoNotScan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ScanMountPoints =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_ScanMountPoints kScanMountPoints{};
+  void add_scan_mount_points(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ScanMountPoints::kFieldId, data, size);
+  }
+  void add_scan_mount_points(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ScanMountPoints::kFieldId, chars.data, chars.size);
+  }
+  void add_scan_mount_points(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanMountPoints::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MountPointMapping =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InodeFileConfig_MountPointMappingEntry,
+      InodeFileConfig>;
+
+  static constexpr FieldMetadata_MountPointMapping kMountPointMapping{};
+  template <typename T = InodeFileConfig_MountPointMappingEntry> T* add_mount_point_mapping() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class InodeFileConfig_MountPointMappingEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  InodeFileConfig_MountPointMappingEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InodeFileConfig_MountPointMappingEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InodeFileConfig_MountPointMappingEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mountpoint() const { return at<1>().valid(); }
+  ::protozero::ConstChars mountpoint() const { return at<1>().as_string(); }
+  bool has_scan_roots() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> scan_roots() const { return GetRepeated<::protozero::ConstChars>(2); }
+};
+
+class InodeFileConfig_MountPointMappingEntry : public ::protozero::Message {
+ public:
+  using Decoder = InodeFileConfig_MountPointMappingEntry_Decoder;
+  enum : int32_t {
+    kMountpointFieldNumber = 1,
+    kScanRootsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InodeFileConfig.MountPointMappingEntry"; }
+
+
+  using FieldMetadata_Mountpoint =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileConfig_MountPointMappingEntry>;
+
+  static constexpr FieldMetadata_Mountpoint kMountpoint{};
+  void set_mountpoint(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Mountpoint::kFieldId, data, size);
+  }
+  void set_mountpoint(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Mountpoint::kFieldId, chars.data, chars.size);
+  }
+  void set_mountpoint(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mountpoint::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ScanRoots =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileConfig_MountPointMappingEntry>;
+
+  static constexpr FieldMetadata_ScanRoots kScanRoots{};
+  void add_scan_roots(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ScanRoots::kFieldId, data, size);
+  }
+  void add_scan_roots(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ScanRoots::kFieldId, chars.data, chars.size);
+  }
+  void add_scan_roots(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanRoots::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/interceptors/console_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ConsoleConfig {
+enum Output : int32_t;
+}  // namespace perfetto_pbzero_enum_ConsoleConfig
+using ConsoleConfig_Output = perfetto_pbzero_enum_ConsoleConfig::Output;
+
+namespace perfetto_pbzero_enum_ConsoleConfig {
+enum Output : int32_t {
+  OUTPUT_UNSPECIFIED = 0,
+  OUTPUT_STDOUT = 1,
+  OUTPUT_STDERR = 2,
+};
+} // namespace perfetto_pbzero_enum_ConsoleConfig
+using ConsoleConfig_Output = perfetto_pbzero_enum_ConsoleConfig::Output;
+
+
+constexpr ConsoleConfig_Output ConsoleConfig_Output_MIN = ConsoleConfig_Output::OUTPUT_UNSPECIFIED;
+constexpr ConsoleConfig_Output ConsoleConfig_Output_MAX = ConsoleConfig_Output::OUTPUT_STDERR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ConsoleConfig_Output_Name(::perfetto::protos::pbzero::ConsoleConfig_Output value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ConsoleConfig_Output::OUTPUT_UNSPECIFIED:
+    return "OUTPUT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ConsoleConfig_Output::OUTPUT_STDOUT:
+    return "OUTPUT_STDOUT";
+
+  case ::perfetto::protos::pbzero::ConsoleConfig_Output::OUTPUT_STDERR:
+    return "OUTPUT_STDERR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ConsoleConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ConsoleConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ConsoleConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ConsoleConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_output() const { return at<1>().valid(); }
+  int32_t output() const { return at<1>().as_int32(); }
+  bool has_enable_colors() const { return at<2>().valid(); }
+  bool enable_colors() const { return at<2>().as_bool(); }
+};
+
+class ConsoleConfig : public ::protozero::Message {
+ public:
+  using Decoder = ConsoleConfig_Decoder;
+  enum : int32_t {
+    kOutputFieldNumber = 1,
+    kEnableColorsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ConsoleConfig"; }
+
+
+  using Output = ::perfetto::protos::pbzero::ConsoleConfig_Output;
+  static inline const char* Output_Name(Output value) {
+    return ::perfetto::protos::pbzero::ConsoleConfig_Output_Name(value);
+  }
+  static inline const Output OUTPUT_UNSPECIFIED = Output::OUTPUT_UNSPECIFIED;
+  static inline const Output OUTPUT_STDOUT = Output::OUTPUT_STDOUT;
+  static inline const Output OUTPUT_STDERR = Output::OUTPUT_STDERR;
+
+  using FieldMetadata_Output =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ConsoleConfig_Output,
+      ConsoleConfig>;
+
+  static constexpr FieldMetadata_Output kOutput{};
+  void set_output(::perfetto::protos::pbzero::ConsoleConfig_Output value) {
+    static constexpr uint32_t field_id = FieldMetadata_Output::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnableColors =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ConsoleConfig>;
+
+  static constexpr FieldMetadata_EnableColors kEnableColors{};
+  void set_enable_colors(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnableColors::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/power/android_power_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_AndroidPowerConfig {
+enum BatteryCounters : int32_t;
+}  // namespace perfetto_pbzero_enum_AndroidPowerConfig
+using AndroidPowerConfig_BatteryCounters = perfetto_pbzero_enum_AndroidPowerConfig::BatteryCounters;
+
+namespace perfetto_pbzero_enum_AndroidPowerConfig {
+enum BatteryCounters : int32_t {
+  BATTERY_COUNTER_UNSPECIFIED = 0,
+  BATTERY_COUNTER_CHARGE = 1,
+  BATTERY_COUNTER_CAPACITY_PERCENT = 2,
+  BATTERY_COUNTER_CURRENT = 3,
+  BATTERY_COUNTER_CURRENT_AVG = 4,
+  BATTERY_COUNTER_VOLTAGE = 5,
+};
+} // namespace perfetto_pbzero_enum_AndroidPowerConfig
+using AndroidPowerConfig_BatteryCounters = perfetto_pbzero_enum_AndroidPowerConfig::BatteryCounters;
+
+
+constexpr AndroidPowerConfig_BatteryCounters AndroidPowerConfig_BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_UNSPECIFIED;
+constexpr AndroidPowerConfig_BatteryCounters AndroidPowerConfig_BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_VOLTAGE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AndroidPowerConfig_BatteryCounters_Name(::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_UNSPECIFIED:
+    return "BATTERY_COUNTER_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_CHARGE:
+    return "BATTERY_COUNTER_CHARGE";
+
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_CAPACITY_PERCENT:
+    return "BATTERY_COUNTER_CAPACITY_PERCENT";
+
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_CURRENT:
+    return "BATTERY_COUNTER_CURRENT";
+
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_CURRENT_AVG:
+    return "BATTERY_COUNTER_CURRENT_AVG";
+
+  case ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters::BATTERY_COUNTER_VOLTAGE:
+    return "BATTERY_COUNTER_VOLTAGE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class AndroidPowerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidPowerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidPowerConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidPowerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_battery_poll_ms() const { return at<1>().valid(); }
+  uint32_t battery_poll_ms() const { return at<1>().as_uint32(); }
+  bool has_battery_counters() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> battery_counters() const { return GetRepeated<int32_t>(2); }
+  bool has_collect_power_rails() const { return at<3>().valid(); }
+  bool collect_power_rails() const { return at<3>().as_bool(); }
+  bool has_collect_energy_estimation_breakdown() const { return at<4>().valid(); }
+  bool collect_energy_estimation_breakdown() const { return at<4>().as_bool(); }
+  bool has_collect_entity_state_residency() const { return at<5>().valid(); }
+  bool collect_entity_state_residency() const { return at<5>().as_bool(); }
+};
+
+class AndroidPowerConfig : public ::protozero::Message {
+ public:
+  using Decoder = AndroidPowerConfig_Decoder;
+  enum : int32_t {
+    kBatteryPollMsFieldNumber = 1,
+    kBatteryCountersFieldNumber = 2,
+    kCollectPowerRailsFieldNumber = 3,
+    kCollectEnergyEstimationBreakdownFieldNumber = 4,
+    kCollectEntityStateResidencyFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidPowerConfig"; }
+
+
+  using BatteryCounters = ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters;
+  static inline const char* BatteryCounters_Name(BatteryCounters value) {
+    return ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters_Name(value);
+  }
+  static inline const BatteryCounters BATTERY_COUNTER_UNSPECIFIED = BatteryCounters::BATTERY_COUNTER_UNSPECIFIED;
+  static inline const BatteryCounters BATTERY_COUNTER_CHARGE = BatteryCounters::BATTERY_COUNTER_CHARGE;
+  static inline const BatteryCounters BATTERY_COUNTER_CAPACITY_PERCENT = BatteryCounters::BATTERY_COUNTER_CAPACITY_PERCENT;
+  static inline const BatteryCounters BATTERY_COUNTER_CURRENT = BatteryCounters::BATTERY_COUNTER_CURRENT;
+  static inline const BatteryCounters BATTERY_COUNTER_CURRENT_AVG = BatteryCounters::BATTERY_COUNTER_CURRENT_AVG;
+  static inline const BatteryCounters BATTERY_COUNTER_VOLTAGE = BatteryCounters::BATTERY_COUNTER_VOLTAGE;
+
+  using FieldMetadata_BatteryPollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidPowerConfig>;
+
+  static constexpr FieldMetadata_BatteryPollMs kBatteryPollMs{};
+  void set_battery_poll_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BatteryPollMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BatteryCounters =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters,
+      AndroidPowerConfig>;
+
+  static constexpr FieldMetadata_BatteryCounters kBatteryCounters{};
+  void add_battery_counters(::perfetto::protos::pbzero::AndroidPowerConfig_BatteryCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_BatteryCounters::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CollectPowerRails =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidPowerConfig>;
+
+  static constexpr FieldMetadata_CollectPowerRails kCollectPowerRails{};
+  void set_collect_power_rails(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectPowerRails::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CollectEnergyEstimationBreakdown =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidPowerConfig>;
+
+  static constexpr FieldMetadata_CollectEnergyEstimationBreakdown kCollectEnergyEstimationBreakdown{};
+  void set_collect_energy_estimation_breakdown(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectEnergyEstimationBreakdown::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CollectEntityStateResidency =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidPowerConfig>;
+
+  static constexpr FieldMetadata_CollectEntityStateResidency kCollectEntityStateResidency{};
+  void set_collect_entity_state_residency(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectEntityStateResidency::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/process_stats/process_stats_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ProcessStatsConfig {
+enum Quirks : int32_t;
+}  // namespace perfetto_pbzero_enum_ProcessStatsConfig
+using ProcessStatsConfig_Quirks = perfetto_pbzero_enum_ProcessStatsConfig::Quirks;
+
+namespace perfetto_pbzero_enum_ProcessStatsConfig {
+enum Quirks : int32_t {
+  QUIRKS_UNSPECIFIED = 0,
+  DISABLE_INITIAL_DUMP = 1,
+  DISABLE_ON_DEMAND = 2,
+};
+} // namespace perfetto_pbzero_enum_ProcessStatsConfig
+using ProcessStatsConfig_Quirks = perfetto_pbzero_enum_ProcessStatsConfig::Quirks;
+
+
+constexpr ProcessStatsConfig_Quirks ProcessStatsConfig_Quirks_MIN = ProcessStatsConfig_Quirks::QUIRKS_UNSPECIFIED;
+constexpr ProcessStatsConfig_Quirks ProcessStatsConfig_Quirks_MAX = ProcessStatsConfig_Quirks::DISABLE_ON_DEMAND;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ProcessStatsConfig_Quirks_Name(::perfetto::protos::pbzero::ProcessStatsConfig_Quirks value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks::QUIRKS_UNSPECIFIED:
+    return "QUIRKS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks::DISABLE_INITIAL_DUMP:
+    return "DISABLE_INITIAL_DUMP";
+
+  case ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks::DISABLE_ON_DEMAND:
+    return "DISABLE_ON_DEMAND";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ProcessStatsConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessStatsConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessStatsConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessStatsConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_quirks() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> quirks() const { return GetRepeated<int32_t>(1); }
+  bool has_scan_all_processes_on_start() const { return at<2>().valid(); }
+  bool scan_all_processes_on_start() const { return at<2>().as_bool(); }
+  bool has_record_thread_names() const { return at<3>().valid(); }
+  bool record_thread_names() const { return at<3>().as_bool(); }
+  bool has_proc_stats_poll_ms() const { return at<4>().valid(); }
+  uint32_t proc_stats_poll_ms() const { return at<4>().as_uint32(); }
+  bool has_proc_stats_cache_ttl_ms() const { return at<6>().valid(); }
+  uint32_t proc_stats_cache_ttl_ms() const { return at<6>().as_uint32(); }
+  bool has_resolve_process_fds() const { return at<9>().valid(); }
+  bool resolve_process_fds() const { return at<9>().as_bool(); }
+  bool has_scan_smaps_rollup() const { return at<10>().valid(); }
+  bool scan_smaps_rollup() const { return at<10>().as_bool(); }
+};
+
+class ProcessStatsConfig : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStatsConfig_Decoder;
+  enum : int32_t {
+    kQuirksFieldNumber = 1,
+    kScanAllProcessesOnStartFieldNumber = 2,
+    kRecordThreadNamesFieldNumber = 3,
+    kProcStatsPollMsFieldNumber = 4,
+    kProcStatsCacheTtlMsFieldNumber = 6,
+    kResolveProcessFdsFieldNumber = 9,
+    kScanSmapsRollupFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessStatsConfig"; }
+
+
+  using Quirks = ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks;
+  static inline const char* Quirks_Name(Quirks value) {
+    return ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks_Name(value);
+  }
+  static inline const Quirks QUIRKS_UNSPECIFIED = Quirks::QUIRKS_UNSPECIFIED;
+  static inline const Quirks DISABLE_INITIAL_DUMP = Quirks::DISABLE_INITIAL_DUMP;
+  static inline const Quirks DISABLE_ON_DEMAND = Quirks::DISABLE_ON_DEMAND;
+
+  using FieldMetadata_Quirks =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ProcessStatsConfig_Quirks,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_Quirks kQuirks{};
+  void add_quirks(::perfetto::protos::pbzero::ProcessStatsConfig_Quirks value) {
+    static constexpr uint32_t field_id = FieldMetadata_Quirks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ScanAllProcessesOnStart =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_ScanAllProcessesOnStart kScanAllProcessesOnStart{};
+  void set_scan_all_processes_on_start(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanAllProcessesOnStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RecordThreadNames =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_RecordThreadNames kRecordThreadNames{};
+  void set_record_thread_names(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_RecordThreadNames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcStatsPollMs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_ProcStatsPollMs kProcStatsPollMs{};
+  void set_proc_stats_poll_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcStatsPollMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcStatsCacheTtlMs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_ProcStatsCacheTtlMs kProcStatsCacheTtlMs{};
+  void set_proc_stats_cache_ttl_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcStatsCacheTtlMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResolveProcessFds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_ResolveProcessFds kResolveProcessFds{};
+  void set_resolve_process_fds(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResolveProcessFds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ScanSmapsRollup =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStatsConfig>;
+
+  static constexpr FieldMetadata_ScanSmapsRollup kScanSmapsRollup{};
+  void set_scan_smaps_rollup(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanSmapsRollup::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/heapprofd_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class HeapprofdConfig_ContinuousDumpConfig;
+
+class HeapprofdConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/27, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  HeapprofdConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapprofdConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapprofdConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_sampling_interval_bytes() const { return at<1>().valid(); }
+  uint64_t sampling_interval_bytes() const { return at<1>().as_uint64(); }
+  bool has_adaptive_sampling_shmem_threshold() const { return at<24>().valid(); }
+  uint64_t adaptive_sampling_shmem_threshold() const { return at<24>().as_uint64(); }
+  bool has_adaptive_sampling_max_sampling_interval_bytes() const { return at<25>().valid(); }
+  uint64_t adaptive_sampling_max_sampling_interval_bytes() const { return at<25>().as_uint64(); }
+  bool has_process_cmdline() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> process_cmdline() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_pid() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> pid() const { return GetRepeated<uint64_t>(4); }
+  bool has_target_installed_by() const { return at<26>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> target_installed_by() const { return GetRepeated<::protozero::ConstChars>(26); }
+  bool has_heaps() const { return at<20>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> heaps() const { return GetRepeated<::protozero::ConstChars>(20); }
+  bool has_exclude_heaps() const { return at<27>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> exclude_heaps() const { return GetRepeated<::protozero::ConstChars>(27); }
+  bool has_stream_allocations() const { return at<23>().valid(); }
+  bool stream_allocations() const { return at<23>().as_bool(); }
+  bool has_heap_sampling_intervals() const { return at<22>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> heap_sampling_intervals() const { return GetRepeated<uint64_t>(22); }
+  bool has_all_heaps() const { return at<21>().valid(); }
+  bool all_heaps() const { return at<21>().as_bool(); }
+  bool has_all() const { return at<5>().valid(); }
+  bool all() const { return at<5>().as_bool(); }
+  bool has_min_anonymous_memory_kb() const { return at<15>().valid(); }
+  uint32_t min_anonymous_memory_kb() const { return at<15>().as_uint32(); }
+  bool has_max_heapprofd_memory_kb() const { return at<16>().valid(); }
+  uint32_t max_heapprofd_memory_kb() const { return at<16>().as_uint32(); }
+  bool has_max_heapprofd_cpu_secs() const { return at<17>().valid(); }
+  uint64_t max_heapprofd_cpu_secs() const { return at<17>().as_uint64(); }
+  bool has_skip_symbol_prefix() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> skip_symbol_prefix() const { return GetRepeated<::protozero::ConstChars>(7); }
+  bool has_continuous_dump_config() const { return at<6>().valid(); }
+  ::protozero::ConstBytes continuous_dump_config() const { return at<6>().as_bytes(); }
+  bool has_shmem_size_bytes() const { return at<8>().valid(); }
+  uint64_t shmem_size_bytes() const { return at<8>().as_uint64(); }
+  bool has_block_client() const { return at<9>().valid(); }
+  bool block_client() const { return at<9>().as_bool(); }
+  bool has_block_client_timeout_us() const { return at<14>().valid(); }
+  uint32_t block_client_timeout_us() const { return at<14>().as_uint32(); }
+  bool has_no_startup() const { return at<10>().valid(); }
+  bool no_startup() const { return at<10>().as_bool(); }
+  bool has_no_running() const { return at<11>().valid(); }
+  bool no_running() const { return at<11>().as_bool(); }
+  bool has_dump_at_max() const { return at<13>().valid(); }
+  bool dump_at_max() const { return at<13>().as_bool(); }
+  bool has_disable_fork_teardown() const { return at<18>().valid(); }
+  bool disable_fork_teardown() const { return at<18>().as_bool(); }
+  bool has_disable_vfork_detection() const { return at<19>().valid(); }
+  bool disable_vfork_detection() const { return at<19>().as_bool(); }
+};
+
+class HeapprofdConfig : public ::protozero::Message {
+ public:
+  using Decoder = HeapprofdConfig_Decoder;
+  enum : int32_t {
+    kSamplingIntervalBytesFieldNumber = 1,
+    kAdaptiveSamplingShmemThresholdFieldNumber = 24,
+    kAdaptiveSamplingMaxSamplingIntervalBytesFieldNumber = 25,
+    kProcessCmdlineFieldNumber = 2,
+    kPidFieldNumber = 4,
+    kTargetInstalledByFieldNumber = 26,
+    kHeapsFieldNumber = 20,
+    kExcludeHeapsFieldNumber = 27,
+    kStreamAllocationsFieldNumber = 23,
+    kHeapSamplingIntervalsFieldNumber = 22,
+    kAllHeapsFieldNumber = 21,
+    kAllFieldNumber = 5,
+    kMinAnonymousMemoryKbFieldNumber = 15,
+    kMaxHeapprofdMemoryKbFieldNumber = 16,
+    kMaxHeapprofdCpuSecsFieldNumber = 17,
+    kSkipSymbolPrefixFieldNumber = 7,
+    kContinuousDumpConfigFieldNumber = 6,
+    kShmemSizeBytesFieldNumber = 8,
+    kBlockClientFieldNumber = 9,
+    kBlockClientTimeoutUsFieldNumber = 14,
+    kNoStartupFieldNumber = 10,
+    kNoRunningFieldNumber = 11,
+    kDumpAtMaxFieldNumber = 13,
+    kDisableForkTeardownFieldNumber = 18,
+    kDisableVforkDetectionFieldNumber = 19,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapprofdConfig"; }
+
+  using ContinuousDumpConfig = ::perfetto::protos::pbzero::HeapprofdConfig_ContinuousDumpConfig;
+
+  using FieldMetadata_SamplingIntervalBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_SamplingIntervalBytes kSamplingIntervalBytes{};
+  void set_sampling_interval_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SamplingIntervalBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AdaptiveSamplingShmemThreshold =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_AdaptiveSamplingShmemThreshold kAdaptiveSamplingShmemThreshold{};
+  void set_adaptive_sampling_shmem_threshold(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdaptiveSamplingShmemThreshold::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AdaptiveSamplingMaxSamplingIntervalBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_AdaptiveSamplingMaxSamplingIntervalBytes kAdaptiveSamplingMaxSamplingIntervalBytes{};
+  void set_adaptive_sampling_max_sampling_interval_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdaptiveSamplingMaxSamplingIntervalBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_ProcessCmdline kProcessCmdline{};
+  void add_process_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessCmdline::kFieldId, data, size);
+  }
+  void add_process_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProcessCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_process_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessCmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void add_pid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetInstalledBy =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_TargetInstalledBy kTargetInstalledBy{};
+  void add_target_installed_by(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, data, size);
+  }
+  void add_target_installed_by(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, chars.data, chars.size);
+  }
+  void add_target_installed_by(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetInstalledBy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Heaps =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_Heaps kHeaps{};
+  void add_heaps(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Heaps::kFieldId, data, size);
+  }
+  void add_heaps(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Heaps::kFieldId, chars.data, chars.size);
+  }
+  void add_heaps(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Heaps::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExcludeHeaps =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_ExcludeHeaps kExcludeHeaps{};
+  void add_exclude_heaps(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ExcludeHeaps::kFieldId, data, size);
+  }
+  void add_exclude_heaps(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ExcludeHeaps::kFieldId, chars.data, chars.size);
+  }
+  void add_exclude_heaps(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludeHeaps::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StreamAllocations =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_StreamAllocations kStreamAllocations{};
+  void set_stream_allocations(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_StreamAllocations::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapSamplingIntervals =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_HeapSamplingIntervals kHeapSamplingIntervals{};
+  void add_heap_sampling_intervals(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapSamplingIntervals::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllHeaps =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_AllHeaps kAllHeaps{};
+  void set_all_heaps(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllHeaps::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_All =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_All kAll{};
+  void set_all(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_All::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MinAnonymousMemoryKb =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_MinAnonymousMemoryKb kMinAnonymousMemoryKb{};
+  void set_min_anonymous_memory_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinAnonymousMemoryKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxHeapprofdMemoryKb =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_MaxHeapprofdMemoryKb kMaxHeapprofdMemoryKb{};
+  void set_max_heapprofd_memory_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxHeapprofdMemoryKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxHeapprofdCpuSecs =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_MaxHeapprofdCpuSecs kMaxHeapprofdCpuSecs{};
+  void set_max_heapprofd_cpu_secs(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxHeapprofdCpuSecs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SkipSymbolPrefix =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_SkipSymbolPrefix kSkipSymbolPrefix{};
+  void add_skip_symbol_prefix(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SkipSymbolPrefix::kFieldId, data, size);
+  }
+  void add_skip_symbol_prefix(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SkipSymbolPrefix::kFieldId, chars.data, chars.size);
+  }
+  void add_skip_symbol_prefix(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkipSymbolPrefix::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ContinuousDumpConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapprofdConfig_ContinuousDumpConfig,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_ContinuousDumpConfig kContinuousDumpConfig{};
+  template <typename T = HeapprofdConfig_ContinuousDumpConfig> T* set_continuous_dump_config() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_ShmemSizeBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_ShmemSizeBytes kShmemSizeBytes{};
+  void set_shmem_size_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmemSizeBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BlockClient =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_BlockClient kBlockClient{};
+  void set_block_client(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockClient::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BlockClientTimeoutUs =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_BlockClientTimeoutUs kBlockClientTimeoutUs{};
+  void set_block_client_timeout_us(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockClientTimeoutUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NoStartup =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_NoStartup kNoStartup{};
+  void set_no_startup(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NoStartup::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NoRunning =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_NoRunning kNoRunning{};
+  void set_no_running(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NoRunning::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DumpAtMax =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_DumpAtMax kDumpAtMax{};
+  void set_dump_at_max(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpAtMax::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisableForkTeardown =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_DisableForkTeardown kDisableForkTeardown{};
+  void set_disable_fork_teardown(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableForkTeardown::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisableVforkDetection =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapprofdConfig>;
+
+  static constexpr FieldMetadata_DisableVforkDetection kDisableVforkDetection{};
+  void set_disable_vfork_detection(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableVforkDetection::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class HeapprofdConfig_ContinuousDumpConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HeapprofdConfig_ContinuousDumpConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapprofdConfig_ContinuousDumpConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapprofdConfig_ContinuousDumpConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dump_phase_ms() const { return at<5>().valid(); }
+  uint32_t dump_phase_ms() const { return at<5>().as_uint32(); }
+  bool has_dump_interval_ms() const { return at<6>().valid(); }
+  uint32_t dump_interval_ms() const { return at<6>().as_uint32(); }
+};
+
+class HeapprofdConfig_ContinuousDumpConfig : public ::protozero::Message {
+ public:
+  using Decoder = HeapprofdConfig_ContinuousDumpConfig_Decoder;
+  enum : int32_t {
+    kDumpPhaseMsFieldNumber = 5,
+    kDumpIntervalMsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapprofdConfig.ContinuousDumpConfig"; }
+
+
+  using FieldMetadata_DumpPhaseMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig_ContinuousDumpConfig>;
+
+  static constexpr FieldMetadata_DumpPhaseMs kDumpPhaseMs{};
+  void set_dump_phase_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpPhaseMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DumpIntervalMs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HeapprofdConfig_ContinuousDumpConfig>;
+
+  static constexpr FieldMetadata_DumpIntervalMs kDumpIntervalMs{};
+  void set_dump_interval_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpIntervalMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/java_hprof_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class JavaHprofConfig_ContinuousDumpConfig;
+
+class JavaHprofConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  JavaHprofConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit JavaHprofConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit JavaHprofConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_process_cmdline() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> process_cmdline() const { return GetRepeated<::protozero::ConstChars>(1); }
+  bool has_pid() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> pid() const { return GetRepeated<uint64_t>(2); }
+  bool has_target_installed_by() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> target_installed_by() const { return GetRepeated<::protozero::ConstChars>(7); }
+  bool has_continuous_dump_config() const { return at<3>().valid(); }
+  ::protozero::ConstBytes continuous_dump_config() const { return at<3>().as_bytes(); }
+  bool has_min_anonymous_memory_kb() const { return at<4>().valid(); }
+  uint32_t min_anonymous_memory_kb() const { return at<4>().as_uint32(); }
+  bool has_dump_smaps() const { return at<5>().valid(); }
+  bool dump_smaps() const { return at<5>().as_bool(); }
+  bool has_ignored_types() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> ignored_types() const { return GetRepeated<::protozero::ConstChars>(6); }
+};
+
+class JavaHprofConfig : public ::protozero::Message {
+ public:
+  using Decoder = JavaHprofConfig_Decoder;
+  enum : int32_t {
+    kProcessCmdlineFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTargetInstalledByFieldNumber = 7,
+    kContinuousDumpConfigFieldNumber = 3,
+    kMinAnonymousMemoryKbFieldNumber = 4,
+    kDumpSmapsFieldNumber = 5,
+    kIgnoredTypesFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.JavaHprofConfig"; }
+
+  using ContinuousDumpConfig = ::perfetto::protos::pbzero::JavaHprofConfig_ContinuousDumpConfig;
+
+  using FieldMetadata_ProcessCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_ProcessCmdline kProcessCmdline{};
+  void add_process_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessCmdline::kFieldId, data, size);
+  }
+  void add_process_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProcessCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_process_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessCmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void add_pid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetInstalledBy =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_TargetInstalledBy kTargetInstalledBy{};
+  void add_target_installed_by(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, data, size);
+  }
+  void add_target_installed_by(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, chars.data, chars.size);
+  }
+  void add_target_installed_by(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetInstalledBy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ContinuousDumpConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      JavaHprofConfig_ContinuousDumpConfig,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_ContinuousDumpConfig kContinuousDumpConfig{};
+  template <typename T = JavaHprofConfig_ContinuousDumpConfig> T* set_continuous_dump_config() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_MinAnonymousMemoryKb =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_MinAnonymousMemoryKb kMinAnonymousMemoryKb{};
+  void set_min_anonymous_memory_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinAnonymousMemoryKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DumpSmaps =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_DumpSmaps kDumpSmaps{};
+  void set_dump_smaps(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpSmaps::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IgnoredTypes =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      JavaHprofConfig>;
+
+  static constexpr FieldMetadata_IgnoredTypes kIgnoredTypes{};
+  void add_ignored_types(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_IgnoredTypes::kFieldId, data, size);
+  }
+  void add_ignored_types(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_IgnoredTypes::kFieldId, chars.data, chars.size);
+  }
+  void add_ignored_types(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_IgnoredTypes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class JavaHprofConfig_ContinuousDumpConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  JavaHprofConfig_ContinuousDumpConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit JavaHprofConfig_ContinuousDumpConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit JavaHprofConfig_ContinuousDumpConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dump_phase_ms() const { return at<1>().valid(); }
+  uint32_t dump_phase_ms() const { return at<1>().as_uint32(); }
+  bool has_dump_interval_ms() const { return at<2>().valid(); }
+  uint32_t dump_interval_ms() const { return at<2>().as_uint32(); }
+  bool has_scan_pids_only_on_start() const { return at<3>().valid(); }
+  bool scan_pids_only_on_start() const { return at<3>().as_bool(); }
+};
+
+class JavaHprofConfig_ContinuousDumpConfig : public ::protozero::Message {
+ public:
+  using Decoder = JavaHprofConfig_ContinuousDumpConfig_Decoder;
+  enum : int32_t {
+    kDumpPhaseMsFieldNumber = 1,
+    kDumpIntervalMsFieldNumber = 2,
+    kScanPidsOnlyOnStartFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.JavaHprofConfig.ContinuousDumpConfig"; }
+
+
+  using FieldMetadata_DumpPhaseMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      JavaHprofConfig_ContinuousDumpConfig>;
+
+  static constexpr FieldMetadata_DumpPhaseMs kDumpPhaseMs{};
+  void set_dump_phase_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpPhaseMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DumpIntervalMs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      JavaHprofConfig_ContinuousDumpConfig>;
+
+  static constexpr FieldMetadata_DumpIntervalMs kDumpIntervalMs{};
+  void set_dump_interval_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DumpIntervalMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ScanPidsOnlyOnStart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      JavaHprofConfig_ContinuousDumpConfig>;
+
+  static constexpr FieldMetadata_ScanPidsOnlyOnStart kScanPidsOnlyOnStart{};
+  void set_scan_pids_only_on_start(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanPidsOnlyOnStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/profiling/perf_event_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PerfEventConfig_CallstackSampling;
+class PerfEventConfig_Scope;
+class PerfEvents_Timebase;
+namespace perfetto_pbzero_enum_PerfEventConfig {
+enum UnwindMode : int32_t;
+}  // namespace perfetto_pbzero_enum_PerfEventConfig
+using PerfEventConfig_UnwindMode = perfetto_pbzero_enum_PerfEventConfig::UnwindMode;
+
+namespace perfetto_pbzero_enum_PerfEventConfig {
+enum UnwindMode : int32_t {
+  UNWIND_UNKNOWN = 0,
+  UNWIND_SKIP = 1,
+  UNWIND_DWARF = 2,
+};
+} // namespace perfetto_pbzero_enum_PerfEventConfig
+using PerfEventConfig_UnwindMode = perfetto_pbzero_enum_PerfEventConfig::UnwindMode;
+
+
+constexpr PerfEventConfig_UnwindMode PerfEventConfig_UnwindMode_MIN = PerfEventConfig_UnwindMode::UNWIND_UNKNOWN;
+constexpr PerfEventConfig_UnwindMode PerfEventConfig_UnwindMode_MAX = PerfEventConfig_UnwindMode::UNWIND_DWARF;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PerfEventConfig_UnwindMode_Name(::perfetto::protos::pbzero::PerfEventConfig_UnwindMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode::UNWIND_UNKNOWN:
+    return "UNWIND_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode::UNWIND_SKIP:
+    return "UNWIND_SKIP";
+
+  case ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode::UNWIND_DWARF:
+    return "UNWIND_DWARF";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class PerfEventConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/18, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PerfEventConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEventConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEventConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timebase() const { return at<15>().valid(); }
+  ::protozero::ConstBytes timebase() const { return at<15>().as_bytes(); }
+  bool has_callstack_sampling() const { return at<16>().valid(); }
+  ::protozero::ConstBytes callstack_sampling() const { return at<16>().as_bytes(); }
+  bool has_ring_buffer_read_period_ms() const { return at<8>().valid(); }
+  uint32_t ring_buffer_read_period_ms() const { return at<8>().as_uint32(); }
+  bool has_ring_buffer_pages() const { return at<3>().valid(); }
+  uint32_t ring_buffer_pages() const { return at<3>().as_uint32(); }
+  bool has_max_enqueued_footprint_kb() const { return at<17>().valid(); }
+  uint64_t max_enqueued_footprint_kb() const { return at<17>().as_uint64(); }
+  bool has_max_daemon_memory_kb() const { return at<13>().valid(); }
+  uint32_t max_daemon_memory_kb() const { return at<13>().as_uint32(); }
+  bool has_remote_descriptor_timeout_ms() const { return at<9>().valid(); }
+  uint32_t remote_descriptor_timeout_ms() const { return at<9>().as_uint32(); }
+  bool has_unwind_state_clear_period_ms() const { return at<10>().valid(); }
+  uint32_t unwind_state_clear_period_ms() const { return at<10>().as_uint32(); }
+  bool has_target_installed_by() const { return at<18>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> target_installed_by() const { return GetRepeated<::protozero::ConstChars>(18); }
+  bool has_all_cpus() const { return at<1>().valid(); }
+  bool all_cpus() const { return at<1>().as_bool(); }
+  bool has_sampling_frequency() const { return at<2>().valid(); }
+  uint32_t sampling_frequency() const { return at<2>().as_uint32(); }
+  bool has_kernel_frames() const { return at<12>().valid(); }
+  bool kernel_frames() const { return at<12>().as_bool(); }
+  bool has_target_pid() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> target_pid() const { return GetRepeated<int32_t>(4); }
+  bool has_target_cmdline() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> target_cmdline() const { return GetRepeated<::protozero::ConstChars>(5); }
+  bool has_exclude_pid() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> exclude_pid() const { return GetRepeated<int32_t>(6); }
+  bool has_exclude_cmdline() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> exclude_cmdline() const { return GetRepeated<::protozero::ConstChars>(7); }
+  bool has_additional_cmdline_count() const { return at<11>().valid(); }
+  uint32_t additional_cmdline_count() const { return at<11>().as_uint32(); }
+};
+
+class PerfEventConfig : public ::protozero::Message {
+ public:
+  using Decoder = PerfEventConfig_Decoder;
+  enum : int32_t {
+    kTimebaseFieldNumber = 15,
+    kCallstackSamplingFieldNumber = 16,
+    kRingBufferReadPeriodMsFieldNumber = 8,
+    kRingBufferPagesFieldNumber = 3,
+    kMaxEnqueuedFootprintKbFieldNumber = 17,
+    kMaxDaemonMemoryKbFieldNumber = 13,
+    kRemoteDescriptorTimeoutMsFieldNumber = 9,
+    kUnwindStateClearPeriodMsFieldNumber = 10,
+    kTargetInstalledByFieldNumber = 18,
+    kAllCpusFieldNumber = 1,
+    kSamplingFrequencyFieldNumber = 2,
+    kKernelFramesFieldNumber = 12,
+    kTargetPidFieldNumber = 4,
+    kTargetCmdlineFieldNumber = 5,
+    kExcludePidFieldNumber = 6,
+    kExcludeCmdlineFieldNumber = 7,
+    kAdditionalCmdlineCountFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEventConfig"; }
+
+  using CallstackSampling = ::perfetto::protos::pbzero::PerfEventConfig_CallstackSampling;
+  using Scope = ::perfetto::protos::pbzero::PerfEventConfig_Scope;
+
+  using UnwindMode = ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode;
+  static inline const char* UnwindMode_Name(UnwindMode value) {
+    return ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode_Name(value);
+  }
+  static inline const UnwindMode UNWIND_UNKNOWN = UnwindMode::UNWIND_UNKNOWN;
+  static inline const UnwindMode UNWIND_SKIP = UnwindMode::UNWIND_SKIP;
+  static inline const UnwindMode UNWIND_DWARF = UnwindMode::UNWIND_DWARF;
+
+  using FieldMetadata_Timebase =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEvents_Timebase,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_Timebase kTimebase{};
+  template <typename T = PerfEvents_Timebase> T* set_timebase() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_CallstackSampling =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEventConfig_CallstackSampling,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_CallstackSampling kCallstackSampling{};
+  template <typename T = PerfEventConfig_CallstackSampling> T* set_callstack_sampling() {
+    return BeginNestedMessage<T>(16);
+  }
+
+
+  using FieldMetadata_RingBufferReadPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_RingBufferReadPeriodMs kRingBufferReadPeriodMs{};
+  void set_ring_buffer_read_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RingBufferReadPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RingBufferPages =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_RingBufferPages kRingBufferPages{};
+  void set_ring_buffer_pages(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RingBufferPages::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxEnqueuedFootprintKb =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_MaxEnqueuedFootprintKb kMaxEnqueuedFootprintKb{};
+  void set_max_enqueued_footprint_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxEnqueuedFootprintKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxDaemonMemoryKb =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_MaxDaemonMemoryKb kMaxDaemonMemoryKb{};
+  void set_max_daemon_memory_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxDaemonMemoryKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RemoteDescriptorTimeoutMs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_RemoteDescriptorTimeoutMs kRemoteDescriptorTimeoutMs{};
+  void set_remote_descriptor_timeout_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RemoteDescriptorTimeoutMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UnwindStateClearPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_UnwindStateClearPeriodMs kUnwindStateClearPeriodMs{};
+  void set_unwind_state_clear_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnwindStateClearPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetInstalledBy =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_TargetInstalledBy kTargetInstalledBy{};
+  void add_target_installed_by(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, data, size);
+  }
+  void add_target_installed_by(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TargetInstalledBy::kFieldId, chars.data, chars.size);
+  }
+  void add_target_installed_by(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetInstalledBy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllCpus =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_AllCpus kAllCpus{};
+  void set_all_cpus(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllCpus::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SamplingFrequency =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_SamplingFrequency kSamplingFrequency{};
+  void set_sampling_frequency(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SamplingFrequency::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KernelFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_KernelFrames kKernelFrames{};
+  void set_kernel_frames(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetPid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_TargetPid kTargetPid{};
+  void add_target_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_TargetCmdline kTargetCmdline{};
+  void add_target_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetCmdline::kFieldId, data, size);
+  }
+  void add_target_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TargetCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_target_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExcludePid =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_ExcludePid kExcludePid{};
+  void add_exclude_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludePid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExcludeCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_ExcludeCmdline kExcludeCmdline{};
+  void add_exclude_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ExcludeCmdline::kFieldId, data, size);
+  }
+  void add_exclude_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ExcludeCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_exclude_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludeCmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AdditionalCmdlineCount =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig>;
+
+  static constexpr FieldMetadata_AdditionalCmdlineCount kAdditionalCmdlineCount{};
+  void set_additional_cmdline_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdditionalCmdlineCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PerfEventConfig_Scope_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PerfEventConfig_Scope_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEventConfig_Scope_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEventConfig_Scope_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_target_pid() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> target_pid() const { return GetRepeated<int32_t>(1); }
+  bool has_target_cmdline() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> target_cmdline() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_exclude_pid() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> exclude_pid() const { return GetRepeated<int32_t>(3); }
+  bool has_exclude_cmdline() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> exclude_cmdline() const { return GetRepeated<::protozero::ConstChars>(4); }
+  bool has_additional_cmdline_count() const { return at<5>().valid(); }
+  uint32_t additional_cmdline_count() const { return at<5>().as_uint32(); }
+  bool has_process_shard_count() const { return at<6>().valid(); }
+  uint32_t process_shard_count() const { return at<6>().as_uint32(); }
+};
+
+class PerfEventConfig_Scope : public ::protozero::Message {
+ public:
+  using Decoder = PerfEventConfig_Scope_Decoder;
+  enum : int32_t {
+    kTargetPidFieldNumber = 1,
+    kTargetCmdlineFieldNumber = 2,
+    kExcludePidFieldNumber = 3,
+    kExcludeCmdlineFieldNumber = 4,
+    kAdditionalCmdlineCountFieldNumber = 5,
+    kProcessShardCountFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEventConfig.Scope"; }
+
+
+  using FieldMetadata_TargetPid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_TargetPid kTargetPid{};
+  void add_target_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_TargetCmdline kTargetCmdline{};
+  void add_target_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TargetCmdline::kFieldId, data, size);
+  }
+  void add_target_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TargetCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_target_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExcludePid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_ExcludePid kExcludePid{};
+  void add_exclude_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludePid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExcludeCmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_ExcludeCmdline kExcludeCmdline{};
+  void add_exclude_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ExcludeCmdline::kFieldId, data, size);
+  }
+  void add_exclude_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ExcludeCmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_exclude_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludeCmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AdditionalCmdlineCount =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_AdditionalCmdlineCount kAdditionalCmdlineCount{};
+  void set_additional_cmdline_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdditionalCmdlineCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessShardCount =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfEventConfig_Scope>;
+
+  static constexpr FieldMetadata_ProcessShardCount kProcessShardCount{};
+  void set_process_shard_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessShardCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PerfEventConfig_CallstackSampling_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfEventConfig_CallstackSampling_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfEventConfig_CallstackSampling_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfEventConfig_CallstackSampling_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_scope() const { return at<1>().valid(); }
+  ::protozero::ConstBytes scope() const { return at<1>().as_bytes(); }
+  bool has_kernel_frames() const { return at<2>().valid(); }
+  bool kernel_frames() const { return at<2>().as_bool(); }
+  bool has_user_frames() const { return at<3>().valid(); }
+  int32_t user_frames() const { return at<3>().as_int32(); }
+};
+
+class PerfEventConfig_CallstackSampling : public ::protozero::Message {
+ public:
+  using Decoder = PerfEventConfig_CallstackSampling_Decoder;
+  enum : int32_t {
+    kScopeFieldNumber = 1,
+    kKernelFramesFieldNumber = 2,
+    kUserFramesFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfEventConfig.CallstackSampling"; }
+
+
+  using FieldMetadata_Scope =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEventConfig_Scope,
+      PerfEventConfig_CallstackSampling>;
+
+  static constexpr FieldMetadata_Scope kScope{};
+  template <typename T = PerfEventConfig_Scope> T* set_scope() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_KernelFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PerfEventConfig_CallstackSampling>;
+
+  static constexpr FieldMetadata_KernelFrames kKernelFrames{};
+  void set_kernel_frames(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UserFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::PerfEventConfig_UnwindMode,
+      PerfEventConfig_CallstackSampling>;
+
+  static constexpr FieldMetadata_UserFrames kUserFrames{};
+  void set_user_frames(::perfetto::protos::pbzero::PerfEventConfig_UnwindMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_UserFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/statsd/atom_ids.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_ATOM_IDS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+enum AtomId : int32_t {
+  ATOM_UNSPECIFIED = 0,
+  ATOM_BLE_SCAN_STATE_CHANGED = 2,
+  ATOM_PROCESS_STATE_CHANGED = 3,
+  ATOM_BLE_SCAN_RESULT_RECEIVED = 4,
+  ATOM_SENSOR_STATE_CHANGED = 5,
+  ATOM_GPS_SCAN_STATE_CHANGED = 6,
+  ATOM_SYNC_STATE_CHANGED = 7,
+  ATOM_SCHEDULED_JOB_STATE_CHANGED = 8,
+  ATOM_SCREEN_BRIGHTNESS_CHANGED = 9,
+  ATOM_WAKELOCK_STATE_CHANGED = 10,
+  ATOM_LONG_PARTIAL_WAKELOCK_STATE_CHANGED = 11,
+  ATOM_MOBILE_RADIO_POWER_STATE_CHANGED = 12,
+  ATOM_WIFI_RADIO_POWER_STATE_CHANGED = 13,
+  ATOM_ACTIVITY_MANAGER_SLEEP_STATE_CHANGED = 14,
+  ATOM_MEMORY_FACTOR_STATE_CHANGED = 15,
+  ATOM_EXCESSIVE_CPU_USAGE_REPORTED = 16,
+  ATOM_CACHED_KILL_REPORTED = 17,
+  ATOM_PROCESS_MEMORY_STAT_REPORTED = 18,
+  ATOM_LAUNCHER_EVENT = 19,
+  ATOM_BATTERY_SAVER_MODE_STATE_CHANGED = 20,
+  ATOM_DEVICE_IDLE_MODE_STATE_CHANGED = 21,
+  ATOM_DEVICE_IDLING_MODE_STATE_CHANGED = 22,
+  ATOM_AUDIO_STATE_CHANGED = 23,
+  ATOM_MEDIA_CODEC_STATE_CHANGED = 24,
+  ATOM_CAMERA_STATE_CHANGED = 25,
+  ATOM_FLASHLIGHT_STATE_CHANGED = 26,
+  ATOM_UID_PROCESS_STATE_CHANGED = 27,
+  ATOM_PROCESS_LIFE_CYCLE_STATE_CHANGED = 28,
+  ATOM_SCREEN_STATE_CHANGED = 29,
+  ATOM_BATTERY_LEVEL_CHANGED = 30,
+  ATOM_CHARGING_STATE_CHANGED = 31,
+  ATOM_PLUGGED_STATE_CHANGED = 32,
+  ATOM_INTERACTIVE_STATE_CHANGED = 33,
+  ATOM_TOUCH_EVENT_REPORTED = 34,
+  ATOM_WAKEUP_ALARM_OCCURRED = 35,
+  ATOM_KERNEL_WAKEUP_REPORTED = 36,
+  ATOM_WIFI_LOCK_STATE_CHANGED = 37,
+  ATOM_WIFI_SIGNAL_STRENGTH_CHANGED = 38,
+  ATOM_WIFI_SCAN_STATE_CHANGED = 39,
+  ATOM_PHONE_SIGNAL_STRENGTH_CHANGED = 40,
+  ATOM_SETTING_CHANGED = 41,
+  ATOM_ACTIVITY_FOREGROUND_STATE_CHANGED = 42,
+  ATOM_ISOLATED_UID_CHANGED = 43,
+  ATOM_PACKET_WAKEUP_OCCURRED = 44,
+  ATOM_WALL_CLOCK_TIME_SHIFTED = 45,
+  ATOM_ANOMALY_DETECTED = 46,
+  ATOM_APP_BREADCRUMB_REPORTED = 47,
+  ATOM_APP_START_OCCURRED = 48,
+  ATOM_APP_START_CANCELED = 49,
+  ATOM_APP_START_FULLY_DRAWN = 50,
+  ATOM_LMK_KILL_OCCURRED = 51,
+  ATOM_PICTURE_IN_PICTURE_STATE_CHANGED = 52,
+  ATOM_WIFI_MULTICAST_LOCK_STATE_CHANGED = 53,
+  ATOM_LMK_STATE_CHANGED = 54,
+  ATOM_APP_START_MEMORY_STATE_CAPTURED = 55,
+  ATOM_SHUTDOWN_SEQUENCE_REPORTED = 56,
+  ATOM_BOOT_SEQUENCE_REPORTED = 57,
+  ATOM_DAVEY_OCCURRED = 58,
+  ATOM_OVERLAY_STATE_CHANGED = 59,
+  ATOM_FOREGROUND_SERVICE_STATE_CHANGED = 60,
+  ATOM_CALL_STATE_CHANGED = 61,
+  ATOM_KEYGUARD_STATE_CHANGED = 62,
+  ATOM_KEYGUARD_BOUNCER_STATE_CHANGED = 63,
+  ATOM_KEYGUARD_BOUNCER_PASSWORD_ENTERED = 64,
+  ATOM_APP_DIED = 65,
+  ATOM_RESOURCE_CONFIGURATION_CHANGED = 66,
+  ATOM_BLUETOOTH_ENABLED_STATE_CHANGED = 67,
+  ATOM_BLUETOOTH_CONNECTION_STATE_CHANGED = 68,
+  ATOM_GPS_SIGNAL_QUALITY_CHANGED = 69,
+  ATOM_USB_CONNECTOR_STATE_CHANGED = 70,
+  ATOM_SPEAKER_IMPEDANCE_REPORTED = 71,
+  ATOM_HARDWARE_FAILED = 72,
+  ATOM_PHYSICAL_DROP_DETECTED = 73,
+  ATOM_CHARGE_CYCLES_REPORTED = 74,
+  ATOM_MOBILE_CONNECTION_STATE_CHANGED = 75,
+  ATOM_MOBILE_RADIO_TECHNOLOGY_CHANGED = 76,
+  ATOM_USB_DEVICE_ATTACHED = 77,
+  ATOM_APP_CRASH_OCCURRED = 78,
+  ATOM_ANR_OCCURRED = 79,
+  ATOM_WTF_OCCURRED = 80,
+  ATOM_LOW_MEM_REPORTED = 81,
+  ATOM_GENERIC_ATOM = 82,
+  ATOM_VIBRATOR_STATE_CHANGED = 84,
+  ATOM_DEFERRED_JOB_STATS_REPORTED = 85,
+  ATOM_THERMAL_THROTTLING = 86,
+  ATOM_BIOMETRIC_ACQUIRED = 87,
+  ATOM_BIOMETRIC_AUTHENTICATED = 88,
+  ATOM_BIOMETRIC_ERROR_OCCURRED = 89,
+  ATOM_UI_EVENT_REPORTED = 90,
+  ATOM_BATTERY_HEALTH_SNAPSHOT = 91,
+  ATOM_SLOW_IO = 92,
+  ATOM_BATTERY_CAUSED_SHUTDOWN = 93,
+  ATOM_PHONE_SERVICE_STATE_CHANGED = 94,
+  ATOM_PHONE_STATE_CHANGED = 95,
+  ATOM_USER_RESTRICTION_CHANGED = 96,
+  ATOM_SETTINGS_UI_CHANGED = 97,
+  ATOM_CONNECTIVITY_STATE_CHANGED = 98,
+  ATOM_SERVICE_STATE_CHANGED = 99,
+  ATOM_SERVICE_LAUNCH_REPORTED = 100,
+  ATOM_FLAG_FLIP_UPDATE_OCCURRED = 101,
+  ATOM_BINARY_PUSH_STATE_CHANGED = 102,
+  ATOM_DEVICE_POLICY_EVENT = 103,
+  ATOM_DOCS_UI_FILE_OP_CANCELED = 104,
+  ATOM_DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED = 105,
+  ATOM_DOCS_UI_FILE_OP_FAILURE = 106,
+  ATOM_DOCS_UI_PROVIDER_FILE_OP = 107,
+  ATOM_DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST = 108,
+  ATOM_DOCS_UI_LAUNCH_REPORTED = 109,
+  ATOM_DOCS_UI_ROOT_VISITED = 110,
+  ATOM_DOCS_UI_STARTUP_MS = 111,
+  ATOM_DOCS_UI_USER_ACTION_REPORTED = 112,
+  ATOM_WIFI_ENABLED_STATE_CHANGED = 113,
+  ATOM_WIFI_RUNNING_STATE_CHANGED = 114,
+  ATOM_APP_COMPACTED = 115,
+  ATOM_NETWORK_DNS_EVENT_REPORTED = 116,
+  ATOM_DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED = 117,
+  ATOM_DOCS_UI_PICK_RESULT_REPORTED = 118,
+  ATOM_DOCS_UI_SEARCH_MODE_REPORTED = 119,
+  ATOM_DOCS_UI_SEARCH_TYPE_REPORTED = 120,
+  ATOM_DATA_STALL_EVENT = 121,
+  ATOM_RESCUE_PARTY_RESET_REPORTED = 122,
+  ATOM_SIGNED_CONFIG_REPORTED = 123,
+  ATOM_GNSS_NI_EVENT_REPORTED = 124,
+  ATOM_BLUETOOTH_LINK_LAYER_CONNECTION_EVENT = 125,
+  ATOM_BLUETOOTH_ACL_CONNECTION_STATE_CHANGED = 126,
+  ATOM_BLUETOOTH_SCO_CONNECTION_STATE_CHANGED = 127,
+  ATOM_APP_DOWNGRADED = 128,
+  ATOM_APP_OPTIMIZED_AFTER_DOWNGRADED = 129,
+  ATOM_LOW_STORAGE_STATE_CHANGED = 130,
+  ATOM_GNSS_NFW_NOTIFICATION_REPORTED = 131,
+  ATOM_GNSS_CONFIGURATION_REPORTED = 132,
+  ATOM_USB_PORT_OVERHEAT_EVENT_REPORTED = 133,
+  ATOM_NFC_ERROR_OCCURRED = 134,
+  ATOM_NFC_STATE_CHANGED = 135,
+  ATOM_NFC_BEAM_OCCURRED = 136,
+  ATOM_NFC_CARDEMULATION_OCCURRED = 137,
+  ATOM_NFC_TAG_OCCURRED = 138,
+  ATOM_NFC_HCE_TRANSACTION_OCCURRED = 139,
+  ATOM_SE_STATE_CHANGED = 140,
+  ATOM_SE_OMAPI_REPORTED = 141,
+  ATOM_BROADCAST_DISPATCH_LATENCY_REPORTED = 142,
+  ATOM_ATTENTION_MANAGER_SERVICE_RESULT_REPORTED = 143,
+  ATOM_ADB_CONNECTION_CHANGED = 144,
+  ATOM_SPEECH_DSP_STAT_REPORTED = 145,
+  ATOM_USB_CONTAMINANT_REPORTED = 146,
+  ATOM_WATCHDOG_ROLLBACK_OCCURRED = 147,
+  ATOM_BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED = 148,
+  ATOM_BUBBLE_UI_CHANGED = 149,
+  ATOM_SCHEDULED_JOB_CONSTRAINT_CHANGED = 150,
+  ATOM_BLUETOOTH_ACTIVE_DEVICE_CHANGED = 151,
+  ATOM_BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED = 152,
+  ATOM_BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED = 153,
+  ATOM_BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED = 154,
+  ATOM_BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED = 155,
+  ATOM_BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED = 156,
+  ATOM_BLUETOOTH_DEVICE_RSSI_REPORTED = 157,
+  ATOM_BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED = 158,
+  ATOM_BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED = 159,
+  ATOM_BLUETOOTH_HCI_TIMEOUT_REPORTED = 160,
+  ATOM_BLUETOOTH_QUALITY_REPORT_REPORTED = 161,
+  ATOM_BLUETOOTH_DEVICE_INFO_REPORTED = 162,
+  ATOM_BLUETOOTH_REMOTE_VERSION_INFO_REPORTED = 163,
+  ATOM_BLUETOOTH_SDP_ATTRIBUTE_REPORTED = 164,
+  ATOM_BLUETOOTH_BOND_STATE_CHANGED = 165,
+  ATOM_BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED = 166,
+  ATOM_BLUETOOTH_SMP_PAIRING_EVENT_REPORTED = 167,
+  ATOM_SCREEN_TIMEOUT_EXTENSION_REPORTED = 168,
+  ATOM_PROCESS_START_TIME = 169,
+  ATOM_PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170,
+  ATOM_BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED = 171,
+  ATOM_DEVICE_IDENTIFIER_ACCESS_DENIED = 172,
+  ATOM_BUBBLE_DEVELOPER_ERROR_REPORTED = 173,
+  ATOM_ASSIST_GESTURE_STAGE_REPORTED = 174,
+  ATOM_ASSIST_GESTURE_FEEDBACK_REPORTED = 175,
+  ATOM_ASSIST_GESTURE_PROGRESS_REPORTED = 176,
+  ATOM_TOUCH_GESTURE_CLASSIFIED = 177,
+  ATOM_HIDDEN_API_USED = 178,
+  ATOM_STYLE_UI_CHANGED = 179,
+  ATOM_PRIVACY_INDICATORS_INTERACTED = 180,
+  ATOM_APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED = 181,
+  ATOM_NETWORK_STACK_REPORTED = 182,
+  ATOM_APP_MOVED_STORAGE_REPORTED = 183,
+  ATOM_BIOMETRIC_ENROLLED = 184,
+  ATOM_SYSTEM_SERVER_WATCHDOG_OCCURRED = 185,
+  ATOM_TOMB_STONE_OCCURRED = 186,
+  ATOM_BLUETOOTH_CLASS_OF_DEVICE_REPORTED = 187,
+  ATOM_INTELLIGENCE_EVENT_REPORTED = 188,
+  ATOM_THERMAL_THROTTLING_SEVERITY_STATE_CHANGED = 189,
+  ATOM_ROLE_REQUEST_RESULT_REPORTED = 190,
+  ATOM_MEDIAMETRICS_AUDIOPOLICY_REPORTED = 191,
+  ATOM_MEDIAMETRICS_AUDIORECORD_REPORTED = 192,
+  ATOM_MEDIAMETRICS_AUDIOTHREAD_REPORTED = 193,
+  ATOM_MEDIAMETRICS_AUDIOTRACK_REPORTED = 194,
+  ATOM_MEDIAMETRICS_CODEC_REPORTED = 195,
+  ATOM_MEDIAMETRICS_DRM_WIDEVINE_REPORTED = 196,
+  ATOM_MEDIAMETRICS_EXTRACTOR_REPORTED = 197,
+  ATOM_MEDIAMETRICS_MEDIADRM_REPORTED = 198,
+  ATOM_MEDIAMETRICS_NUPLAYER_REPORTED = 199,
+  ATOM_MEDIAMETRICS_RECORDER_REPORTED = 200,
+  ATOM_MEDIAMETRICS_DRMMANAGER_REPORTED = 201,
+  ATOM_CAR_POWER_STATE_CHANGED = 203,
+  ATOM_GARAGE_MODE_INFO = 204,
+  ATOM_TEST_ATOM_REPORTED = 205,
+  ATOM_CONTENT_CAPTURE_CALLER_MISMATCH_REPORTED = 206,
+  ATOM_CONTENT_CAPTURE_SERVICE_EVENTS = 207,
+  ATOM_CONTENT_CAPTURE_SESSION_EVENTS = 208,
+  ATOM_CONTENT_CAPTURE_FLUSHED = 209,
+  ATOM_LOCATION_MANAGER_API_USAGE_REPORTED = 210,
+  ATOM_REVIEW_PERMISSIONS_FRAGMENT_RESULT_REPORTED = 211,
+  ATOM_RUNTIME_PERMISSIONS_UPGRADE_RESULT = 212,
+  ATOM_GRANT_PERMISSIONS_ACTIVITY_BUTTON_ACTIONS = 213,
+  ATOM_LOCATION_ACCESS_CHECK_NOTIFICATION_ACTION = 214,
+  ATOM_APP_PERMISSION_FRAGMENT_ACTION_REPORTED = 215,
+  ATOM_APP_PERMISSION_FRAGMENT_VIEWED = 216,
+  ATOM_APP_PERMISSIONS_FRAGMENT_VIEWED = 217,
+  ATOM_PERMISSION_APPS_FRAGMENT_VIEWED = 218,
+  ATOM_TEXT_SELECTION_EVENT = 219,
+  ATOM_TEXT_LINKIFY_EVENT = 220,
+  ATOM_CONVERSATION_ACTIONS_EVENT = 221,
+  ATOM_LANGUAGE_DETECTION_EVENT = 222,
+  ATOM_EXCLUSION_RECT_STATE_CHANGED = 223,
+  ATOM_BACK_GESTURE_REPORTED_REPORTED = 224,
+  ATOM_UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED = 225,
+  ATOM_UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED = 226,
+  ATOM_CAMERA_ACTION_EVENT = 227,
+  ATOM_APP_COMPATIBILITY_CHANGE_REPORTED = 228,
+  ATOM_PERFETTO_UPLOADED = 229,
+  ATOM_VMS_CLIENT_CONNECTION_STATE_CHANGED = 230,
+  ATOM_MEDIA_PROVIDER_SCAN_OCCURRED = 233,
+  ATOM_MEDIA_CONTENT_DELETED = 234,
+  ATOM_MEDIA_PROVIDER_PERMISSION_REQUESTED = 235,
+  ATOM_MEDIA_PROVIDER_SCHEMA_CHANGED = 236,
+  ATOM_MEDIA_PROVIDER_IDLE_MAINTENANCE_FINISHED = 237,
+  ATOM_REBOOT_ESCROW_RECOVERY_REPORTED = 238,
+  ATOM_BOOT_TIME_EVENT_DURATION_REPORTED = 239,
+  ATOM_BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED = 240,
+  ATOM_BOOT_TIME_EVENT_UTC_TIME_REPORTED = 241,
+  ATOM_BOOT_TIME_EVENT_ERROR_CODE_REPORTED = 242,
+  ATOM_USERSPACE_REBOOT_REPORTED = 243,
+  ATOM_NOTIFICATION_REPORTED = 244,
+  ATOM_NOTIFICATION_PANEL_REPORTED = 245,
+  ATOM_NOTIFICATION_CHANNEL_MODIFIED = 246,
+  ATOM_INTEGRITY_CHECK_RESULT_REPORTED = 247,
+  ATOM_INTEGRITY_RULES_PUSHED = 248,
+  ATOM_CB_MESSAGE_REPORTED = 249,
+  ATOM_CB_MESSAGE_ERROR = 250,
+  ATOM_WIFI_HEALTH_STAT_REPORTED = 251,
+  ATOM_WIFI_FAILURE_STAT_REPORTED = 252,
+  ATOM_WIFI_CONNECTION_RESULT_REPORTED = 253,
+  ATOM_APP_FREEZE_CHANGED = 254,
+  ATOM_SNAPSHOT_MERGE_REPORTED = 255,
+  ATOM_FOREGROUND_SERVICE_APP_OP_SESSION_ENDED = 256,
+  ATOM_DISPLAY_JANK_REPORTED = 257,
+  ATOM_APP_STANDBY_BUCKET_CHANGED = 258,
+  ATOM_SHARESHEET_STARTED = 259,
+  ATOM_RANKING_SELECTED = 260,
+  ATOM_TVSETTINGS_UI_INTERACTED = 261,
+  ATOM_LAUNCHER_SNAPSHOT = 262,
+  ATOM_PACKAGE_INSTALLER_V2_REPORTED = 263,
+  ATOM_USER_LIFECYCLE_JOURNEY_REPORTED = 264,
+  ATOM_USER_LIFECYCLE_EVENT_OCCURRED = 265,
+  ATOM_ACCESSIBILITY_SHORTCUT_REPORTED = 266,
+  ATOM_ACCESSIBILITY_SERVICE_REPORTED = 267,
+  ATOM_DOCS_UI_DRAG_AND_DROP_REPORTED = 268,
+  ATOM_APP_USAGE_EVENT_OCCURRED = 269,
+  ATOM_AUTO_REVOKE_NOTIFICATION_CLICKED = 270,
+  ATOM_AUTO_REVOKE_FRAGMENT_APP_VIEWED = 271,
+  ATOM_AUTO_REVOKED_APP_INTERACTION = 272,
+  ATOM_APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION = 273,
+  ATOM_EVS_USAGE_STATS_REPORTED = 274,
+  ATOM_AUDIO_POWER_USAGE_DATA_REPORTED = 275,
+  ATOM_TV_TUNER_STATE_CHANGED = 276,
+  ATOM_MEDIAOUTPUT_OP_SWITCH_REPORTED = 277,
+  ATOM_CB_MESSAGE_FILTERED = 278,
+  ATOM_TV_TUNER_DVR_STATUS = 279,
+  ATOM_TV_CAS_SESSION_OPEN_STATUS = 280,
+  ATOM_ASSISTANT_INVOCATION_REPORTED = 281,
+  ATOM_DISPLAY_WAKE_REPORTED = 282,
+  ATOM_CAR_USER_HAL_MODIFY_USER_REQUEST_REPORTED = 283,
+  ATOM_CAR_USER_HAL_MODIFY_USER_RESPONSE_REPORTED = 284,
+  ATOM_CAR_USER_HAL_POST_SWITCH_RESPONSE_REPORTED = 285,
+  ATOM_CAR_USER_HAL_INITIAL_USER_INFO_REQUEST_REPORTED = 286,
+  ATOM_CAR_USER_HAL_INITIAL_USER_INFO_RESPONSE_REPORTED = 287,
+  ATOM_CAR_USER_HAL_USER_ASSOCIATION_REQUEST_REPORTED = 288,
+  ATOM_CAR_USER_HAL_SET_USER_ASSOCIATION_RESPONSE_REPORTED = 289,
+  ATOM_NETWORK_IP_PROVISIONING_REPORTED = 290,
+  ATOM_NETWORK_DHCP_RENEW_REPORTED = 291,
+  ATOM_NETWORK_VALIDATION_REPORTED = 292,
+  ATOM_NETWORK_STACK_QUIRK_REPORTED = 293,
+  ATOM_MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED = 294,
+  ATOM_MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED = 295,
+  ATOM_MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED = 296,
+  ATOM_MEDIAMETRICS_AUDIODEVICECONNECTION_REPORTED = 297,
+  ATOM_BLOB_COMMITTED = 298,
+  ATOM_BLOB_LEASED = 299,
+  ATOM_BLOB_OPENED = 300,
+  ATOM_CONTACTS_PROVIDER_STATUS_REPORTED = 301,
+  ATOM_KEYSTORE_KEY_EVENT_REPORTED = 302,
+  ATOM_NETWORK_TETHERING_REPORTED = 303,
+  ATOM_IME_TOUCH_REPORTED = 304,
+  ATOM_UI_INTERACTION_FRAME_INFO_REPORTED = 305,
+  ATOM_UI_ACTION_LATENCY_REPORTED = 306,
+  ATOM_WIFI_DISCONNECT_REPORTED = 307,
+  ATOM_WIFI_CONNECTION_STATE_CHANGED = 308,
+  ATOM_HDMI_CEC_ACTIVE_SOURCE_CHANGED = 309,
+  ATOM_HDMI_CEC_MESSAGE_REPORTED = 310,
+  ATOM_AIRPLANE_MODE = 311,
+  ATOM_MODEM_RESTART = 312,
+  ATOM_CARRIER_ID_MISMATCH_REPORTED = 313,
+  ATOM_CARRIER_ID_TABLE_UPDATED = 314,
+  ATOM_DATA_STALL_RECOVERY_REPORTED = 315,
+  ATOM_MEDIAMETRICS_MEDIAPARSER_REPORTED = 316,
+  ATOM_TLS_HANDSHAKE_REPORTED = 317,
+  ATOM_TEXT_CLASSIFIER_API_USAGE_REPORTED = 318,
+  ATOM_CAR_WATCHDOG_KILL_STATS_REPORTED = 319,
+  ATOM_MEDIAMETRICS_PLAYBACK_REPORTED = 320,
+  ATOM_MEDIA_NETWORK_INFO_CHANGED = 321,
+  ATOM_MEDIA_PLAYBACK_STATE_CHANGED = 322,
+  ATOM_MEDIA_PLAYBACK_ERROR_REPORTED = 323,
+  ATOM_MEDIA_PLAYBACK_TRACK_CHANGED = 324,
+  ATOM_WIFI_SCAN_REPORTED = 325,
+  ATOM_WIFI_PNO_SCAN_REPORTED = 326,
+  ATOM_TIF_TUNE_CHANGED = 327,
+  ATOM_AUTO_ROTATE_REPORTED = 328,
+  ATOM_PERFETTO_TRIGGER = 329,
+  ATOM_TRANSCODING_DATA = 330,
+  ATOM_IMS_SERVICE_ENTITLEMENT_UPDATED = 331,
+  ATOM_DEVICE_ROTATED = 333,
+  ATOM_SIM_SPECIFIC_SETTINGS_RESTORED = 334,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_REPORTED = 335,
+  ATOM_PIN_STORAGE_EVENT = 336,
+  ATOM_FACE_DOWN_REPORTED = 337,
+  ATOM_BLUETOOTH_HAL_CRASH_REASON_REPORTED = 338,
+  ATOM_REBOOT_ESCROW_PREPARATION_REPORTED = 339,
+  ATOM_REBOOT_ESCROW_LSKF_CAPTURE_REPORTED = 340,
+  ATOM_REBOOT_ESCROW_REBOOT_REPORTED = 341,
+  ATOM_BINDER_LATENCY_REPORTED = 342,
+  ATOM_MEDIAMETRICS_AAUDIOSTREAM_REPORTED = 343,
+  ATOM_MEDIA_TRANSCODING_SESSION_ENDED = 344,
+  ATOM_MAGNIFICATION_USAGE_REPORTED = 345,
+  ATOM_MAGNIFICATION_MODE_WITH_IME_ON_REPORTED = 346,
+  ATOM_APP_SEARCH_CALL_STATS_REPORTED = 347,
+  ATOM_APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED = 348,
+  ATOM_DEVICE_CONTROL_CHANGED = 349,
+  ATOM_DEVICE_STATE_CHANGED = 350,
+  ATOM_INPUTDEVICE_REGISTERED = 351,
+  ATOM_SMARTSPACE_CARD_REPORTED = 352,
+  ATOM_AUTH_PROMPT_AUTHENTICATE_INVOKED = 353,
+  ATOM_AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED = 354,
+  ATOM_AUTH_ENROLL_ACTION_INVOKED = 355,
+  ATOM_AUTH_DEPRECATED_API_USED = 356,
+  ATOM_UNATTENDED_REBOOT_OCCURRED = 357,
+  ATOM_LONG_REBOOT_BLOCKING_REPORTED = 358,
+  ATOM_LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED = 359,
+  ATOM_FDTRACK_EVENT_OCCURRED = 364,
+  ATOM_TIMEOUT_AUTO_EXTENDED_REPORTED = 365,
+  ATOM_ALARM_BATCH_DELIVERED = 367,
+  ATOM_ALARM_SCHEDULED = 368,
+  ATOM_CAR_WATCHDOG_IO_OVERUSE_STATS_REPORTED = 369,
+  ATOM_USER_LEVEL_HIBERNATION_STATE_CHANGED = 370,
+  ATOM_APP_SEARCH_INITIALIZE_STATS_REPORTED = 371,
+  ATOM_APP_SEARCH_QUERY_STATS_REPORTED = 372,
+  ATOM_APP_PROCESS_DIED = 373,
+  ATOM_NETWORK_IP_REACHABILITY_MONITOR_REPORTED = 374,
+  ATOM_SLOW_INPUT_EVENT_REPORTED = 375,
+  ATOM_ANR_OCCURRED_PROCESSING_STARTED = 376,
+  ATOM_APP_SEARCH_REMOVE_STATS_REPORTED = 377,
+  ATOM_MEDIA_CODEC_REPORTED = 378,
+  ATOM_PERMISSION_USAGE_FRAGMENT_INTERACTION = 379,
+  ATOM_PERMISSION_DETAILS_INTERACTION = 380,
+  ATOM_PRIVACY_SENSOR_TOGGLE_INTERACTION = 381,
+  ATOM_PRIVACY_TOGGLE_DIALOG_INTERACTION = 382,
+  ATOM_APP_SEARCH_OPTIMIZE_STATS_REPORTED = 383,
+  ATOM_NON_A11Y_TOOL_SERVICE_WARNING_REPORT = 384,
+  ATOM_APP_SEARCH_SET_SCHEMA_STATS_REPORTED = 385,
+  ATOM_APP_COMPAT_STATE_CHANGED = 386,
+  ATOM_SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED = 387,
+  ATOM_SPLITSCREEN_UI_CHANGED = 388,
+  ATOM_NETWORK_DNS_HANDSHAKE_REPORTED = 389,
+  ATOM_BLUETOOTH_CODE_PATH_COUNTER = 390,
+  ATOM_BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY = 392,
+  ATOM_ACCESSIBILITY_FLOATING_MENU_UI_CHANGED = 393,
+  ATOM_NEURALNETWORKS_COMPILATION_COMPLETED = 394,
+  ATOM_NEURALNETWORKS_EXECUTION_COMPLETED = 395,
+  ATOM_NEURALNETWORKS_COMPILATION_FAILED = 396,
+  ATOM_NEURALNETWORKS_EXECUTION_FAILED = 397,
+  ATOM_CONTEXT_HUB_BOOTED = 398,
+  ATOM_CONTEXT_HUB_RESTARTED = 399,
+  ATOM_CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED = 400,
+  ATOM_CHRE_CODE_DOWNLOAD_TRANSACTED = 401,
+  ATOM_UWB_SESSION_INITED = 402,
+  ATOM_UWB_SESSION_CLOSED = 403,
+  ATOM_UWB_FIRST_RANGING_RECEIVED = 404,
+  ATOM_UWB_RANGING_MEASUREMENT_RECEIVED = 405,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED = 406,
+  ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED = 407,
+  ATOM_CLIPBOARD_CLEARED = 408,
+  ATOM_VM_CREATION_REQUESTED = 409,
+  ATOM_NEARBY_DEVICE_SCAN_STATE_CHANGED = 410,
+  ATOM_CAMERA_COMPAT_CONTROL_EVENT_REPORTED = 411,
+  ATOM_APPLICATION_LOCALES_CHANGED = 412,
+  ATOM_MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED = 413,
+  ATOM_FOLD_STATE_DURATION_REPORTED = 414,
+  ATOM_LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED = 415,
+  ATOM_DISPLAY_HBM_STATE_CHANGED = 416,
+  ATOM_DISPLAY_HBM_BRIGHTNESS_CHANGED = 417,
+  ATOM_PERSISTENT_URI_PERMISSIONS_FLUSHED = 418,
+  ATOM_EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED = 419,
+  ATOM_VBMETA_DIGEST_REPORTED = 420,
+  ATOM_APEX_INFO_GATHERED = 421,
+  ATOM_PVM_INFO_GATHERED = 422,
+  ATOM_WEAR_SETTINGS_UI_INTERACTED = 423,
+  ATOM_TRACING_SERVICE_REPORT_EVENT = 424,
+  ATOM_MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED = 425,
+  ATOM_LAUNCHER_LATENCY = 426,
+  ATOM_DROPBOX_ENTRY_DROPPED = 427,
+  ATOM_WIFI_P2P_CONNECTION_REPORTED = 428,
+  ATOM_GAME_STATE_CHANGED = 429,
+  ATOM_HOTWORD_DETECTOR_CREATE_REQUESTED = 430,
+  ATOM_HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED = 431,
+  ATOM_HOTWORD_DETECTION_SERVICE_RESTARTED = 432,
+  ATOM_HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED = 433,
+  ATOM_HOTWORD_DETECTOR_EVENTS = 434,
+  ATOM_AD_SERVICES_API_CALLED = 435,
+  ATOM_AD_SERVICES_MESUREMENT_REPORTS_UPLOADED = 436,
+  ATOM_BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED = 437,
+  ATOM_CONTACTS_INDEXER_UPDATE_STATS_REPORTED = 440,
+  ATOM_APP_BACKGROUND_RESTRICTIONS_INFO = 441,
+  ATOM_MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED = 442,
+  ATOM_MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED = 443,
+  ATOM_PERMISSION_REMINDER_NOTIFICATION_INTERACTED = 444,
+  ATOM_RECENT_PERMISSION_DECISIONS_INTERACTED = 445,
+  ATOM_GNSS_PSDS_DOWNLOAD_REPORTED = 446,
+  ATOM_LE_AUDIO_CONNECTION_SESSION_REPORTED = 447,
+  ATOM_LE_AUDIO_BROADCAST_SESSION_REPORTED = 448,
+  ATOM_DREAM_UI_EVENT_REPORTED = 449,
+  ATOM_TASK_MANAGER_EVENT_REPORTED = 450,
+  ATOM_CDM_ASSOCIATION_ACTION = 451,
+  ATOM_MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED = 452,
+  ATOM_MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED = 453,
+  ATOM_ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED = 454,
+  ATOM_WIFI_SETUP_FAILURE_CRASH_REPORTED = 455,
+  ATOM_UWB_DEVICE_ERROR_REPORTED = 456,
+  ATOM_ISOLATED_COMPILATION_SCHEDULED = 457,
+  ATOM_ISOLATED_COMPILATION_ENDED = 458,
+  ATOM_ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE = 459,
+  ATOM_SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED = 460,
+  ATOM_TELEPHONY_ANOMALY_DETECTED = 461,
+  ATOM_LETTERBOX_POSITION_CHANGED = 462,
+  ATOM_REMOTE_KEY_PROVISIONING_ATTEMPT = 463,
+  ATOM_REMOTE_KEY_PROVISIONING_NETWORK_INFO = 464,
+  ATOM_REMOTE_KEY_PROVISIONING_TIMING = 465,
+  ATOM_MEDIAOUTPUT_OP_INTERACTION_REPORT = 466,
+  ATOM_SYNC_EXEMPTION_OCCURRED = 468,
+  ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED = 469,
+  ATOM_DOCK_STATE_CHANGED = 470,
+  ATOM_SAFETY_SOURCE_STATE_COLLECTED = 471,
+  ATOM_SAFETY_CENTER_SYSTEM_EVENT_REPORTED = 472,
+  ATOM_SAFETY_CENTER_INTERACTION_REPORTED = 473,
+  ATOM_SETTINGS_PROVIDER_SETTING_CHANGED = 474,
+  ATOM_BROADCAST_DELIVERY_EVENT_REPORTED = 475,
+  ATOM_SERVICE_REQUEST_EVENT_REPORTED = 476,
+  ATOM_PROVIDER_ACQUISITION_EVENT_REPORTED = 477,
+  ATOM_BLUETOOTH_DEVICE_NAME_REPORTED = 478,
+  ATOM_CB_CONFIG_UPDATED = 479,
+  ATOM_CB_MODULE_ERROR_REPORTED = 480,
+  ATOM_CB_SERVICE_FEATURE_CHANGED = 481,
+  ATOM_CB_RECEIVER_FEATURE_CHANGED = 482,
+  ATOM_JSSCRIPTENGINE_LATENCY_REPORTED = 483,
+  ATOM_PRIVACY_SIGNAL_NOTIFICATION_INTERACTION = 484,
+  ATOM_PRIVACY_SIGNAL_ISSUE_CARD_INTERACTION = 485,
+  ATOM_PRIVACY_SIGNALS_JOB_FAILURE = 486,
+  ATOM_VIBRATION_REPORTED = 487,
+  ATOM_UWB_RANGING_START = 489,
+  ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED = 490,
+  ATOM_APP_COMPACTED_V2 = 491,
+  ATOM_AD_SERVICES_SETTINGS_USAGE_REPORTED = 493,
+  ATOM_DISPLAY_BRIGHTNESS_CHANGED = 494,
+  ATOM_ACTIVITY_ACTION_BLOCKED = 495,
+  ATOM_BACKGROUND_FETCH_PROCESS_REPORTED = 496,
+  ATOM_UPDATE_CUSTOM_AUDIENCE_PROCESS_REPORTED = 497,
+  ATOM_RUN_AD_BIDDING_PROCESS_REPORTED = 498,
+  ATOM_RUN_AD_SCORING_PROCESS_REPORTED = 499,
+  ATOM_RUN_AD_SELECTION_PROCESS_REPORTED = 500,
+  ATOM_RUN_AD_BIDDING_PER_CA_PROCESS_REPORTED = 501,
+  ATOM_MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED = 502,
+  ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED = 503,
+  ATOM_NETWORK_DNS_SERVER_SUPPORT_REPORTED = 504,
+  ATOM_VM_BOOTED = 505,
+  ATOM_VM_EXITED = 506,
+  ATOM_AMBIENT_BRIGHTNESS_STATS_REPORTED = 507,
+  ATOM_MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED = 508,
+  ATOM_MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED = 509,
+  ATOM_MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED = 510,
+  ATOM_MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED = 511,
+  ATOM_AD_SERVICES_MEASUREMENT_REGISTRATIONS = 512,
+  ATOM_HEARING_AID_INFO_REPORTED = 513,
+  ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED = 514,
+  ATOM_AMBIENT_MODE_CHANGED = 515,
+  ATOM_ANR_LATENCY_REPORTED = 516,
+  ATOM_RESOURCE_API_INFO = 517,
+  ATOM_SYSTEM_DEFAULT_NETWORK_CHANGED = 518,
+  ATOM_IWLAN_SETUP_DATA_CALL_RESULT_REPORTED = 519,
+  ATOM_IWLAN_PDN_DISCONNECTED_REASON_REPORTED = 520,
+  ATOM_AIRPLANE_MODE_SESSION_REPORTED = 521,
+  ATOM_VM_CPU_STATUS_REPORTED = 522,
+  ATOM_VM_MEM_STATUS_REPORTED = 523,
+  ATOM_PACKAGE_INSTALLATION_SESSION_REPORTED = 524,
+  ATOM_DEFAULT_NETWORK_REMATCH_INFO = 525,
+  ATOM_NETWORK_SELECTION_PERFORMANCE = 526,
+  ATOM_NETWORK_NSD_REPORTED = 527,
+  ATOM_BLUETOOTH_DISCONNECTION_REASON_REPORTED = 529,
+  ATOM_BLUETOOTH_LOCAL_VERSIONS_REPORTED = 530,
+  ATOM_BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED = 531,
+  ATOM_BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED = 532,
+  ATOM_BLUETOOTH_GATT_APP_INFO = 533,
+  ATOM_BRIGHTNESS_CONFIGURATION_UPDATED = 534,
+  ATOM_AD_SERVICES_GET_TOPICS_REPORTED = 535,
+  ATOM_AD_SERVICES_EPOCH_COMPUTATION_GET_TOP_TOPICS_REPORTED = 536,
+  ATOM_AD_SERVICES_EPOCH_COMPUTATION_CLASSIFIER_REPORTED = 537,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_LAUNCHED = 538,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FINISHED = 539,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECTION_REPORTED = 540,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_TRIGGERED = 541,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FIRST_DEVICE_SCAN_LATENCY = 542,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECT_DEVICE_LATENCY = 543,
+  ATOM_PACKAGE_MANAGER_SNAPSHOT_REPORTED = 544,
+  ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED = 545,
+  ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED = 546,
+  ATOM_LAUNCHER_IMPRESSION_EVENT = 547,
+  ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_ALL_DEVICES_SCAN_LATENCY = 549,
+  ATOM_WS_WATCH_FACE_EDITED = 551,
+  ATOM_WS_WATCH_FACE_FAVORITE_ACTION_REPORTED = 552,
+  ATOM_WS_WATCH_FACE_SET_ACTION_REPORTED = 553,
+  ATOM_PACKAGE_UNINSTALLATION_REPORTED = 554,
+  ATOM_GAME_MODE_CHANGED = 555,
+  ATOM_GAME_MODE_CONFIGURATION_CHANGED = 556,
+  ATOM_BEDTIME_MODE_STATE_CHANGED = 557,
+  ATOM_NETWORK_SLICE_SESSION_ENDED = 558,
+  ATOM_NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED = 559,
+  ATOM_NFC_TAG_TYPE_OCCURRED = 560,
+  ATOM_NFC_AID_CONFLICT_OCCURRED = 561,
+  ATOM_NFC_READER_CONFLICT_OCCURRED = 562,
+  ATOM_WS_TILE_LIST_CHANGED = 563,
+  ATOM_GET_TYPE_ACCESSED_WITHOUT_PERMISSION = 564,
+  ATOM_MOBILE_BUNDLED_APP_INFO_GATHERED = 566,
+  ATOM_WS_WATCH_FACE_COMPLICATION_SET_CHANGED = 567,
+  ATOM_MEDIA_DRM_CREATED = 568,
+  ATOM_MEDIA_DRM_ERRORED = 569,
+  ATOM_MEDIA_DRM_SESSION_OPENED = 570,
+  ATOM_MEDIA_DRM_SESSION_CLOSED = 571,
+  ATOM_USER_SELECTED_RESOLUTION = 572,
+  ATOM_UNSAFE_INTENT_EVENT_REPORTED = 573,
+  ATOM_PERFORMANCE_HINT_SESSION_REPORTED = 574,
+  ATOM_MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED = 576,
+  ATOM_BIOMETRIC_TOUCH_REPORTED = 577,
+  ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED = 578,
+  ATOM_APP_SEARCH_SCHEMA_MIGRATION_STATS_REPORTED = 579,
+  ATOM_LOCATION_ENABLED_STATE_CHANGED = 580,
+  ATOM_IME_REQUEST_FINISHED = 581,
+  ATOM_USB_COMPLIANCE_WARNINGS_REPORTED = 582,
+  ATOM_APP_SUPPORTED_LOCALES_CHANGED = 583,
+  ATOM_GRAMMATICAL_INFLECTION_CHANGED = 584,
+  ATOM_MEDIA_PROVIDER_VOLUME_RECOVERY_REPORTED = 586,
+  ATOM_BIOMETRIC_PROPERTIES_COLLECTED = 587,
+  ATOM_KERNEL_WAKEUP_ATTRIBUTED = 588,
+  ATOM_SCREEN_STATE_CHANGED_V2 = 589,
+  ATOM_WS_BACKUP_ACTION_REPORTED = 590,
+  ATOM_WS_RESTORE_ACTION_REPORTED = 591,
+  ATOM_DEVICE_LOG_ACCESS_EVENT_REPORTED = 592,
+  ATOM_MEDIA_SESSION_UPDATED = 594,
+  ATOM_WEAR_OOBE_STATE_CHANGED = 595,
+  ATOM_WS_NOTIFICATION_UPDATED = 596,
+  ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED = 601,
+  ATOM_WS_COMPLICATION_TAPPED = 602,
+  ATOM_WS_WEAR_TIME_SESSION = 610,
+  ATOM_WIFI_BYTES_TRANSFER = 10000,
+  ATOM_WIFI_BYTES_TRANSFER_BY_FG_BG = 10001,
+  ATOM_MOBILE_BYTES_TRANSFER = 10002,
+  ATOM_MOBILE_BYTES_TRANSFER_BY_FG_BG = 10003,
+  ATOM_BLUETOOTH_BYTES_TRANSFER = 10006,
+  ATOM_KERNEL_WAKELOCK = 10004,
+  ATOM_SUBSYSTEM_SLEEP_STATE = 10005,
+  ATOM_CPU_TIME_PER_UID = 10009,
+  ATOM_CPU_TIME_PER_UID_FREQ = 10010,
+  ATOM_WIFI_ACTIVITY_INFO = 10011,
+  ATOM_MODEM_ACTIVITY_INFO = 10012,
+  ATOM_BLUETOOTH_ACTIVITY_INFO = 10007,
+  ATOM_PROCESS_MEMORY_STATE = 10013,
+  ATOM_SYSTEM_ELAPSED_REALTIME = 10014,
+  ATOM_SYSTEM_UPTIME = 10015,
+  ATOM_CPU_ACTIVE_TIME = 10016,
+  ATOM_CPU_CLUSTER_TIME = 10017,
+  ATOM_DISK_SPACE = 10018,
+  ATOM_REMAINING_BATTERY_CAPACITY = 10019,
+  ATOM_FULL_BATTERY_CAPACITY = 10020,
+  ATOM_TEMPERATURE = 10021,
+  ATOM_BINDER_CALLS = 10022,
+  ATOM_BINDER_CALLS_EXCEPTIONS = 10023,
+  ATOM_LOOPER_STATS = 10024,
+  ATOM_DISK_STATS = 10025,
+  ATOM_DIRECTORY_USAGE = 10026,
+  ATOM_APP_SIZE = 10027,
+  ATOM_CATEGORY_SIZE = 10028,
+  ATOM_PROC_STATS = 10029,
+  ATOM_BATTERY_VOLTAGE = 10030,
+  ATOM_NUM_FINGERPRINTS_ENROLLED = 10031,
+  ATOM_DISK_IO = 10032,
+  ATOM_POWER_PROFILE = 10033,
+  ATOM_PROC_STATS_PKG_PROC = 10034,
+  ATOM_PROCESS_CPU_TIME = 10035,
+  ATOM_CPU_TIME_PER_THREAD_FREQ = 10037,
+  ATOM_ON_DEVICE_POWER_MEASUREMENT = 10038,
+  ATOM_DEVICE_CALCULATED_POWER_USE = 10039,
+  ATOM_PROCESS_MEMORY_HIGH_WATER_MARK = 10042,
+  ATOM_BATTERY_LEVEL = 10043,
+  ATOM_BUILD_INFORMATION = 10044,
+  ATOM_BATTERY_CYCLE_COUNT = 10045,
+  ATOM_DEBUG_ELAPSED_CLOCK = 10046,
+  ATOM_DEBUG_FAILING_ELAPSED_CLOCK = 10047,
+  ATOM_NUM_FACES_ENROLLED = 10048,
+  ATOM_ROLE_HOLDER = 10049,
+  ATOM_DANGEROUS_PERMISSION_STATE = 10050,
+  ATOM_TRAIN_INFO = 10051,
+  ATOM_TIME_ZONE_DATA_INFO = 10052,
+  ATOM_EXTERNAL_STORAGE_INFO = 10053,
+  ATOM_GPU_STATS_GLOBAL_INFO = 10054,
+  ATOM_GPU_STATS_APP_INFO = 10055,
+  ATOM_SYSTEM_ION_HEAP_SIZE = 10056,
+  ATOM_APPS_ON_EXTERNAL_STORAGE_INFO = 10057,
+  ATOM_FACE_SETTINGS = 10058,
+  ATOM_COOLING_DEVICE = 10059,
+  ATOM_APP_OPS = 10060,
+  ATOM_PROCESS_SYSTEM_ION_HEAP_SIZE = 10061,
+  ATOM_SURFACEFLINGER_STATS_GLOBAL_INFO = 10062,
+  ATOM_SURFACEFLINGER_STATS_LAYER_INFO = 10063,
+  ATOM_PROCESS_MEMORY_SNAPSHOT = 10064,
+  ATOM_VMS_CLIENT_STATS = 10065,
+  ATOM_NOTIFICATION_REMOTE_VIEWS = 10066,
+  ATOM_DANGEROUS_PERMISSION_STATE_SAMPLED = 10067,
+  ATOM_GRAPHICS_STATS = 10068,
+  ATOM_RUNTIME_APP_OP_ACCESS = 10069,
+  ATOM_ION_HEAP_SIZE = 10070,
+  ATOM_PACKAGE_NOTIFICATION_PREFERENCES = 10071,
+  ATOM_PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES = 10072,
+  ATOM_PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES = 10073,
+  ATOM_GNSS_STATS = 10074,
+  ATOM_ATTRIBUTED_APP_OPS = 10075,
+  ATOM_VOICE_CALL_SESSION = 10076,
+  ATOM_VOICE_CALL_RAT_USAGE = 10077,
+  ATOM_SIM_SLOT_STATE = 10078,
+  ATOM_SUPPORTED_RADIO_ACCESS_FAMILY = 10079,
+  ATOM_SETTING_SNAPSHOT = 10080,
+  ATOM_BLOB_INFO = 10081,
+  ATOM_DATA_USAGE_BYTES_TRANSFER = 10082,
+  ATOM_BYTES_TRANSFER_BY_TAG_AND_METERED = 10083,
+  ATOM_DND_MODE_RULE = 10084,
+  ATOM_GENERAL_EXTERNAL_STORAGE_ACCESS_STATS = 10085,
+  ATOM_INCOMING_SMS = 10086,
+  ATOM_OUTGOING_SMS = 10087,
+  ATOM_CARRIER_ID_TABLE_VERSION = 10088,
+  ATOM_DATA_CALL_SESSION = 10089,
+  ATOM_CELLULAR_SERVICE_STATE = 10090,
+  ATOM_CELLULAR_DATA_SERVICE_SWITCH = 10091,
+  ATOM_SYSTEM_MEMORY = 10092,
+  ATOM_IMS_REGISTRATION_TERMINATION = 10093,
+  ATOM_IMS_REGISTRATION_STATS = 10094,
+  ATOM_CPU_TIME_PER_CLUSTER_FREQ = 10095,
+  ATOM_CPU_CYCLES_PER_UID_CLUSTER = 10096,
+  ATOM_DEVICE_ROTATED_DATA = 10097,
+  ATOM_CPU_CYCLES_PER_THREAD_GROUP_CLUSTER = 10098,
+  ATOM_MEDIA_DRM_ACTIVITY_INFO = 10099,
+  ATOM_OEM_MANAGED_BYTES_TRANSFER = 10100,
+  ATOM_GNSS_POWER_STATS = 10101,
+  ATOM_TIME_ZONE_DETECTOR_STATE = 10102,
+  ATOM_KEYSTORE2_STORAGE_STATS = 10103,
+  ATOM_RKP_POOL_STATS = 10104,
+  ATOM_PROCESS_DMABUF_MEMORY = 10105,
+  ATOM_PENDING_ALARM_INFO = 10106,
+  ATOM_USER_LEVEL_HIBERNATED_APPS = 10107,
+  ATOM_LAUNCHER_LAYOUT_SNAPSHOT = 10108,
+  ATOM_GLOBAL_HIBERNATED_APPS = 10109,
+  ATOM_INPUT_EVENT_LATENCY_SKETCH = 10110,
+  ATOM_BATTERY_USAGE_STATS_BEFORE_RESET = 10111,
+  ATOM_BATTERY_USAGE_STATS_SINCE_RESET = 10112,
+  ATOM_BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL = 10113,
+  ATOM_INSTALLED_INCREMENTAL_PACKAGE = 10114,
+  ATOM_TELEPHONY_NETWORK_REQUESTS = 10115,
+  ATOM_APP_SEARCH_STORAGE_INFO = 10116,
+  ATOM_VMSTAT = 10117,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO = 10118,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO = 10119,
+  ATOM_KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO = 10120,
+  ATOM_KEYSTORE2_ATOM_WITH_OVERFLOW = 10121,
+  ATOM_KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO = 10122,
+  ATOM_KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO = 10123,
+  ATOM_RKP_ERROR_STATS = 10124,
+  ATOM_KEYSTORE2_CRASH_STATS = 10125,
+  ATOM_VENDOR_APEX_INFO = 10126,
+  ATOM_ACCESSIBILITY_SHORTCUT_STATS = 10127,
+  ATOM_ACCESSIBILITY_FLOATING_MENU_STATS = 10128,
+  ATOM_DATA_USAGE_BYTES_TRANSFER_V2 = 10129,
+  ATOM_MEDIA_CAPABILITIES = 10130,
+  ATOM_CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY = 10131,
+  ATOM_CAR_WATCHDOG_UID_IO_USAGE_SUMMARY = 10132,
+  ATOM_IMS_REGISTRATION_FEATURE_TAG_STATS = 10133,
+  ATOM_RCS_CLIENT_PROVISIONING_STATS = 10134,
+  ATOM_RCS_ACS_PROVISIONING_STATS = 10135,
+  ATOM_SIP_DELEGATE_STATS = 10136,
+  ATOM_SIP_TRANSPORT_FEATURE_TAG_STATS = 10137,
+  ATOM_SIP_MESSAGE_RESPONSE = 10138,
+  ATOM_SIP_TRANSPORT_SESSION = 10139,
+  ATOM_IMS_DEDICATED_BEARER_LISTENER_EVENT = 10140,
+  ATOM_IMS_DEDICATED_BEARER_EVENT = 10141,
+  ATOM_IMS_REGISTRATION_SERVICE_DESC_STATS = 10142,
+  ATOM_UCE_EVENT_STATS = 10143,
+  ATOM_PRESENCE_NOTIFY_EVENT = 10144,
+  ATOM_GBA_EVENT = 10145,
+  ATOM_PER_SIM_STATUS = 10146,
+  ATOM_GPU_WORK_PER_UID = 10147,
+  ATOM_PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE = 10148,
+  ATOM_SIGNED_PARTITION_INFO = 10149,
+  ATOM_PINNED_FILE_SIZES_PER_PACKAGE = 10150,
+  ATOM_PENDING_INTENTS_PER_PACKAGE = 10151,
+  ATOM_USER_INFO = 10152,
+  ATOM_TELEPHONY_NETWORK_REQUESTS_V2 = 10153,
+  ATOM_DEVICE_TELEPHONY_PROPERTIES = 10154,
+  ATOM_REMOTE_KEY_PROVISIONING_ERROR_COUNTS = 10155,
+  ATOM_SAFETY_STATE = 10156,
+  ATOM_INCOMING_MMS = 10157,
+  ATOM_OUTGOING_MMS = 10158,
+  ATOM_MULTI_USER_INFO = 10160,
+  ATOM_NETWORK_BPF_MAP_INFO = 10161,
+  ATOM_OUTGOING_SHORT_CODE_SMS = 10162,
+  ATOM_CONNECTIVITY_STATE_SAMPLE = 10163,
+  ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO = 10164,
+  ATOM_GAME_MODE_INFO = 10165,
+  ATOM_GAME_MODE_CONFIGURATION = 10166,
+  ATOM_GAME_MODE_LISTENER = 10167,
+  ATOM_NETWORK_SLICE_REQUEST_COUNT = 10168,
+  ATOM_WS_TILE_SNAPSHOT = 10169,
+  ATOM_WS_ACTIVE_WATCH_FACE_COMPLICATION_SET_SNAPSHOT = 10170,
+  ATOM_PROCESS_STATE = 10171,
+  ATOM_PROCESS_ASSOCIATION = 10172,
+  ATOM_ADPF_SYSTEM_COMPONENT_INFO = 10173,
+  ATOM_NOTIFICATION_MEMORY_USE = 10174,
+  ATOM_HDR_CAPABILITIES = 10175,
+  ATOM_WS_FAVOURITE_WATCH_FACE_LIST_SNAPSHOT = 10176,
+  ATOM_WIFI_AWARE_NDP_REPORTED = 638,
+  ATOM_WIFI_AWARE_ATTACH_REPORTED = 639,
+  ATOM_WIFI_SELF_RECOVERY_TRIGGERED = 661,
+  ATOM_SOFT_AP_STARTED = 680,
+  ATOM_SOFT_AP_STOPPED = 681,
+  ATOM_WIFI_LOCK_RELEASED = 687,
+  ATOM_WIFI_LOCK_DEACTIVATED = 688,
+  ATOM_WIFI_CONFIG_SAVED = 689,
+  ATOM_WIFI_AWARE_RESOURCE_USING_CHANGED = 690,
+  ATOM_WIFI_AWARE_HAL_API_CALLED = 691,
+  ATOM_WIFI_LOCAL_ONLY_REQUEST_RECEIVED = 692,
+  ATOM_WIFI_LOCAL_ONLY_REQUEST_SCAN_TRIGGERED = 693,
+  ATOM_WIFI_THREAD_TASK_EXECUTED = 694,
+  ATOM_WIFI_STATE_CHANGED = 700,
+  ATOM_WIFI_AWARE_CAPABILITIES = 10190,
+  ATOM_WIFI_MODULE_INFO = 10193,
+  ATOM_SETTINGS_SPA_REPORTED = 622,
+  ATOM_EXPRESS_EVENT_REPORTED = 528,
+  ATOM_EXPRESS_HISTOGRAM_SAMPLE_REPORTED = 593,
+  ATOM_EXPRESS_UID_EVENT_REPORTED = 644,
+  ATOM_EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED = 658,
+  ATOM_PERMISSION_RATIONALE_DIALOG_VIEWED = 645,
+  ATOM_PERMISSION_RATIONALE_DIALOG_ACTION_REPORTED = 646,
+  ATOM_APP_DATA_SHARING_UPDATES_NOTIFICATION_INTERACTION = 647,
+  ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_VIEWED = 648,
+  ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_ACTION_REPORTED = 649,
+  ATOM_WS_INCOMING_CALL_ACTION_REPORTED = 626,
+  ATOM_WS_CALL_DISCONNECTION_REPORTED = 627,
+  ATOM_WS_CALL_DURATION_REPORTED = 628,
+  ATOM_WS_CALL_USER_EXPERIENCE_LATENCY_REPORTED = 629,
+  ATOM_WS_CALL_INTERACTION_REPORTED = 630,
+  ATOM_FULL_SCREEN_INTENT_LAUNCHED = 631,
+  ATOM_BAL_ALLOWED = 632,
+  ATOM_IN_TASK_ACTIVITY_STARTED = 685,
+  ATOM_CACHED_APPS_HIGH_WATERMARK = 10189,
+  ATOM_ODREFRESH_REPORTED = 366,
+  ATOM_ODSIGN_REPORTED = 548,
+  ATOM_ART_DATUM_REPORTED = 332,
+  ATOM_ART_DEVICE_DATUM_REPORTED = 550,
+  ATOM_ART_DATUM_DELTA_REPORTED = 565,
+  ATOM_BACKGROUND_DEXOPT_JOB_ENDED = 467,
+  ATOM_WEAR_ADAPTIVE_SUSPEND_STATS_REPORTED = 619,
+  ATOM_WEAR_POWER_ANOMALY_SERVICE_OPERATIONAL_STATS_REPORTED = 620,
+  ATOM_WEAR_POWER_ANOMALY_SERVICE_EVENT_STATS_REPORTED = 621,
+  ATOM_EMERGENCY_STATE_CHANGED = 633,
+  ATOM_DND_STATE_CHANGED = 657,
+  ATOM_MTE_STATE = 10181,
+  ATOM_AD_SERVICES_BACK_COMPAT_GET_TOPICS_REPORTED = 598,
+  ATOM_AD_SERVICES_BACK_COMPAT_EPOCH_COMPUTATION_CLASSIFIER_REPORTED = 599,
+  ATOM_AD_SERVICES_MEASUREMENT_DEBUG_KEYS = 640,
+  ATOM_AD_SERVICES_ERROR_REPORTED = 662,
+  ATOM_AD_SERVICES_BACKGROUND_JOBS_EXECUTION_REPORTED = 663,
+  ATOM_AD_SERVICES_MEASUREMENT_DELAYED_SOURCE_REGISTRATION = 673,
+  ATOM_AD_SERVICES_MEASUREMENT_ATTRIBUTION = 674,
+  ATOM_AD_SERVICES_MEASUREMENT_JOBS = 675,
+  ATOM_AD_SERVICES_MEASUREMENT_WIPEOUT = 676,
+  ATOM_AD_SERVICES_CONSENT_MIGRATED = 702,
+  ATOM_RKPD_POOL_STATS = 664,
+  ATOM_RKPD_CLIENT_OPERATION = 665,
+  ATOM_AUTOFILL_UI_EVENT_REPORTED = 603,
+  ATOM_AUTOFILL_FILL_REQUEST_REPORTED = 604,
+  ATOM_AUTOFILL_FILL_RESPONSE_REPORTED = 605,
+  ATOM_AUTOFILL_SAVE_EVENT_REPORTED = 606,
+  ATOM_AUTOFILL_SESSION_COMMITTED = 607,
+  ATOM_AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED = 659,
+  ATOM_TEST_EXTENSION_ATOM_REPORTED = 660,
+  ATOM_TEST_RESTRICTED_ATOM_REPORTED = 672,
+  ATOM_STATS_SOCKET_LOSS_REPORTED = 752,
+  ATOM_PLUGIN_INITIALIZED = 655,
+  ATOM_TV_LOW_POWER_STANDBY_POLICY = 679,
+  ATOM_LOCKSCREEN_SHORTCUT_SELECTED = 611,
+  ATOM_LOCKSCREEN_SHORTCUT_TRIGGERED = 612,
+  ATOM_EMERGENCY_NUMBERS_INFO = 10180,
+  ATOM_QUALIFIED_RAT_LIST_CHANGED = 634,
+  ATOM_QNS_IMS_CALL_DROP_STATS = 635,
+  ATOM_QNS_FALLBACK_RESTRICTION_CHANGED = 636,
+  ATOM_QNS_RAT_PREFERENCE_MISMATCH_INFO = 10177,
+  ATOM_QNS_HANDOVER_TIME_MILLIS = 10178,
+  ATOM_QNS_HANDOVER_PINGPONG = 10179,
+  ATOM_SATELLITE_CONTROLLER = 10182,
+  ATOM_SATELLITE_SESSION = 10183,
+  ATOM_SATELLITE_INCOMING_DATAGRAM = 10184,
+  ATOM_SATELLITE_OUTGOING_DATAGRAM = 10185,
+  ATOM_SATELLITE_PROVISION = 10186,
+  ATOM_SATELLITE_SOS_MESSAGE_RECOMMENDER = 10187,
+  ATOM_IKE_SESSION_TERMINATED = 678,
+  ATOM_IKE_LIVENESS_CHECK_SESSION_VALIDATED = 760,
+  ATOM_BLUETOOTH_HASHED_DEVICE_NAME_REPORTED = 613,
+  ATOM_BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION = 614,
+  ATOM_BLUETOOTH_L2CAP_COC_SERVER_CONNECTION = 615,
+  ATOM_BLUETOOTH_LE_SESSION_CONNECTED = 656,
+  ATOM_RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED = 666,
+  ATOM_BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED = 696,
+  ATOM_HEALTH_CONNECT_UI_IMPRESSION = 623,
+  ATOM_HEALTH_CONNECT_UI_INTERACTION = 624,
+  ATOM_HEALTH_CONNECT_APP_OPENED_REPORTED = 625,
+  ATOM_HEALTH_CONNECT_API_CALLED = 616,
+  ATOM_HEALTH_CONNECT_USAGE_STATS = 617,
+  ATOM_HEALTH_CONNECT_STORAGE_STATS = 618,
+  ATOM_HEALTH_CONNECT_API_INVOKED = 643,
+  ATOM_EXERCISE_ROUTE_API_CALLED = 654,
+  ATOM_ATOM_9999 = 9999,
+  ATOM_ATOM_99999 = 99999,
+  ATOM_THREADNETWORK_TELEMETRY_DATA_REPORTED = 738,
+  ATOM_THREADNETWORK_TOPO_ENTRY_REPEATED = 739,
+  ATOM_THREADNETWORK_DEVICE_INFO_REPORTED = 740,
+  ATOM_EMERGENCY_NUMBER_DIALED = 637,
+  ATOM_SANDBOX_API_CALLED = 488,
+  ATOM_SANDBOX_ACTIVITY_EVENT_OCCURRED = 735,
+  ATOM_SANDBOX_SDK_STORAGE = 10159,
+  ATOM_CRONET_ENGINE_CREATED = 703,
+  ATOM_CRONET_TRAFFIC_REPORTED = 704,
+  ATOM_CRONET_ENGINE_BUILDER_INITIALIZED = 762,
+  ATOM_CRONET_HTTP_FLAGS_INITIALIZED = 763,
+  ATOM_CRONET_INITIALIZED = 764,
+  ATOM_DAILY_KEEPALIVE_INFO_REPORTED = 650,
+  ATOM_IP_CLIENT_RA_INFO_REPORTED = 778,
+  ATOM_APF_SESSION_INFO_REPORTED = 777,
+  ATOM_CREDENTIAL_MANAGER_API_CALLED = 585,
+  ATOM_CREDENTIAL_MANAGER_INIT_PHASE_REPORTED = 651,
+  ATOM_CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED = 652,
+  ATOM_CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED = 653,
+  ATOM_CREDENTIAL_MANAGER_TOTAL_REPORTED = 667,
+  ATOM_CREDENTIAL_MANAGER_FINALNOUID_REPORTED = 668,
+  ATOM_CREDENTIAL_MANAGER_GET_REPORTED = 669,
+  ATOM_CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED = 670,
+  ATOM_CREDENTIAL_MANAGER_APIV2_CALLED = 671,
+  ATOM_UWB_ACTIVITY_INFO = 10188,
+  ATOM_MEDIA_ACTION_REPORTED = 608,
+  ATOM_MEDIA_CONTROLS_LAUNCHED = 609,
+  ATOM_MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED = 600,
+  ATOM_MEDIA_CODEC_STARTED = 641,
+  ATOM_MEDIA_CODEC_STOPPED = 642,
+  ATOM_MEDIA_CODEC_RENDERED = 684,
+};
+
+constexpr AtomId AtomId_MIN = AtomId::ATOM_UNSPECIFIED;
+constexpr AtomId AtomId_MAX = AtomId::ATOM_ATOM_99999;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AtomId_Name(::perfetto::protos::pbzero::AtomId value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UNSPECIFIED:
+    return "ATOM_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLE_SCAN_STATE_CHANGED:
+    return "ATOM_BLE_SCAN_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_STATE_CHANGED:
+    return "ATOM_PROCESS_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLE_SCAN_RESULT_RECEIVED:
+    return "ATOM_BLE_SCAN_RESULT_RECEIVED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SENSOR_STATE_CHANGED:
+    return "ATOM_SENSOR_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GPS_SCAN_STATE_CHANGED:
+    return "ATOM_GPS_SCAN_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYNC_STATE_CHANGED:
+    return "ATOM_SYNC_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCHEDULED_JOB_STATE_CHANGED:
+    return "ATOM_SCHEDULED_JOB_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCREEN_BRIGHTNESS_CHANGED:
+    return "ATOM_SCREEN_BRIGHTNESS_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WAKELOCK_STATE_CHANGED:
+    return "ATOM_WAKELOCK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LONG_PARTIAL_WAKELOCK_STATE_CHANGED:
+    return "ATOM_LONG_PARTIAL_WAKELOCK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_RADIO_POWER_STATE_CHANGED:
+    return "ATOM_MOBILE_RADIO_POWER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_RADIO_POWER_STATE_CHANGED:
+    return "ATOM_WIFI_RADIO_POWER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACTIVITY_MANAGER_SLEEP_STATE_CHANGED:
+    return "ATOM_ACTIVITY_MANAGER_SLEEP_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEMORY_FACTOR_STATE_CHANGED:
+    return "ATOM_MEMORY_FACTOR_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXCESSIVE_CPU_USAGE_REPORTED:
+    return "ATOM_EXCESSIVE_CPU_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CACHED_KILL_REPORTED:
+    return "ATOM_CACHED_KILL_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_MEMORY_STAT_REPORTED:
+    return "ATOM_PROCESS_MEMORY_STAT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LAUNCHER_EVENT:
+    return "ATOM_LAUNCHER_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_SAVER_MODE_STATE_CHANGED:
+    return "ATOM_BATTERY_SAVER_MODE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_IDLE_MODE_STATE_CHANGED:
+    return "ATOM_DEVICE_IDLE_MODE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_IDLING_MODE_STATE_CHANGED:
+    return "ATOM_DEVICE_IDLING_MODE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUDIO_STATE_CHANGED:
+    return "ATOM_AUDIO_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_STATE_CHANGED:
+    return "ATOM_MEDIA_CODEC_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAMERA_STATE_CHANGED:
+    return "ATOM_CAMERA_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FLASHLIGHT_STATE_CHANGED:
+    return "ATOM_FLASHLIGHT_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UID_PROCESS_STATE_CHANGED:
+    return "ATOM_UID_PROCESS_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_LIFE_CYCLE_STATE_CHANGED:
+    return "ATOM_PROCESS_LIFE_CYCLE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCREEN_STATE_CHANGED:
+    return "ATOM_SCREEN_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_LEVEL_CHANGED:
+    return "ATOM_BATTERY_LEVEL_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CHARGING_STATE_CHANGED:
+    return "ATOM_CHARGING_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PLUGGED_STATE_CHANGED:
+    return "ATOM_PLUGGED_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INTERACTIVE_STATE_CHANGED:
+    return "ATOM_INTERACTIVE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TOUCH_EVENT_REPORTED:
+    return "ATOM_TOUCH_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WAKEUP_ALARM_OCCURRED:
+    return "ATOM_WAKEUP_ALARM_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KERNEL_WAKEUP_REPORTED:
+    return "ATOM_KERNEL_WAKEUP_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_LOCK_STATE_CHANGED:
+    return "ATOM_WIFI_LOCK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_SIGNAL_STRENGTH_CHANGED:
+    return "ATOM_WIFI_SIGNAL_STRENGTH_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_SCAN_STATE_CHANGED:
+    return "ATOM_WIFI_SCAN_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PHONE_SIGNAL_STRENGTH_CHANGED:
+    return "ATOM_PHONE_SIGNAL_STRENGTH_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SETTING_CHANGED:
+    return "ATOM_SETTING_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACTIVITY_FOREGROUND_STATE_CHANGED:
+    return "ATOM_ACTIVITY_FOREGROUND_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ISOLATED_UID_CHANGED:
+    return "ATOM_ISOLATED_UID_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKET_WAKEUP_OCCURRED:
+    return "ATOM_PACKET_WAKEUP_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WALL_CLOCK_TIME_SHIFTED:
+    return "ATOM_WALL_CLOCK_TIME_SHIFTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ANOMALY_DETECTED:
+    return "ATOM_ANOMALY_DETECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_BREADCRUMB_REPORTED:
+    return "ATOM_APP_BREADCRUMB_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_START_OCCURRED:
+    return "ATOM_APP_START_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_START_CANCELED:
+    return "ATOM_APP_START_CANCELED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_START_FULLY_DRAWN:
+    return "ATOM_APP_START_FULLY_DRAWN";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LMK_KILL_OCCURRED:
+    return "ATOM_LMK_KILL_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PICTURE_IN_PICTURE_STATE_CHANGED:
+    return "ATOM_PICTURE_IN_PICTURE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_MULTICAST_LOCK_STATE_CHANGED:
+    return "ATOM_WIFI_MULTICAST_LOCK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LMK_STATE_CHANGED:
+    return "ATOM_LMK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_START_MEMORY_STATE_CAPTURED:
+    return "ATOM_APP_START_MEMORY_STATE_CAPTURED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SHUTDOWN_SEQUENCE_REPORTED:
+    return "ATOM_SHUTDOWN_SEQUENCE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_SEQUENCE_REPORTED:
+    return "ATOM_BOOT_SEQUENCE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DAVEY_OCCURRED:
+    return "ATOM_DAVEY_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_OVERLAY_STATE_CHANGED:
+    return "ATOM_OVERLAY_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FOREGROUND_SERVICE_STATE_CHANGED:
+    return "ATOM_FOREGROUND_SERVICE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CALL_STATE_CHANGED:
+    return "ATOM_CALL_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYGUARD_STATE_CHANGED:
+    return "ATOM_KEYGUARD_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYGUARD_BOUNCER_STATE_CHANGED:
+    return "ATOM_KEYGUARD_BOUNCER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYGUARD_BOUNCER_PASSWORD_ENTERED:
+    return "ATOM_KEYGUARD_BOUNCER_PASSWORD_ENTERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_DIED:
+    return "ATOM_APP_DIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RESOURCE_CONFIGURATION_CHANGED:
+    return "ATOM_RESOURCE_CONFIGURATION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_ENABLED_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_ENABLED_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_CONNECTION_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GPS_SIGNAL_QUALITY_CHANGED:
+    return "ATOM_GPS_SIGNAL_QUALITY_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USB_CONNECTOR_STATE_CHANGED:
+    return "ATOM_USB_CONNECTOR_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SPEAKER_IMPEDANCE_REPORTED:
+    return "ATOM_SPEAKER_IMPEDANCE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HARDWARE_FAILED:
+    return "ATOM_HARDWARE_FAILED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PHYSICAL_DROP_DETECTED:
+    return "ATOM_PHYSICAL_DROP_DETECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CHARGE_CYCLES_REPORTED:
+    return "ATOM_CHARGE_CYCLES_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_CONNECTION_STATE_CHANGED:
+    return "ATOM_MOBILE_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_RADIO_TECHNOLOGY_CHANGED:
+    return "ATOM_MOBILE_RADIO_TECHNOLOGY_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USB_DEVICE_ATTACHED:
+    return "ATOM_USB_DEVICE_ATTACHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_CRASH_OCCURRED:
+    return "ATOM_APP_CRASH_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ANR_OCCURRED:
+    return "ATOM_ANR_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WTF_OCCURRED:
+    return "ATOM_WTF_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOW_MEM_REPORTED:
+    return "ATOM_LOW_MEM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GENERIC_ATOM:
+    return "ATOM_GENERIC_ATOM";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VIBRATOR_STATE_CHANGED:
+    return "ATOM_VIBRATOR_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEFERRED_JOB_STATS_REPORTED:
+    return "ATOM_DEFERRED_JOB_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_THERMAL_THROTTLING:
+    return "ATOM_THERMAL_THROTTLING";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_ACQUIRED:
+    return "ATOM_BIOMETRIC_ACQUIRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_AUTHENTICATED:
+    return "ATOM_BIOMETRIC_AUTHENTICATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_ERROR_OCCURRED:
+    return "ATOM_BIOMETRIC_ERROR_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UI_EVENT_REPORTED:
+    return "ATOM_UI_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_HEALTH_SNAPSHOT:
+    return "ATOM_BATTERY_HEALTH_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SLOW_IO:
+    return "ATOM_SLOW_IO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_CAUSED_SHUTDOWN:
+    return "ATOM_BATTERY_CAUSED_SHUTDOWN";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PHONE_SERVICE_STATE_CHANGED:
+    return "ATOM_PHONE_SERVICE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PHONE_STATE_CHANGED:
+    return "ATOM_PHONE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_RESTRICTION_CHANGED:
+    return "ATOM_USER_RESTRICTION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SETTINGS_UI_CHANGED:
+    return "ATOM_SETTINGS_UI_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONNECTIVITY_STATE_CHANGED:
+    return "ATOM_CONNECTIVITY_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SERVICE_STATE_CHANGED:
+    return "ATOM_SERVICE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SERVICE_LAUNCH_REPORTED:
+    return "ATOM_SERVICE_LAUNCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FLAG_FLIP_UPDATE_OCCURRED:
+    return "ATOM_FLAG_FLIP_UPDATE_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BINARY_PUSH_STATE_CHANGED:
+    return "ATOM_BINARY_PUSH_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_POLICY_EVENT:
+    return "ATOM_DEVICE_POLICY_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_FILE_OP_CANCELED:
+    return "ATOM_DOCS_UI_FILE_OP_CANCELED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED:
+    return "ATOM_DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_FILE_OP_FAILURE:
+    return "ATOM_DOCS_UI_FILE_OP_FAILURE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_PROVIDER_FILE_OP:
+    return "ATOM_DOCS_UI_PROVIDER_FILE_OP";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST:
+    return "ATOM_DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_LAUNCH_REPORTED:
+    return "ATOM_DOCS_UI_LAUNCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_ROOT_VISITED:
+    return "ATOM_DOCS_UI_ROOT_VISITED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_STARTUP_MS:
+    return "ATOM_DOCS_UI_STARTUP_MS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_USER_ACTION_REPORTED:
+    return "ATOM_DOCS_UI_USER_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_ENABLED_STATE_CHANGED:
+    return "ATOM_WIFI_ENABLED_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_RUNNING_STATE_CHANGED:
+    return "ATOM_WIFI_RUNNING_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_COMPACTED:
+    return "ATOM_APP_COMPACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_DNS_EVENT_REPORTED:
+    return "ATOM_NETWORK_DNS_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED:
+    return "ATOM_DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_PICK_RESULT_REPORTED:
+    return "ATOM_DOCS_UI_PICK_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_SEARCH_MODE_REPORTED:
+    return "ATOM_DOCS_UI_SEARCH_MODE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_SEARCH_TYPE_REPORTED:
+    return "ATOM_DOCS_UI_SEARCH_TYPE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DATA_STALL_EVENT:
+    return "ATOM_DATA_STALL_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RESCUE_PARTY_RESET_REPORTED:
+    return "ATOM_RESCUE_PARTY_RESET_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIGNED_CONFIG_REPORTED:
+    return "ATOM_SIGNED_CONFIG_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_NI_EVENT_REPORTED:
+    return "ATOM_GNSS_NI_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_LINK_LAYER_CONNECTION_EVENT:
+    return "ATOM_BLUETOOTH_LINK_LAYER_CONNECTION_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_ACL_CONNECTION_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_ACL_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_SCO_CONNECTION_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_SCO_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_DOWNGRADED:
+    return "ATOM_APP_DOWNGRADED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_OPTIMIZED_AFTER_DOWNGRADED:
+    return "ATOM_APP_OPTIMIZED_AFTER_DOWNGRADED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOW_STORAGE_STATE_CHANGED:
+    return "ATOM_LOW_STORAGE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_NFW_NOTIFICATION_REPORTED:
+    return "ATOM_GNSS_NFW_NOTIFICATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_CONFIGURATION_REPORTED:
+    return "ATOM_GNSS_CONFIGURATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USB_PORT_OVERHEAT_EVENT_REPORTED:
+    return "ATOM_USB_PORT_OVERHEAT_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_ERROR_OCCURRED:
+    return "ATOM_NFC_ERROR_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_STATE_CHANGED:
+    return "ATOM_NFC_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_BEAM_OCCURRED:
+    return "ATOM_NFC_BEAM_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_CARDEMULATION_OCCURRED:
+    return "ATOM_NFC_CARDEMULATION_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_TAG_OCCURRED:
+    return "ATOM_NFC_TAG_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_HCE_TRANSACTION_OCCURRED:
+    return "ATOM_NFC_HCE_TRANSACTION_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SE_STATE_CHANGED:
+    return "ATOM_SE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SE_OMAPI_REPORTED:
+    return "ATOM_SE_OMAPI_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BROADCAST_DISPATCH_LATENCY_REPORTED:
+    return "ATOM_BROADCAST_DISPATCH_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ATTENTION_MANAGER_SERVICE_RESULT_REPORTED:
+    return "ATOM_ATTENTION_MANAGER_SERVICE_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ADB_CONNECTION_CHANGED:
+    return "ATOM_ADB_CONNECTION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SPEECH_DSP_STAT_REPORTED:
+    return "ATOM_SPEECH_DSP_STAT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USB_CONTAMINANT_REPORTED:
+    return "ATOM_USB_CONTAMINANT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WATCHDOG_ROLLBACK_OCCURRED:
+    return "ATOM_WATCHDOG_ROLLBACK_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED:
+    return "ATOM_BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BUBBLE_UI_CHANGED:
+    return "ATOM_BUBBLE_UI_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCHEDULED_JOB_CONSTRAINT_CHANGED:
+    return "ATOM_SCHEDULED_JOB_CONSTRAINT_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_ACTIVE_DEVICE_CHANGED:
+    return "ATOM_BLUETOOTH_ACTIVE_DEVICE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED:
+    return "ATOM_BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED:
+    return "ATOM_BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED:
+    return "ATOM_BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED:
+    return "ATOM_BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DEVICE_RSSI_REPORTED:
+    return "ATOM_BLUETOOTH_DEVICE_RSSI_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED:
+    return "ATOM_BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED:
+    return "ATOM_BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_HCI_TIMEOUT_REPORTED:
+    return "ATOM_BLUETOOTH_HCI_TIMEOUT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_QUALITY_REPORT_REPORTED:
+    return "ATOM_BLUETOOTH_QUALITY_REPORT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DEVICE_INFO_REPORTED:
+    return "ATOM_BLUETOOTH_DEVICE_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_REMOTE_VERSION_INFO_REPORTED:
+    return "ATOM_BLUETOOTH_REMOTE_VERSION_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_SDP_ATTRIBUTE_REPORTED:
+    return "ATOM_BLUETOOTH_SDP_ATTRIBUTE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_BOND_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_BOND_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED:
+    return "ATOM_BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_SMP_PAIRING_EVENT_REPORTED:
+    return "ATOM_BLUETOOTH_SMP_PAIRING_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCREEN_TIMEOUT_EXTENSION_REPORTED:
+    return "ATOM_SCREEN_TIMEOUT_EXTENSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_START_TIME:
+    return "ATOM_PROCESS_START_TIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_GRANT_REQUEST_RESULT_REPORTED:
+    return "ATOM_PERMISSION_GRANT_REQUEST_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED:
+    return "ATOM_BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_IDENTIFIER_ACCESS_DENIED:
+    return "ATOM_DEVICE_IDENTIFIER_ACCESS_DENIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BUBBLE_DEVELOPER_ERROR_REPORTED:
+    return "ATOM_BUBBLE_DEVELOPER_ERROR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ASSIST_GESTURE_STAGE_REPORTED:
+    return "ATOM_ASSIST_GESTURE_STAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ASSIST_GESTURE_FEEDBACK_REPORTED:
+    return "ATOM_ASSIST_GESTURE_FEEDBACK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ASSIST_GESTURE_PROGRESS_REPORTED:
+    return "ATOM_ASSIST_GESTURE_PROGRESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TOUCH_GESTURE_CLASSIFIED:
+    return "ATOM_TOUCH_GESTURE_CLASSIFIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HIDDEN_API_USED:
+    return "ATOM_HIDDEN_API_USED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_STYLE_UI_CHANGED:
+    return "ATOM_STYLE_UI_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_INDICATORS_INTERACTED:
+    return "ATOM_PRIVACY_INDICATORS_INTERACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED:
+    return "ATOM_APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_STACK_REPORTED:
+    return "ATOM_NETWORK_STACK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_MOVED_STORAGE_REPORTED:
+    return "ATOM_APP_MOVED_STORAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_ENROLLED:
+    return "ATOM_BIOMETRIC_ENROLLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_SERVER_WATCHDOG_OCCURRED:
+    return "ATOM_SYSTEM_SERVER_WATCHDOG_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TOMB_STONE_OCCURRED:
+    return "ATOM_TOMB_STONE_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_CLASS_OF_DEVICE_REPORTED:
+    return "ATOM_BLUETOOTH_CLASS_OF_DEVICE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INTELLIGENCE_EVENT_REPORTED:
+    return "ATOM_INTELLIGENCE_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_THERMAL_THROTTLING_SEVERITY_STATE_CHANGED:
+    return "ATOM_THERMAL_THROTTLING_SEVERITY_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ROLE_REQUEST_RESULT_REPORTED:
+    return "ATOM_ROLE_REQUEST_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOPOLICY_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOPOLICY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIORECORD_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIORECORD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOTHREAD_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOTHREAD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOTRACK_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOTRACK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_CODEC_REPORTED:
+    return "ATOM_MEDIAMETRICS_CODEC_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_DRM_WIDEVINE_REPORTED:
+    return "ATOM_MEDIAMETRICS_DRM_WIDEVINE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_EXTRACTOR_REPORTED:
+    return "ATOM_MEDIAMETRICS_EXTRACTOR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_MEDIADRM_REPORTED:
+    return "ATOM_MEDIAMETRICS_MEDIADRM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_NUPLAYER_REPORTED:
+    return "ATOM_MEDIAMETRICS_NUPLAYER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_RECORDER_REPORTED:
+    return "ATOM_MEDIAMETRICS_RECORDER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_DRMMANAGER_REPORTED:
+    return "ATOM_MEDIAMETRICS_DRMMANAGER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_POWER_STATE_CHANGED:
+    return "ATOM_CAR_POWER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GARAGE_MODE_INFO:
+    return "ATOM_GARAGE_MODE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEST_ATOM_REPORTED:
+    return "ATOM_TEST_ATOM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTENT_CAPTURE_CALLER_MISMATCH_REPORTED:
+    return "ATOM_CONTENT_CAPTURE_CALLER_MISMATCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTENT_CAPTURE_SERVICE_EVENTS:
+    return "ATOM_CONTENT_CAPTURE_SERVICE_EVENTS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTENT_CAPTURE_SESSION_EVENTS:
+    return "ATOM_CONTENT_CAPTURE_SESSION_EVENTS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTENT_CAPTURE_FLUSHED:
+    return "ATOM_CONTENT_CAPTURE_FLUSHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCATION_MANAGER_API_USAGE_REPORTED:
+    return "ATOM_LOCATION_MANAGER_API_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REVIEW_PERMISSIONS_FRAGMENT_RESULT_REPORTED:
+    return "ATOM_REVIEW_PERMISSIONS_FRAGMENT_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUNTIME_PERMISSIONS_UPGRADE_RESULT:
+    return "ATOM_RUNTIME_PERMISSIONS_UPGRADE_RESULT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GRANT_PERMISSIONS_ACTIVITY_BUTTON_ACTIONS:
+    return "ATOM_GRANT_PERMISSIONS_ACTIVITY_BUTTON_ACTIONS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCATION_ACCESS_CHECK_NOTIFICATION_ACTION:
+    return "ATOM_LOCATION_ACCESS_CHECK_NOTIFICATION_ACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_PERMISSION_FRAGMENT_ACTION_REPORTED:
+    return "ATOM_APP_PERMISSION_FRAGMENT_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_PERMISSION_FRAGMENT_VIEWED:
+    return "ATOM_APP_PERMISSION_FRAGMENT_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_PERMISSIONS_FRAGMENT_VIEWED:
+    return "ATOM_APP_PERMISSIONS_FRAGMENT_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_APPS_FRAGMENT_VIEWED:
+    return "ATOM_PERMISSION_APPS_FRAGMENT_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_SELECTION_EVENT:
+    return "ATOM_TEXT_SELECTION_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_LINKIFY_EVENT:
+    return "ATOM_TEXT_LINKIFY_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONVERSATION_ACTIONS_EVENT:
+    return "ATOM_CONVERSATION_ACTIONS_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LANGUAGE_DETECTION_EVENT:
+    return "ATOM_LANGUAGE_DETECTION_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXCLUSION_RECT_STATE_CHANGED:
+    return "ATOM_EXCLUSION_RECT_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BACK_GESTURE_REPORTED_REPORTED:
+    return "ATOM_BACK_GESTURE_REPORTED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED:
+    return "ATOM_UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED:
+    return "ATOM_UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAMERA_ACTION_EVENT:
+    return "ATOM_CAMERA_ACTION_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_COMPATIBILITY_CHANGE_REPORTED:
+    return "ATOM_APP_COMPATIBILITY_CHANGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERFETTO_UPLOADED:
+    return "ATOM_PERFETTO_UPLOADED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VMS_CLIENT_CONNECTION_STATE_CHANGED:
+    return "ATOM_VMS_CLIENT_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PROVIDER_SCAN_OCCURRED:
+    return "ATOM_MEDIA_PROVIDER_SCAN_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CONTENT_DELETED:
+    return "ATOM_MEDIA_CONTENT_DELETED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PROVIDER_PERMISSION_REQUESTED:
+    return "ATOM_MEDIA_PROVIDER_PERMISSION_REQUESTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PROVIDER_SCHEMA_CHANGED:
+    return "ATOM_MEDIA_PROVIDER_SCHEMA_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PROVIDER_IDLE_MAINTENANCE_FINISHED:
+    return "ATOM_MEDIA_PROVIDER_IDLE_MAINTENANCE_FINISHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REBOOT_ESCROW_RECOVERY_REPORTED:
+    return "ATOM_REBOOT_ESCROW_RECOVERY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_TIME_EVENT_DURATION_REPORTED:
+    return "ATOM_BOOT_TIME_EVENT_DURATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED:
+    return "ATOM_BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_TIME_EVENT_UTC_TIME_REPORTED:
+    return "ATOM_BOOT_TIME_EVENT_UTC_TIME_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_TIME_EVENT_ERROR_CODE_REPORTED:
+    return "ATOM_BOOT_TIME_EVENT_ERROR_CODE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USERSPACE_REBOOT_REPORTED:
+    return "ATOM_USERSPACE_REBOOT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NOTIFICATION_REPORTED:
+    return "ATOM_NOTIFICATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NOTIFICATION_PANEL_REPORTED:
+    return "ATOM_NOTIFICATION_PANEL_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NOTIFICATION_CHANNEL_MODIFIED:
+    return "ATOM_NOTIFICATION_CHANNEL_MODIFIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INTEGRITY_CHECK_RESULT_REPORTED:
+    return "ATOM_INTEGRITY_CHECK_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INTEGRITY_RULES_PUSHED:
+    return "ATOM_INTEGRITY_RULES_PUSHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_MESSAGE_REPORTED:
+    return "ATOM_CB_MESSAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_MESSAGE_ERROR:
+    return "ATOM_CB_MESSAGE_ERROR";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_HEALTH_STAT_REPORTED:
+    return "ATOM_WIFI_HEALTH_STAT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_FAILURE_STAT_REPORTED:
+    return "ATOM_WIFI_FAILURE_STAT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_CONNECTION_RESULT_REPORTED:
+    return "ATOM_WIFI_CONNECTION_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_FREEZE_CHANGED:
+    return "ATOM_APP_FREEZE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SNAPSHOT_MERGE_REPORTED:
+    return "ATOM_SNAPSHOT_MERGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FOREGROUND_SERVICE_APP_OP_SESSION_ENDED:
+    return "ATOM_FOREGROUND_SERVICE_APP_OP_SESSION_ENDED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISPLAY_JANK_REPORTED:
+    return "ATOM_DISPLAY_JANK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_STANDBY_BUCKET_CHANGED:
+    return "ATOM_APP_STANDBY_BUCKET_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SHARESHEET_STARTED:
+    return "ATOM_SHARESHEET_STARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RANKING_SELECTED:
+    return "ATOM_RANKING_SELECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TVSETTINGS_UI_INTERACTED:
+    return "ATOM_TVSETTINGS_UI_INTERACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LAUNCHER_SNAPSHOT:
+    return "ATOM_LAUNCHER_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_INSTALLER_V2_REPORTED:
+    return "ATOM_PACKAGE_INSTALLER_V2_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_LIFECYCLE_JOURNEY_REPORTED:
+    return "ATOM_USER_LIFECYCLE_JOURNEY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_LIFECYCLE_EVENT_OCCURRED:
+    return "ATOM_USER_LIFECYCLE_EVENT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_SHORTCUT_REPORTED:
+    return "ATOM_ACCESSIBILITY_SHORTCUT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_SERVICE_REPORTED:
+    return "ATOM_ACCESSIBILITY_SERVICE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCS_UI_DRAG_AND_DROP_REPORTED:
+    return "ATOM_DOCS_UI_DRAG_AND_DROP_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_USAGE_EVENT_OCCURRED:
+    return "ATOM_APP_USAGE_EVENT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTO_REVOKE_NOTIFICATION_CLICKED:
+    return "ATOM_AUTO_REVOKE_NOTIFICATION_CLICKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTO_REVOKE_FRAGMENT_APP_VIEWED:
+    return "ATOM_AUTO_REVOKE_FRAGMENT_APP_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTO_REVOKED_APP_INTERACTION:
+    return "ATOM_AUTO_REVOKED_APP_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION:
+    return "ATOM_APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EVS_USAGE_STATS_REPORTED:
+    return "ATOM_EVS_USAGE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUDIO_POWER_USAGE_DATA_REPORTED:
+    return "ATOM_AUDIO_POWER_USAGE_DATA_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TV_TUNER_STATE_CHANGED:
+    return "ATOM_TV_TUNER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAOUTPUT_OP_SWITCH_REPORTED:
+    return "ATOM_MEDIAOUTPUT_OP_SWITCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_MESSAGE_FILTERED:
+    return "ATOM_CB_MESSAGE_FILTERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TV_TUNER_DVR_STATUS:
+    return "ATOM_TV_TUNER_DVR_STATUS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TV_CAS_SESSION_OPEN_STATUS:
+    return "ATOM_TV_CAS_SESSION_OPEN_STATUS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ASSISTANT_INVOCATION_REPORTED:
+    return "ATOM_ASSISTANT_INVOCATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISPLAY_WAKE_REPORTED:
+    return "ATOM_DISPLAY_WAKE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_MODIFY_USER_REQUEST_REPORTED:
+    return "ATOM_CAR_USER_HAL_MODIFY_USER_REQUEST_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_MODIFY_USER_RESPONSE_REPORTED:
+    return "ATOM_CAR_USER_HAL_MODIFY_USER_RESPONSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_POST_SWITCH_RESPONSE_REPORTED:
+    return "ATOM_CAR_USER_HAL_POST_SWITCH_RESPONSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_INITIAL_USER_INFO_REQUEST_REPORTED:
+    return "ATOM_CAR_USER_HAL_INITIAL_USER_INFO_REQUEST_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_INITIAL_USER_INFO_RESPONSE_REPORTED:
+    return "ATOM_CAR_USER_HAL_INITIAL_USER_INFO_RESPONSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_USER_ASSOCIATION_REQUEST_REPORTED:
+    return "ATOM_CAR_USER_HAL_USER_ASSOCIATION_REQUEST_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_USER_HAL_SET_USER_ASSOCIATION_RESPONSE_REPORTED:
+    return "ATOM_CAR_USER_HAL_SET_USER_ASSOCIATION_RESPONSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_IP_PROVISIONING_REPORTED:
+    return "ATOM_NETWORK_IP_PROVISIONING_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_DHCP_RENEW_REPORTED:
+    return "ATOM_NETWORK_DHCP_RENEW_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_VALIDATION_REPORTED:
+    return "ATOM_NETWORK_VALIDATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_STACK_QUIRK_REPORTED:
+    return "ATOM_NETWORK_STACK_QUIRK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIODEVICECONNECTION_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIODEVICECONNECTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLOB_COMMITTED:
+    return "ATOM_BLOB_COMMITTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLOB_LEASED:
+    return "ATOM_BLOB_LEASED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLOB_OPENED:
+    return "ATOM_BLOB_OPENED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTACTS_PROVIDER_STATUS_REPORTED:
+    return "ATOM_CONTACTS_PROVIDER_STATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE_KEY_EVENT_REPORTED:
+    return "ATOM_KEYSTORE_KEY_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_TETHERING_REPORTED:
+    return "ATOM_NETWORK_TETHERING_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IME_TOUCH_REPORTED:
+    return "ATOM_IME_TOUCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UI_INTERACTION_FRAME_INFO_REPORTED:
+    return "ATOM_UI_INTERACTION_FRAME_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UI_ACTION_LATENCY_REPORTED:
+    return "ATOM_UI_ACTION_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_DISCONNECT_REPORTED:
+    return "ATOM_WIFI_DISCONNECT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_CONNECTION_STATE_CHANGED:
+    return "ATOM_WIFI_CONNECTION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HDMI_CEC_ACTIVE_SOURCE_CHANGED:
+    return "ATOM_HDMI_CEC_ACTIVE_SOURCE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HDMI_CEC_MESSAGE_REPORTED:
+    return "ATOM_HDMI_CEC_MESSAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AIRPLANE_MODE:
+    return "ATOM_AIRPLANE_MODE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MODEM_RESTART:
+    return "ATOM_MODEM_RESTART";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CARRIER_ID_MISMATCH_REPORTED:
+    return "ATOM_CARRIER_ID_MISMATCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CARRIER_ID_TABLE_UPDATED:
+    return "ATOM_CARRIER_ID_TABLE_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DATA_STALL_RECOVERY_REPORTED:
+    return "ATOM_DATA_STALL_RECOVERY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_MEDIAPARSER_REPORTED:
+    return "ATOM_MEDIAMETRICS_MEDIAPARSER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TLS_HANDSHAKE_REPORTED:
+    return "ATOM_TLS_HANDSHAKE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_CLASSIFIER_API_USAGE_REPORTED:
+    return "ATOM_TEXT_CLASSIFIER_API_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_WATCHDOG_KILL_STATS_REPORTED:
+    return "ATOM_CAR_WATCHDOG_KILL_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_PLAYBACK_REPORTED:
+    return "ATOM_MEDIAMETRICS_PLAYBACK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_NETWORK_INFO_CHANGED:
+    return "ATOM_MEDIA_NETWORK_INFO_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PLAYBACK_STATE_CHANGED:
+    return "ATOM_MEDIA_PLAYBACK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PLAYBACK_ERROR_REPORTED:
+    return "ATOM_MEDIA_PLAYBACK_ERROR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PLAYBACK_TRACK_CHANGED:
+    return "ATOM_MEDIA_PLAYBACK_TRACK_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_SCAN_REPORTED:
+    return "ATOM_WIFI_SCAN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_PNO_SCAN_REPORTED:
+    return "ATOM_WIFI_PNO_SCAN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TIF_TUNE_CHANGED:
+    return "ATOM_TIF_TUNE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTO_ROTATE_REPORTED:
+    return "ATOM_AUTO_ROTATE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERFETTO_TRIGGER:
+    return "ATOM_PERFETTO_TRIGGER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TRANSCODING_DATA:
+    return "ATOM_TRANSCODING_DATA";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_SERVICE_ENTITLEMENT_UPDATED:
+    return "ATOM_IMS_SERVICE_ENTITLEMENT_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_ROTATED:
+    return "ATOM_DEVICE_ROTATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIM_SPECIFIC_SETTINGS_RESTORED:
+    return "ATOM_SIM_SPECIFIC_SETTINGS_RESTORED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_CLASSIFIER_DOWNLOAD_REPORTED:
+    return "ATOM_TEXT_CLASSIFIER_DOWNLOAD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PIN_STORAGE_EVENT:
+    return "ATOM_PIN_STORAGE_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FACE_DOWN_REPORTED:
+    return "ATOM_FACE_DOWN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_HAL_CRASH_REASON_REPORTED:
+    return "ATOM_BLUETOOTH_HAL_CRASH_REASON_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REBOOT_ESCROW_PREPARATION_REPORTED:
+    return "ATOM_REBOOT_ESCROW_PREPARATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REBOOT_ESCROW_LSKF_CAPTURE_REPORTED:
+    return "ATOM_REBOOT_ESCROW_LSKF_CAPTURE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REBOOT_ESCROW_REBOOT_REPORTED:
+    return "ATOM_REBOOT_ESCROW_REBOOT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BINDER_LATENCY_REPORTED:
+    return "ATOM_BINDER_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AAUDIOSTREAM_REPORTED:
+    return "ATOM_MEDIAMETRICS_AAUDIOSTREAM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_TRANSCODING_SESSION_ENDED:
+    return "ATOM_MEDIA_TRANSCODING_SESSION_ENDED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MAGNIFICATION_USAGE_REPORTED:
+    return "ATOM_MAGNIFICATION_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MAGNIFICATION_MODE_WITH_IME_ON_REPORTED:
+    return "ATOM_MAGNIFICATION_MODE_WITH_IME_ON_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_CALL_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_CALL_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_CONTROL_CHANGED:
+    return "ATOM_DEVICE_CONTROL_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_STATE_CHANGED:
+    return "ATOM_DEVICE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INPUTDEVICE_REGISTERED:
+    return "ATOM_INPUTDEVICE_REGISTERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SMARTSPACE_CARD_REPORTED:
+    return "ATOM_SMARTSPACE_CARD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTH_PROMPT_AUTHENTICATE_INVOKED:
+    return "ATOM_AUTH_PROMPT_AUTHENTICATE_INVOKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED:
+    return "ATOM_AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTH_ENROLL_ACTION_INVOKED:
+    return "ATOM_AUTH_ENROLL_ACTION_INVOKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTH_DEPRECATED_API_USED:
+    return "ATOM_AUTH_DEPRECATED_API_USED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UNATTENDED_REBOOT_OCCURRED:
+    return "ATOM_UNATTENDED_REBOOT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LONG_REBOOT_BLOCKING_REPORTED:
+    return "ATOM_LONG_REBOOT_BLOCKING_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED:
+    return "ATOM_LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FDTRACK_EVENT_OCCURRED:
+    return "ATOM_FDTRACK_EVENT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TIMEOUT_AUTO_EXTENDED_REPORTED:
+    return "ATOM_TIMEOUT_AUTO_EXTENDED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ALARM_BATCH_DELIVERED:
+    return "ATOM_ALARM_BATCH_DELIVERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ALARM_SCHEDULED:
+    return "ATOM_ALARM_SCHEDULED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_WATCHDOG_IO_OVERUSE_STATS_REPORTED:
+    return "ATOM_CAR_WATCHDOG_IO_OVERUSE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_LEVEL_HIBERNATION_STATE_CHANGED:
+    return "ATOM_USER_LEVEL_HIBERNATION_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_INITIALIZE_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_INITIALIZE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_QUERY_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_QUERY_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_PROCESS_DIED:
+    return "ATOM_APP_PROCESS_DIED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_IP_REACHABILITY_MONITOR_REPORTED:
+    return "ATOM_NETWORK_IP_REACHABILITY_MONITOR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SLOW_INPUT_EVENT_REPORTED:
+    return "ATOM_SLOW_INPUT_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ANR_OCCURRED_PROCESSING_STARTED:
+    return "ATOM_ANR_OCCURRED_PROCESSING_STARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_REMOVE_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_REMOVE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_REPORTED:
+    return "ATOM_MEDIA_CODEC_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_USAGE_FRAGMENT_INTERACTION:
+    return "ATOM_PERMISSION_USAGE_FRAGMENT_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_DETAILS_INTERACTION:
+    return "ATOM_PERMISSION_DETAILS_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_SENSOR_TOGGLE_INTERACTION:
+    return "ATOM_PRIVACY_SENSOR_TOGGLE_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_TOGGLE_DIALOG_INTERACTION:
+    return "ATOM_PRIVACY_TOGGLE_DIALOG_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_OPTIMIZE_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_OPTIMIZE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NON_A11Y_TOOL_SERVICE_WARNING_REPORT:
+    return "ATOM_NON_A11Y_TOOL_SERVICE_WARNING_REPORT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_SET_SCHEMA_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_SET_SCHEMA_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_COMPAT_STATE_CHANGED:
+    return "ATOM_APP_COMPAT_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED:
+    return "ATOM_SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SPLITSCREEN_UI_CHANGED:
+    return "ATOM_SPLITSCREEN_UI_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_DNS_HANDSHAKE_REPORTED:
+    return "ATOM_NETWORK_DNS_HANDSHAKE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_CODE_PATH_COUNTER:
+    return "ATOM_BLUETOOTH_CODE_PATH_COUNTER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY:
+    return "ATOM_BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_FLOATING_MENU_UI_CHANGED:
+    return "ATOM_ACCESSIBILITY_FLOATING_MENU_UI_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NEURALNETWORKS_COMPILATION_COMPLETED:
+    return "ATOM_NEURALNETWORKS_COMPILATION_COMPLETED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NEURALNETWORKS_EXECUTION_COMPLETED:
+    return "ATOM_NEURALNETWORKS_EXECUTION_COMPLETED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NEURALNETWORKS_COMPILATION_FAILED:
+    return "ATOM_NEURALNETWORKS_COMPILATION_FAILED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NEURALNETWORKS_EXECUTION_FAILED:
+    return "ATOM_NEURALNETWORKS_EXECUTION_FAILED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTEXT_HUB_BOOTED:
+    return "ATOM_CONTEXT_HUB_BOOTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTEXT_HUB_RESTARTED:
+    return "ATOM_CONTEXT_HUB_RESTARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED:
+    return "ATOM_CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CHRE_CODE_DOWNLOAD_TRANSACTED:
+    return "ATOM_CHRE_CODE_DOWNLOAD_TRANSACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_SESSION_INITED:
+    return "ATOM_UWB_SESSION_INITED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_SESSION_CLOSED:
+    return "ATOM_UWB_SESSION_CLOSED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_FIRST_RANGING_RECEIVED:
+    return "ATOM_UWB_FIRST_RANGING_RECEIVED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_RANGING_MEASUREMENT_RECEIVED:
+    return "ATOM_UWB_RANGING_MEASUREMENT_RECEIVED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED:
+    return "ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED:
+    return "ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CLIPBOARD_CLEARED:
+    return "ATOM_CLIPBOARD_CLEARED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VM_CREATION_REQUESTED:
+    return "ATOM_VM_CREATION_REQUESTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NEARBY_DEVICE_SCAN_STATE_CHANGED:
+    return "ATOM_NEARBY_DEVICE_SCAN_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAMERA_COMPAT_CONTROL_EVENT_REPORTED:
+    return "ATOM_CAMERA_COMPAT_CONTROL_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APPLICATION_LOCALES_CHANGED:
+    return "ATOM_APPLICATION_LOCALES_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FOLD_STATE_DURATION_REPORTED:
+    return "ATOM_FOLD_STATE_DURATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED:
+    return "ATOM_LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISPLAY_HBM_STATE_CHANGED:
+    return "ATOM_DISPLAY_HBM_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISPLAY_HBM_BRIGHTNESS_CHANGED:
+    return "ATOM_DISPLAY_HBM_BRIGHTNESS_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERSISTENT_URI_PERMISSIONS_FLUSHED:
+    return "ATOM_PERSISTENT_URI_PERMISSIONS_FLUSHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED:
+    return "ATOM_EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VBMETA_DIGEST_REPORTED:
+    return "ATOM_VBMETA_DIGEST_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APEX_INFO_GATHERED:
+    return "ATOM_APEX_INFO_GATHERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PVM_INFO_GATHERED:
+    return "ATOM_PVM_INFO_GATHERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_SETTINGS_UI_INTERACTED:
+    return "ATOM_WEAR_SETTINGS_UI_INTERACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TRACING_SERVICE_REPORT_EVENT:
+    return "ATOM_TRACING_SERVICE_REPORT_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED:
+    return "ATOM_MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LAUNCHER_LATENCY:
+    return "ATOM_LAUNCHER_LATENCY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DROPBOX_ENTRY_DROPPED:
+    return "ATOM_DROPBOX_ENTRY_DROPPED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_P2P_CONNECTION_REPORTED:
+    return "ATOM_WIFI_P2P_CONNECTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_STATE_CHANGED:
+    return "ATOM_GAME_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_DETECTOR_CREATE_REQUESTED:
+    return "ATOM_HOTWORD_DETECTOR_CREATE_REQUESTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED:
+    return "ATOM_HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_DETECTION_SERVICE_RESTARTED:
+    return "ATOM_HOTWORD_DETECTION_SERVICE_RESTARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED:
+    return "ATOM_HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_DETECTOR_EVENTS:
+    return "ATOM_HOTWORD_DETECTOR_EVENTS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_API_CALLED:
+    return "ATOM_AD_SERVICES_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MESUREMENT_REPORTS_UPLOADED:
+    return "ATOM_AD_SERVICES_MESUREMENT_REPORTS_UPLOADED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED:
+    return "ATOM_BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONTACTS_INDEXER_UPDATE_STATS_REPORTED:
+    return "ATOM_CONTACTS_INDEXER_UPDATE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_BACKGROUND_RESTRICTIONS_INFO:
+    return "ATOM_APP_BACKGROUND_RESTRICTIONS_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED:
+    return "ATOM_MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED:
+    return "ATOM_MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_REMINDER_NOTIFICATION_INTERACTED:
+    return "ATOM_PERMISSION_REMINDER_NOTIFICATION_INTERACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RECENT_PERMISSION_DECISIONS_INTERACTED:
+    return "ATOM_RECENT_PERMISSION_DECISIONS_INTERACTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_PSDS_DOWNLOAD_REPORTED:
+    return "ATOM_GNSS_PSDS_DOWNLOAD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LE_AUDIO_CONNECTION_SESSION_REPORTED:
+    return "ATOM_LE_AUDIO_CONNECTION_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LE_AUDIO_BROADCAST_SESSION_REPORTED:
+    return "ATOM_LE_AUDIO_BROADCAST_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DREAM_UI_EVENT_REPORTED:
+    return "ATOM_DREAM_UI_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TASK_MANAGER_EVENT_REPORTED:
+    return "ATOM_TASK_MANAGER_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CDM_ASSOCIATION_ACTION:
+    return "ATOM_CDM_ASSOCIATION_ACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED:
+    return "ATOM_MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED:
+    return "ATOM_MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED:
+    return "ATOM_ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_SETUP_FAILURE_CRASH_REPORTED:
+    return "ATOM_WIFI_SETUP_FAILURE_CRASH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_DEVICE_ERROR_REPORTED:
+    return "ATOM_UWB_DEVICE_ERROR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ISOLATED_COMPILATION_SCHEDULED:
+    return "ATOM_ISOLATED_COMPILATION_SCHEDULED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ISOLATED_COMPILATION_ENDED:
+    return "ATOM_ISOLATED_COMPILATION_ENDED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE:
+    return "ATOM_ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED:
+    return "ATOM_SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TELEPHONY_ANOMALY_DETECTED:
+    return "ATOM_TELEPHONY_ANOMALY_DETECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LETTERBOX_POSITION_CHANGED:
+    return "ATOM_LETTERBOX_POSITION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REMOTE_KEY_PROVISIONING_ATTEMPT:
+    return "ATOM_REMOTE_KEY_PROVISIONING_ATTEMPT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REMOTE_KEY_PROVISIONING_NETWORK_INFO:
+    return "ATOM_REMOTE_KEY_PROVISIONING_NETWORK_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REMOTE_KEY_PROVISIONING_TIMING:
+    return "ATOM_REMOTE_KEY_PROVISIONING_TIMING";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAOUTPUT_OP_INTERACTION_REPORT:
+    return "ATOM_MEDIAOUTPUT_OP_INTERACTION_REPORT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYNC_EXEMPTION_OCCURRED:
+    return "ATOM_SYNC_EXEMPTION_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED:
+    return "ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DOCK_STATE_CHANGED:
+    return "ATOM_DOCK_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SAFETY_SOURCE_STATE_COLLECTED:
+    return "ATOM_SAFETY_SOURCE_STATE_COLLECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SAFETY_CENTER_SYSTEM_EVENT_REPORTED:
+    return "ATOM_SAFETY_CENTER_SYSTEM_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SAFETY_CENTER_INTERACTION_REPORTED:
+    return "ATOM_SAFETY_CENTER_INTERACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SETTINGS_PROVIDER_SETTING_CHANGED:
+    return "ATOM_SETTINGS_PROVIDER_SETTING_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BROADCAST_DELIVERY_EVENT_REPORTED:
+    return "ATOM_BROADCAST_DELIVERY_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SERVICE_REQUEST_EVENT_REPORTED:
+    return "ATOM_SERVICE_REQUEST_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROVIDER_ACQUISITION_EVENT_REPORTED:
+    return "ATOM_PROVIDER_ACQUISITION_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DEVICE_NAME_REPORTED:
+    return "ATOM_BLUETOOTH_DEVICE_NAME_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_CONFIG_UPDATED:
+    return "ATOM_CB_CONFIG_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_MODULE_ERROR_REPORTED:
+    return "ATOM_CB_MODULE_ERROR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_SERVICE_FEATURE_CHANGED:
+    return "ATOM_CB_SERVICE_FEATURE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CB_RECEIVER_FEATURE_CHANGED:
+    return "ATOM_CB_RECEIVER_FEATURE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_JSSCRIPTENGINE_LATENCY_REPORTED:
+    return "ATOM_JSSCRIPTENGINE_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_SIGNAL_NOTIFICATION_INTERACTION:
+    return "ATOM_PRIVACY_SIGNAL_NOTIFICATION_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_SIGNAL_ISSUE_CARD_INTERACTION:
+    return "ATOM_PRIVACY_SIGNAL_ISSUE_CARD_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRIVACY_SIGNALS_JOB_FAILURE:
+    return "ATOM_PRIVACY_SIGNALS_JOB_FAILURE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VIBRATION_REPORTED:
+    return "ATOM_VIBRATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_RANGING_START:
+    return "ATOM_UWB_RANGING_START";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED:
+    return "ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_COMPACTED_V2:
+    return "ATOM_APP_COMPACTED_V2";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_SETTINGS_USAGE_REPORTED:
+    return "ATOM_AD_SERVICES_SETTINGS_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISPLAY_BRIGHTNESS_CHANGED:
+    return "ATOM_DISPLAY_BRIGHTNESS_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACTIVITY_ACTION_BLOCKED:
+    return "ATOM_ACTIVITY_ACTION_BLOCKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BACKGROUND_FETCH_PROCESS_REPORTED:
+    return "ATOM_BACKGROUND_FETCH_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UPDATE_CUSTOM_AUDIENCE_PROCESS_REPORTED:
+    return "ATOM_UPDATE_CUSTOM_AUDIENCE_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUN_AD_BIDDING_PROCESS_REPORTED:
+    return "ATOM_RUN_AD_BIDDING_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUN_AD_SCORING_PROCESS_REPORTED:
+    return "ATOM_RUN_AD_SCORING_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUN_AD_SELECTION_PROCESS_REPORTED:
+    return "ATOM_RUN_AD_SELECTION_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUN_AD_BIDDING_PER_CA_PROCESS_REPORTED:
+    return "ATOM_RUN_AD_BIDDING_PER_CA_PROCESS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED:
+    return "ATOM_MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED:
+    return "ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_DNS_SERVER_SUPPORT_REPORTED:
+    return "ATOM_NETWORK_DNS_SERVER_SUPPORT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VM_BOOTED:
+    return "ATOM_VM_BOOTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VM_EXITED:
+    return "ATOM_VM_EXITED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AMBIENT_BRIGHTNESS_STATS_REPORTED:
+    return "ATOM_AMBIENT_BRIGHTNESS_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED:
+    return "ATOM_MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED:
+    return "ATOM_MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED:
+    return "ATOM_MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED:
+    return "ATOM_MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_REGISTRATIONS:
+    return "ATOM_AD_SERVICES_MEASUREMENT_REGISTRATIONS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEARING_AID_INFO_REPORTED:
+    return "ATOM_HEARING_AID_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED:
+    return "ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AMBIENT_MODE_CHANGED:
+    return "ATOM_AMBIENT_MODE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ANR_LATENCY_REPORTED:
+    return "ATOM_ANR_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RESOURCE_API_INFO:
+    return "ATOM_RESOURCE_API_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_DEFAULT_NETWORK_CHANGED:
+    return "ATOM_SYSTEM_DEFAULT_NETWORK_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IWLAN_SETUP_DATA_CALL_RESULT_REPORTED:
+    return "ATOM_IWLAN_SETUP_DATA_CALL_RESULT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IWLAN_PDN_DISCONNECTED_REASON_REPORTED:
+    return "ATOM_IWLAN_PDN_DISCONNECTED_REASON_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AIRPLANE_MODE_SESSION_REPORTED:
+    return "ATOM_AIRPLANE_MODE_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VM_CPU_STATUS_REPORTED:
+    return "ATOM_VM_CPU_STATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VM_MEM_STATUS_REPORTED:
+    return "ATOM_VM_MEM_STATUS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_INSTALLATION_SESSION_REPORTED:
+    return "ATOM_PACKAGE_INSTALLATION_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEFAULT_NETWORK_REMATCH_INFO:
+    return "ATOM_DEFAULT_NETWORK_REMATCH_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_SELECTION_PERFORMANCE:
+    return "ATOM_NETWORK_SELECTION_PERFORMANCE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_NSD_REPORTED:
+    return "ATOM_NETWORK_NSD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_DISCONNECTION_REASON_REPORTED:
+    return "ATOM_BLUETOOTH_DISCONNECTION_REASON_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_LOCAL_VERSIONS_REPORTED:
+    return "ATOM_BLUETOOTH_LOCAL_VERSIONS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED:
+    return "ATOM_BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED:
+    return "ATOM_BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_GATT_APP_INFO:
+    return "ATOM_BLUETOOTH_GATT_APP_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BRIGHTNESS_CONFIGURATION_UPDATED:
+    return "ATOM_BRIGHTNESS_CONFIGURATION_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_GET_TOPICS_REPORTED:
+    return "ATOM_AD_SERVICES_GET_TOPICS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_EPOCH_COMPUTATION_GET_TOP_TOPICS_REPORTED:
+    return "ATOM_AD_SERVICES_EPOCH_COMPUTATION_GET_TOP_TOPICS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_EPOCH_COMPUTATION_CLASSIFIER_REPORTED:
+    return "ATOM_AD_SERVICES_EPOCH_COMPUTATION_CLASSIFIER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_LAUNCHED:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_LAUNCHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FINISHED:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FINISHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECTION_REPORTED:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_TRIGGERED:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_TRIGGERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FIRST_DEVICE_SCAN_LATENCY:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FIRST_DEVICE_SCAN_LATENCY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECT_DEVICE_LATENCY:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECT_DEVICE_LATENCY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_MANAGER_SNAPSHOT_REPORTED:
+    return "ATOM_PACKAGE_MANAGER_SNAPSHOT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED:
+    return "ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED:
+    return "ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LAUNCHER_IMPRESSION_EVENT:
+    return "ATOM_LAUNCHER_IMPRESSION_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_ALL_DEVICES_SCAN_LATENCY:
+    return "ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_ALL_DEVICES_SCAN_LATENCY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_WATCH_FACE_EDITED:
+    return "ATOM_WS_WATCH_FACE_EDITED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_WATCH_FACE_FAVORITE_ACTION_REPORTED:
+    return "ATOM_WS_WATCH_FACE_FAVORITE_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_WATCH_FACE_SET_ACTION_REPORTED:
+    return "ATOM_WS_WATCH_FACE_SET_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_UNINSTALLATION_REPORTED:
+    return "ATOM_PACKAGE_UNINSTALLATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_MODE_CHANGED:
+    return "ATOM_GAME_MODE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_MODE_CONFIGURATION_CHANGED:
+    return "ATOM_GAME_MODE_CONFIGURATION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BEDTIME_MODE_STATE_CHANGED:
+    return "ATOM_BEDTIME_MODE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_SLICE_SESSION_ENDED:
+    return "ATOM_NETWORK_SLICE_SESSION_ENDED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED:
+    return "ATOM_NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_TAG_TYPE_OCCURRED:
+    return "ATOM_NFC_TAG_TYPE_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_AID_CONFLICT_OCCURRED:
+    return "ATOM_NFC_AID_CONFLICT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NFC_READER_CONFLICT_OCCURRED:
+    return "ATOM_NFC_READER_CONFLICT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_TILE_LIST_CHANGED:
+    return "ATOM_WS_TILE_LIST_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GET_TYPE_ACCESSED_WITHOUT_PERMISSION:
+    return "ATOM_GET_TYPE_ACCESSED_WITHOUT_PERMISSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_BUNDLED_APP_INFO_GATHERED:
+    return "ATOM_MOBILE_BUNDLED_APP_INFO_GATHERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_WATCH_FACE_COMPLICATION_SET_CHANGED:
+    return "ATOM_WS_WATCH_FACE_COMPLICATION_SET_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_DRM_CREATED:
+    return "ATOM_MEDIA_DRM_CREATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_DRM_ERRORED:
+    return "ATOM_MEDIA_DRM_ERRORED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_DRM_SESSION_OPENED:
+    return "ATOM_MEDIA_DRM_SESSION_OPENED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_DRM_SESSION_CLOSED:
+    return "ATOM_MEDIA_DRM_SESSION_CLOSED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_SELECTED_RESOLUTION:
+    return "ATOM_USER_SELECTED_RESOLUTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UNSAFE_INTENT_EVENT_REPORTED:
+    return "ATOM_UNSAFE_INTENT_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERFORMANCE_HINT_SESSION_REPORTED:
+    return "ATOM_PERFORMANCE_HINT_SESSION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED:
+    return "ATOM_MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_TOUCH_REPORTED:
+    return "ATOM_BIOMETRIC_TOUCH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED:
+    return "ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_SCHEMA_MIGRATION_STATS_REPORTED:
+    return "ATOM_APP_SEARCH_SCHEMA_MIGRATION_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCATION_ENABLED_STATE_CHANGED:
+    return "ATOM_LOCATION_ENABLED_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IME_REQUEST_FINISHED:
+    return "ATOM_IME_REQUEST_FINISHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USB_COMPLIANCE_WARNINGS_REPORTED:
+    return "ATOM_USB_COMPLIANCE_WARNINGS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SUPPORTED_LOCALES_CHANGED:
+    return "ATOM_APP_SUPPORTED_LOCALES_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GRAMMATICAL_INFLECTION_CHANGED:
+    return "ATOM_GRAMMATICAL_INFLECTION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_PROVIDER_VOLUME_RECOVERY_REPORTED:
+    return "ATOM_MEDIA_PROVIDER_VOLUME_RECOVERY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BIOMETRIC_PROPERTIES_COLLECTED:
+    return "ATOM_BIOMETRIC_PROPERTIES_COLLECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KERNEL_WAKEUP_ATTRIBUTED:
+    return "ATOM_KERNEL_WAKEUP_ATTRIBUTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SCREEN_STATE_CHANGED_V2:
+    return "ATOM_SCREEN_STATE_CHANGED_V2";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_BACKUP_ACTION_REPORTED:
+    return "ATOM_WS_BACKUP_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_RESTORE_ACTION_REPORTED:
+    return "ATOM_WS_RESTORE_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_LOG_ACCESS_EVENT_REPORTED:
+    return "ATOM_DEVICE_LOG_ACCESS_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_SESSION_UPDATED:
+    return "ATOM_MEDIA_SESSION_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_OOBE_STATE_CHANGED:
+    return "ATOM_WEAR_OOBE_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_NOTIFICATION_UPDATED:
+    return "ATOM_WS_NOTIFICATION_UPDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED:
+    return "ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_COMPLICATION_TAPPED:
+    return "ATOM_WS_COMPLICATION_TAPPED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_WEAR_TIME_SESSION:
+    return "ATOM_WS_WEAR_TIME_SESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_BYTES_TRANSFER:
+    return "ATOM_WIFI_BYTES_TRANSFER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_BYTES_TRANSFER_BY_FG_BG:
+    return "ATOM_WIFI_BYTES_TRANSFER_BY_FG_BG";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_BYTES_TRANSFER:
+    return "ATOM_MOBILE_BYTES_TRANSFER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MOBILE_BYTES_TRANSFER_BY_FG_BG:
+    return "ATOM_MOBILE_BYTES_TRANSFER_BY_FG_BG";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_BYTES_TRANSFER:
+    return "ATOM_BLUETOOTH_BYTES_TRANSFER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KERNEL_WAKELOCK:
+    return "ATOM_KERNEL_WAKELOCK";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SUBSYSTEM_SLEEP_STATE:
+    return "ATOM_SUBSYSTEM_SLEEP_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_TIME_PER_UID:
+    return "ATOM_CPU_TIME_PER_UID";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_TIME_PER_UID_FREQ:
+    return "ATOM_CPU_TIME_PER_UID_FREQ";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_ACTIVITY_INFO:
+    return "ATOM_WIFI_ACTIVITY_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MODEM_ACTIVITY_INFO:
+    return "ATOM_MODEM_ACTIVITY_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_ACTIVITY_INFO:
+    return "ATOM_BLUETOOTH_ACTIVITY_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_MEMORY_STATE:
+    return "ATOM_PROCESS_MEMORY_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_ELAPSED_REALTIME:
+    return "ATOM_SYSTEM_ELAPSED_REALTIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_UPTIME:
+    return "ATOM_SYSTEM_UPTIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_ACTIVE_TIME:
+    return "ATOM_CPU_ACTIVE_TIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_CLUSTER_TIME:
+    return "ATOM_CPU_CLUSTER_TIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISK_SPACE:
+    return "ATOM_DISK_SPACE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REMAINING_BATTERY_CAPACITY:
+    return "ATOM_REMAINING_BATTERY_CAPACITY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FULL_BATTERY_CAPACITY:
+    return "ATOM_FULL_BATTERY_CAPACITY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEMPERATURE:
+    return "ATOM_TEMPERATURE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BINDER_CALLS:
+    return "ATOM_BINDER_CALLS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BINDER_CALLS_EXCEPTIONS:
+    return "ATOM_BINDER_CALLS_EXCEPTIONS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOOPER_STATS:
+    return "ATOM_LOOPER_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISK_STATS:
+    return "ATOM_DISK_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DIRECTORY_USAGE:
+    return "ATOM_DIRECTORY_USAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SIZE:
+    return "ATOM_APP_SIZE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CATEGORY_SIZE:
+    return "ATOM_CATEGORY_SIZE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROC_STATS:
+    return "ATOM_PROC_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_VOLTAGE:
+    return "ATOM_BATTERY_VOLTAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NUM_FINGERPRINTS_ENROLLED:
+    return "ATOM_NUM_FINGERPRINTS_ENROLLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DISK_IO:
+    return "ATOM_DISK_IO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_POWER_PROFILE:
+    return "ATOM_POWER_PROFILE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROC_STATS_PKG_PROC:
+    return "ATOM_PROC_STATS_PKG_PROC";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_CPU_TIME:
+    return "ATOM_PROCESS_CPU_TIME";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_TIME_PER_THREAD_FREQ:
+    return "ATOM_CPU_TIME_PER_THREAD_FREQ";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ON_DEVICE_POWER_MEASUREMENT:
+    return "ATOM_ON_DEVICE_POWER_MEASUREMENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_CALCULATED_POWER_USE:
+    return "ATOM_DEVICE_CALCULATED_POWER_USE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_MEMORY_HIGH_WATER_MARK:
+    return "ATOM_PROCESS_MEMORY_HIGH_WATER_MARK";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_LEVEL:
+    return "ATOM_BATTERY_LEVEL";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BUILD_INFORMATION:
+    return "ATOM_BUILD_INFORMATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_CYCLE_COUNT:
+    return "ATOM_BATTERY_CYCLE_COUNT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEBUG_ELAPSED_CLOCK:
+    return "ATOM_DEBUG_ELAPSED_CLOCK";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEBUG_FAILING_ELAPSED_CLOCK:
+    return "ATOM_DEBUG_FAILING_ELAPSED_CLOCK";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NUM_FACES_ENROLLED:
+    return "ATOM_NUM_FACES_ENROLLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ROLE_HOLDER:
+    return "ATOM_ROLE_HOLDER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DANGEROUS_PERMISSION_STATE:
+    return "ATOM_DANGEROUS_PERMISSION_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TRAIN_INFO:
+    return "ATOM_TRAIN_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TIME_ZONE_DATA_INFO:
+    return "ATOM_TIME_ZONE_DATA_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXTERNAL_STORAGE_INFO:
+    return "ATOM_EXTERNAL_STORAGE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GPU_STATS_GLOBAL_INFO:
+    return "ATOM_GPU_STATS_GLOBAL_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GPU_STATS_APP_INFO:
+    return "ATOM_GPU_STATS_APP_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_ION_HEAP_SIZE:
+    return "ATOM_SYSTEM_ION_HEAP_SIZE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APPS_ON_EXTERNAL_STORAGE_INFO:
+    return "ATOM_APPS_ON_EXTERNAL_STORAGE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FACE_SETTINGS:
+    return "ATOM_FACE_SETTINGS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_COOLING_DEVICE:
+    return "ATOM_COOLING_DEVICE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_OPS:
+    return "ATOM_APP_OPS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_SYSTEM_ION_HEAP_SIZE:
+    return "ATOM_PROCESS_SYSTEM_ION_HEAP_SIZE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SURFACEFLINGER_STATS_GLOBAL_INFO:
+    return "ATOM_SURFACEFLINGER_STATS_GLOBAL_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SURFACEFLINGER_STATS_LAYER_INFO:
+    return "ATOM_SURFACEFLINGER_STATS_LAYER_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_MEMORY_SNAPSHOT:
+    return "ATOM_PROCESS_MEMORY_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VMS_CLIENT_STATS:
+    return "ATOM_VMS_CLIENT_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NOTIFICATION_REMOTE_VIEWS:
+    return "ATOM_NOTIFICATION_REMOTE_VIEWS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DANGEROUS_PERMISSION_STATE_SAMPLED:
+    return "ATOM_DANGEROUS_PERMISSION_STATE_SAMPLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GRAPHICS_STATS:
+    return "ATOM_GRAPHICS_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RUNTIME_APP_OP_ACCESS:
+    return "ATOM_RUNTIME_APP_OP_ACCESS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ION_HEAP_SIZE:
+    return "ATOM_ION_HEAP_SIZE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_NOTIFICATION_PREFERENCES:
+    return "ATOM_PACKAGE_NOTIFICATION_PREFERENCES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES:
+    return "ATOM_PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES:
+    return "ATOM_PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_STATS:
+    return "ATOM_GNSS_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ATTRIBUTED_APP_OPS:
+    return "ATOM_ATTRIBUTED_APP_OPS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VOICE_CALL_SESSION:
+    return "ATOM_VOICE_CALL_SESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VOICE_CALL_RAT_USAGE:
+    return "ATOM_VOICE_CALL_RAT_USAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIM_SLOT_STATE:
+    return "ATOM_SIM_SLOT_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SUPPORTED_RADIO_ACCESS_FAMILY:
+    return "ATOM_SUPPORTED_RADIO_ACCESS_FAMILY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SETTING_SNAPSHOT:
+    return "ATOM_SETTING_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLOB_INFO:
+    return "ATOM_BLOB_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DATA_USAGE_BYTES_TRANSFER:
+    return "ATOM_DATA_USAGE_BYTES_TRANSFER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BYTES_TRANSFER_BY_TAG_AND_METERED:
+    return "ATOM_BYTES_TRANSFER_BY_TAG_AND_METERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DND_MODE_RULE:
+    return "ATOM_DND_MODE_RULE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GENERAL_EXTERNAL_STORAGE_ACCESS_STATS:
+    return "ATOM_GENERAL_EXTERNAL_STORAGE_ACCESS_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INCOMING_SMS:
+    return "ATOM_INCOMING_SMS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_OUTGOING_SMS:
+    return "ATOM_OUTGOING_SMS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CARRIER_ID_TABLE_VERSION:
+    return "ATOM_CARRIER_ID_TABLE_VERSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DATA_CALL_SESSION:
+    return "ATOM_DATA_CALL_SESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CELLULAR_SERVICE_STATE:
+    return "ATOM_CELLULAR_SERVICE_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CELLULAR_DATA_SERVICE_SWITCH:
+    return "ATOM_CELLULAR_DATA_SERVICE_SWITCH";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SYSTEM_MEMORY:
+    return "ATOM_SYSTEM_MEMORY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_REGISTRATION_TERMINATION:
+    return "ATOM_IMS_REGISTRATION_TERMINATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_REGISTRATION_STATS:
+    return "ATOM_IMS_REGISTRATION_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_TIME_PER_CLUSTER_FREQ:
+    return "ATOM_CPU_TIME_PER_CLUSTER_FREQ";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_CYCLES_PER_UID_CLUSTER:
+    return "ATOM_CPU_CYCLES_PER_UID_CLUSTER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_ROTATED_DATA:
+    return "ATOM_DEVICE_ROTATED_DATA";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CPU_CYCLES_PER_THREAD_GROUP_CLUSTER:
+    return "ATOM_CPU_CYCLES_PER_THREAD_GROUP_CLUSTER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_DRM_ACTIVITY_INFO:
+    return "ATOM_MEDIA_DRM_ACTIVITY_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_OEM_MANAGED_BYTES_TRANSFER:
+    return "ATOM_OEM_MANAGED_BYTES_TRANSFER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GNSS_POWER_STATS:
+    return "ATOM_GNSS_POWER_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TIME_ZONE_DETECTOR_STATE:
+    return "ATOM_TIME_ZONE_DETECTOR_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_STORAGE_STATS:
+    return "ATOM_KEYSTORE2_STORAGE_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RKP_POOL_STATS:
+    return "ATOM_RKP_POOL_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_DMABUF_MEMORY:
+    return "ATOM_PROCESS_DMABUF_MEMORY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PENDING_ALARM_INFO:
+    return "ATOM_PENDING_ALARM_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_LEVEL_HIBERNATED_APPS:
+    return "ATOM_USER_LEVEL_HIBERNATED_APPS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LAUNCHER_LAYOUT_SNAPSHOT:
+    return "ATOM_LAUNCHER_LAYOUT_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GLOBAL_HIBERNATED_APPS:
+    return "ATOM_GLOBAL_HIBERNATED_APPS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INPUT_EVENT_LATENCY_SKETCH:
+    return "ATOM_INPUT_EVENT_LATENCY_SKETCH";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_USAGE_STATS_BEFORE_RESET:
+    return "ATOM_BATTERY_USAGE_STATS_BEFORE_RESET";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_USAGE_STATS_SINCE_RESET:
+    return "ATOM_BATTERY_USAGE_STATS_SINCE_RESET";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL:
+    return "ATOM_BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INSTALLED_INCREMENTAL_PACKAGE:
+    return "ATOM_INSTALLED_INCREMENTAL_PACKAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TELEPHONY_NETWORK_REQUESTS:
+    return "ATOM_TELEPHONY_NETWORK_REQUESTS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_SEARCH_STORAGE_INFO:
+    return "ATOM_APP_SEARCH_STORAGE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VMSTAT:
+    return "ATOM_VMSTAT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO:
+    return "ATOM_KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO:
+    return "ATOM_KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO:
+    return "ATOM_KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_ATOM_WITH_OVERFLOW:
+    return "ATOM_KEYSTORE2_ATOM_WITH_OVERFLOW";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO:
+    return "ATOM_KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO:
+    return "ATOM_KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RKP_ERROR_STATS:
+    return "ATOM_RKP_ERROR_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_KEYSTORE2_CRASH_STATS:
+    return "ATOM_KEYSTORE2_CRASH_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_VENDOR_APEX_INFO:
+    return "ATOM_VENDOR_APEX_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_SHORTCUT_STATS:
+    return "ATOM_ACCESSIBILITY_SHORTCUT_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ACCESSIBILITY_FLOATING_MENU_STATS:
+    return "ATOM_ACCESSIBILITY_FLOATING_MENU_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DATA_USAGE_BYTES_TRANSFER_V2:
+    return "ATOM_DATA_USAGE_BYTES_TRANSFER_V2";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CAPABILITIES:
+    return "ATOM_MEDIA_CAPABILITIES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY:
+    return "ATOM_CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CAR_WATCHDOG_UID_IO_USAGE_SUMMARY:
+    return "ATOM_CAR_WATCHDOG_UID_IO_USAGE_SUMMARY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_REGISTRATION_FEATURE_TAG_STATS:
+    return "ATOM_IMS_REGISTRATION_FEATURE_TAG_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RCS_CLIENT_PROVISIONING_STATS:
+    return "ATOM_RCS_CLIENT_PROVISIONING_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RCS_ACS_PROVISIONING_STATS:
+    return "ATOM_RCS_ACS_PROVISIONING_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIP_DELEGATE_STATS:
+    return "ATOM_SIP_DELEGATE_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIP_TRANSPORT_FEATURE_TAG_STATS:
+    return "ATOM_SIP_TRANSPORT_FEATURE_TAG_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIP_MESSAGE_RESPONSE:
+    return "ATOM_SIP_MESSAGE_RESPONSE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIP_TRANSPORT_SESSION:
+    return "ATOM_SIP_TRANSPORT_SESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_DEDICATED_BEARER_LISTENER_EVENT:
+    return "ATOM_IMS_DEDICATED_BEARER_LISTENER_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_DEDICATED_BEARER_EVENT:
+    return "ATOM_IMS_DEDICATED_BEARER_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IMS_REGISTRATION_SERVICE_DESC_STATS:
+    return "ATOM_IMS_REGISTRATION_SERVICE_DESC_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UCE_EVENT_STATS:
+    return "ATOM_UCE_EVENT_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PRESENCE_NOTIFY_EVENT:
+    return "ATOM_PRESENCE_NOTIFY_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GBA_EVENT:
+    return "ATOM_GBA_EVENT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PER_SIM_STATUS:
+    return "ATOM_PER_SIM_STATUS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GPU_WORK_PER_UID:
+    return "ATOM_GPU_WORK_PER_UID";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE:
+    return "ATOM_PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SIGNED_PARTITION_INFO:
+    return "ATOM_SIGNED_PARTITION_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PINNED_FILE_SIZES_PER_PACKAGE:
+    return "ATOM_PINNED_FILE_SIZES_PER_PACKAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PENDING_INTENTS_PER_PACKAGE:
+    return "ATOM_PENDING_INTENTS_PER_PACKAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_USER_INFO:
+    return "ATOM_USER_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TELEPHONY_NETWORK_REQUESTS_V2:
+    return "ATOM_TELEPHONY_NETWORK_REQUESTS_V2";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DEVICE_TELEPHONY_PROPERTIES:
+    return "ATOM_DEVICE_TELEPHONY_PROPERTIES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_REMOTE_KEY_PROVISIONING_ERROR_COUNTS:
+    return "ATOM_REMOTE_KEY_PROVISIONING_ERROR_COUNTS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SAFETY_STATE:
+    return "ATOM_SAFETY_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_INCOMING_MMS:
+    return "ATOM_INCOMING_MMS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_OUTGOING_MMS:
+    return "ATOM_OUTGOING_MMS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MULTI_USER_INFO:
+    return "ATOM_MULTI_USER_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_BPF_MAP_INFO:
+    return "ATOM_NETWORK_BPF_MAP_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_OUTGOING_SHORT_CODE_SMS:
+    return "ATOM_OUTGOING_SHORT_CODE_SMS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CONNECTIVITY_STATE_SAMPLE:
+    return "ATOM_CONNECTIVITY_STATE_SAMPLE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO:
+    return "ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_MODE_INFO:
+    return "ATOM_GAME_MODE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_MODE_CONFIGURATION:
+    return "ATOM_GAME_MODE_CONFIGURATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_GAME_MODE_LISTENER:
+    return "ATOM_GAME_MODE_LISTENER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NETWORK_SLICE_REQUEST_COUNT:
+    return "ATOM_NETWORK_SLICE_REQUEST_COUNT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_TILE_SNAPSHOT:
+    return "ATOM_WS_TILE_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_ACTIVE_WATCH_FACE_COMPLICATION_SET_SNAPSHOT:
+    return "ATOM_WS_ACTIVE_WATCH_FACE_COMPLICATION_SET_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_STATE:
+    return "ATOM_PROCESS_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PROCESS_ASSOCIATION:
+    return "ATOM_PROCESS_ASSOCIATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ADPF_SYSTEM_COMPONENT_INFO:
+    return "ATOM_ADPF_SYSTEM_COMPONENT_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_NOTIFICATION_MEMORY_USE:
+    return "ATOM_NOTIFICATION_MEMORY_USE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HDR_CAPABILITIES:
+    return "ATOM_HDR_CAPABILITIES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_FAVOURITE_WATCH_FACE_LIST_SNAPSHOT:
+    return "ATOM_WS_FAVOURITE_WATCH_FACE_LIST_SNAPSHOT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_AWARE_NDP_REPORTED:
+    return "ATOM_WIFI_AWARE_NDP_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_AWARE_ATTACH_REPORTED:
+    return "ATOM_WIFI_AWARE_ATTACH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_SELF_RECOVERY_TRIGGERED:
+    return "ATOM_WIFI_SELF_RECOVERY_TRIGGERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SOFT_AP_STARTED:
+    return "ATOM_SOFT_AP_STARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SOFT_AP_STOPPED:
+    return "ATOM_SOFT_AP_STOPPED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_LOCK_RELEASED:
+    return "ATOM_WIFI_LOCK_RELEASED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_LOCK_DEACTIVATED:
+    return "ATOM_WIFI_LOCK_DEACTIVATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_CONFIG_SAVED:
+    return "ATOM_WIFI_CONFIG_SAVED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_AWARE_RESOURCE_USING_CHANGED:
+    return "ATOM_WIFI_AWARE_RESOURCE_USING_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_AWARE_HAL_API_CALLED:
+    return "ATOM_WIFI_AWARE_HAL_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_LOCAL_ONLY_REQUEST_RECEIVED:
+    return "ATOM_WIFI_LOCAL_ONLY_REQUEST_RECEIVED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_LOCAL_ONLY_REQUEST_SCAN_TRIGGERED:
+    return "ATOM_WIFI_LOCAL_ONLY_REQUEST_SCAN_TRIGGERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_THREAD_TASK_EXECUTED:
+    return "ATOM_WIFI_THREAD_TASK_EXECUTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_STATE_CHANGED:
+    return "ATOM_WIFI_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_AWARE_CAPABILITIES:
+    return "ATOM_WIFI_AWARE_CAPABILITIES";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WIFI_MODULE_INFO:
+    return "ATOM_WIFI_MODULE_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SETTINGS_SPA_REPORTED:
+    return "ATOM_SETTINGS_SPA_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXPRESS_EVENT_REPORTED:
+    return "ATOM_EXPRESS_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXPRESS_HISTOGRAM_SAMPLE_REPORTED:
+    return "ATOM_EXPRESS_HISTOGRAM_SAMPLE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXPRESS_UID_EVENT_REPORTED:
+    return "ATOM_EXPRESS_UID_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED:
+    return "ATOM_EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_RATIONALE_DIALOG_VIEWED:
+    return "ATOM_PERMISSION_RATIONALE_DIALOG_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PERMISSION_RATIONALE_DIALOG_ACTION_REPORTED:
+    return "ATOM_PERMISSION_RATIONALE_DIALOG_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_DATA_SHARING_UPDATES_NOTIFICATION_INTERACTION:
+    return "ATOM_APP_DATA_SHARING_UPDATES_NOTIFICATION_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_VIEWED:
+    return "ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_VIEWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_ACTION_REPORTED:
+    return "ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_INCOMING_CALL_ACTION_REPORTED:
+    return "ATOM_WS_INCOMING_CALL_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_CALL_DISCONNECTION_REPORTED:
+    return "ATOM_WS_CALL_DISCONNECTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_CALL_DURATION_REPORTED:
+    return "ATOM_WS_CALL_DURATION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_CALL_USER_EXPERIENCE_LATENCY_REPORTED:
+    return "ATOM_WS_CALL_USER_EXPERIENCE_LATENCY_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WS_CALL_INTERACTION_REPORTED:
+    return "ATOM_WS_CALL_INTERACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_FULL_SCREEN_INTENT_LAUNCHED:
+    return "ATOM_FULL_SCREEN_INTENT_LAUNCHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BAL_ALLOWED:
+    return "ATOM_BAL_ALLOWED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IN_TASK_ACTIVITY_STARTED:
+    return "ATOM_IN_TASK_ACTIVITY_STARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CACHED_APPS_HIGH_WATERMARK:
+    return "ATOM_CACHED_APPS_HIGH_WATERMARK";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ODREFRESH_REPORTED:
+    return "ATOM_ODREFRESH_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ODSIGN_REPORTED:
+    return "ATOM_ODSIGN_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ART_DATUM_REPORTED:
+    return "ATOM_ART_DATUM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ART_DEVICE_DATUM_REPORTED:
+    return "ATOM_ART_DEVICE_DATUM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ART_DATUM_DELTA_REPORTED:
+    return "ATOM_ART_DATUM_DELTA_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BACKGROUND_DEXOPT_JOB_ENDED:
+    return "ATOM_BACKGROUND_DEXOPT_JOB_ENDED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_ADAPTIVE_SUSPEND_STATS_REPORTED:
+    return "ATOM_WEAR_ADAPTIVE_SUSPEND_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_POWER_ANOMALY_SERVICE_OPERATIONAL_STATS_REPORTED:
+    return "ATOM_WEAR_POWER_ANOMALY_SERVICE_OPERATIONAL_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_WEAR_POWER_ANOMALY_SERVICE_EVENT_STATS_REPORTED:
+    return "ATOM_WEAR_POWER_ANOMALY_SERVICE_EVENT_STATS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EMERGENCY_STATE_CHANGED:
+    return "ATOM_EMERGENCY_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DND_STATE_CHANGED:
+    return "ATOM_DND_STATE_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MTE_STATE:
+    return "ATOM_MTE_STATE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_BACK_COMPAT_GET_TOPICS_REPORTED:
+    return "ATOM_AD_SERVICES_BACK_COMPAT_GET_TOPICS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_BACK_COMPAT_EPOCH_COMPUTATION_CLASSIFIER_REPORTED:
+    return "ATOM_AD_SERVICES_BACK_COMPAT_EPOCH_COMPUTATION_CLASSIFIER_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_DEBUG_KEYS:
+    return "ATOM_AD_SERVICES_MEASUREMENT_DEBUG_KEYS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_ERROR_REPORTED:
+    return "ATOM_AD_SERVICES_ERROR_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_BACKGROUND_JOBS_EXECUTION_REPORTED:
+    return "ATOM_AD_SERVICES_BACKGROUND_JOBS_EXECUTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_DELAYED_SOURCE_REGISTRATION:
+    return "ATOM_AD_SERVICES_MEASUREMENT_DELAYED_SOURCE_REGISTRATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_ATTRIBUTION:
+    return "ATOM_AD_SERVICES_MEASUREMENT_ATTRIBUTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_JOBS:
+    return "ATOM_AD_SERVICES_MEASUREMENT_JOBS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_MEASUREMENT_WIPEOUT:
+    return "ATOM_AD_SERVICES_MEASUREMENT_WIPEOUT";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AD_SERVICES_CONSENT_MIGRATED:
+    return "ATOM_AD_SERVICES_CONSENT_MIGRATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RKPD_POOL_STATS:
+    return "ATOM_RKPD_POOL_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RKPD_CLIENT_OPERATION:
+    return "ATOM_RKPD_CLIENT_OPERATION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_UI_EVENT_REPORTED:
+    return "ATOM_AUTOFILL_UI_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_FILL_REQUEST_REPORTED:
+    return "ATOM_AUTOFILL_FILL_REQUEST_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_FILL_RESPONSE_REPORTED:
+    return "ATOM_AUTOFILL_FILL_RESPONSE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_SAVE_EVENT_REPORTED:
+    return "ATOM_AUTOFILL_SAVE_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_SESSION_COMMITTED:
+    return "ATOM_AUTOFILL_SESSION_COMMITTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED:
+    return "ATOM_AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEST_EXTENSION_ATOM_REPORTED:
+    return "ATOM_TEST_EXTENSION_ATOM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TEST_RESTRICTED_ATOM_REPORTED:
+    return "ATOM_TEST_RESTRICTED_ATOM_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_STATS_SOCKET_LOSS_REPORTED:
+    return "ATOM_STATS_SOCKET_LOSS_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_PLUGIN_INITIALIZED:
+    return "ATOM_PLUGIN_INITIALIZED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_TV_LOW_POWER_STANDBY_POLICY:
+    return "ATOM_TV_LOW_POWER_STANDBY_POLICY";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCKSCREEN_SHORTCUT_SELECTED:
+    return "ATOM_LOCKSCREEN_SHORTCUT_SELECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_LOCKSCREEN_SHORTCUT_TRIGGERED:
+    return "ATOM_LOCKSCREEN_SHORTCUT_TRIGGERED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EMERGENCY_NUMBERS_INFO:
+    return "ATOM_EMERGENCY_NUMBERS_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QUALIFIED_RAT_LIST_CHANGED:
+    return "ATOM_QUALIFIED_RAT_LIST_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QNS_IMS_CALL_DROP_STATS:
+    return "ATOM_QNS_IMS_CALL_DROP_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QNS_FALLBACK_RESTRICTION_CHANGED:
+    return "ATOM_QNS_FALLBACK_RESTRICTION_CHANGED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QNS_RAT_PREFERENCE_MISMATCH_INFO:
+    return "ATOM_QNS_RAT_PREFERENCE_MISMATCH_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QNS_HANDOVER_TIME_MILLIS:
+    return "ATOM_QNS_HANDOVER_TIME_MILLIS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_QNS_HANDOVER_PINGPONG:
+    return "ATOM_QNS_HANDOVER_PINGPONG";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_CONTROLLER:
+    return "ATOM_SATELLITE_CONTROLLER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_SESSION:
+    return "ATOM_SATELLITE_SESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_INCOMING_DATAGRAM:
+    return "ATOM_SATELLITE_INCOMING_DATAGRAM";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_OUTGOING_DATAGRAM:
+    return "ATOM_SATELLITE_OUTGOING_DATAGRAM";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_PROVISION:
+    return "ATOM_SATELLITE_PROVISION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SATELLITE_SOS_MESSAGE_RECOMMENDER:
+    return "ATOM_SATELLITE_SOS_MESSAGE_RECOMMENDER";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IKE_SESSION_TERMINATED:
+    return "ATOM_IKE_SESSION_TERMINATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IKE_LIVENESS_CHECK_SESSION_VALIDATED:
+    return "ATOM_IKE_LIVENESS_CHECK_SESSION_VALIDATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_HASHED_DEVICE_NAME_REPORTED:
+    return "ATOM_BLUETOOTH_HASHED_DEVICE_NAME_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION:
+    return "ATOM_BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_L2CAP_COC_SERVER_CONNECTION:
+    return "ATOM_BLUETOOTH_L2CAP_COC_SERVER_CONNECTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_LE_SESSION_CONNECTED:
+    return "ATOM_BLUETOOTH_LE_SESSION_CONNECTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED:
+    return "ATOM_RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED:
+    return "ATOM_BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_UI_IMPRESSION:
+    return "ATOM_HEALTH_CONNECT_UI_IMPRESSION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_UI_INTERACTION:
+    return "ATOM_HEALTH_CONNECT_UI_INTERACTION";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_APP_OPENED_REPORTED:
+    return "ATOM_HEALTH_CONNECT_APP_OPENED_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_API_CALLED:
+    return "ATOM_HEALTH_CONNECT_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_USAGE_STATS:
+    return "ATOM_HEALTH_CONNECT_USAGE_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_STORAGE_STATS:
+    return "ATOM_HEALTH_CONNECT_STORAGE_STATS";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_HEALTH_CONNECT_API_INVOKED:
+    return "ATOM_HEALTH_CONNECT_API_INVOKED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EXERCISE_ROUTE_API_CALLED:
+    return "ATOM_EXERCISE_ROUTE_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ATOM_9999:
+    return "ATOM_ATOM_9999";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_ATOM_99999:
+    return "ATOM_ATOM_99999";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_THREADNETWORK_TELEMETRY_DATA_REPORTED:
+    return "ATOM_THREADNETWORK_TELEMETRY_DATA_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_THREADNETWORK_TOPO_ENTRY_REPEATED:
+    return "ATOM_THREADNETWORK_TOPO_ENTRY_REPEATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_THREADNETWORK_DEVICE_INFO_REPORTED:
+    return "ATOM_THREADNETWORK_DEVICE_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_EMERGENCY_NUMBER_DIALED:
+    return "ATOM_EMERGENCY_NUMBER_DIALED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SANDBOX_API_CALLED:
+    return "ATOM_SANDBOX_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SANDBOX_ACTIVITY_EVENT_OCCURRED:
+    return "ATOM_SANDBOX_ACTIVITY_EVENT_OCCURRED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_SANDBOX_SDK_STORAGE:
+    return "ATOM_SANDBOX_SDK_STORAGE";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CRONET_ENGINE_CREATED:
+    return "ATOM_CRONET_ENGINE_CREATED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CRONET_TRAFFIC_REPORTED:
+    return "ATOM_CRONET_TRAFFIC_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CRONET_ENGINE_BUILDER_INITIALIZED:
+    return "ATOM_CRONET_ENGINE_BUILDER_INITIALIZED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CRONET_HTTP_FLAGS_INITIALIZED:
+    return "ATOM_CRONET_HTTP_FLAGS_INITIALIZED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CRONET_INITIALIZED:
+    return "ATOM_CRONET_INITIALIZED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_DAILY_KEEPALIVE_INFO_REPORTED:
+    return "ATOM_DAILY_KEEPALIVE_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_IP_CLIENT_RA_INFO_REPORTED:
+    return "ATOM_IP_CLIENT_RA_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_APF_SESSION_INFO_REPORTED:
+    return "ATOM_APF_SESSION_INFO_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_API_CALLED:
+    return "ATOM_CREDENTIAL_MANAGER_API_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_INIT_PHASE_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_INIT_PHASE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_TOTAL_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_TOTAL_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_FINALNOUID_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_FINALNOUID_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_GET_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_GET_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED:
+    return "ATOM_CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_CREDENTIAL_MANAGER_APIV2_CALLED:
+    return "ATOM_CREDENTIAL_MANAGER_APIV2_CALLED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_UWB_ACTIVITY_INFO:
+    return "ATOM_UWB_ACTIVITY_INFO";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_ACTION_REPORTED:
+    return "ATOM_MEDIA_ACTION_REPORTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CONTROLS_LAUNCHED:
+    return "ATOM_MEDIA_CONTROLS_LAUNCHED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED:
+    return "ATOM_MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_STARTED:
+    return "ATOM_MEDIA_CODEC_STARTED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_STOPPED:
+    return "ATOM_MEDIA_CODEC_STOPPED";
+
+  case ::perfetto::protos::pbzero::AtomId::ATOM_MEDIA_CODEC_RENDERED:
+    return "ATOM_MEDIA_CODEC_RENDERED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/statsd/statsd_tracing_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_STATSD_TRACING_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STATSD_STATSD_TRACING_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class StatsdPullAtomConfig;
+enum AtomId : int32_t;
+
+class StatsdPullAtomConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StatsdPullAtomConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StatsdPullAtomConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StatsdPullAtomConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pull_atom_id() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> pull_atom_id() const { return GetRepeated<int32_t>(1); }
+  bool has_raw_pull_atom_id() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> raw_pull_atom_id() const { return GetRepeated<int32_t>(2); }
+  bool has_pull_frequency_ms() const { return at<3>().valid(); }
+  int32_t pull_frequency_ms() const { return at<3>().as_int32(); }
+  bool has_packages() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> packages() const { return GetRepeated<::protozero::ConstChars>(4); }
+};
+
+class StatsdPullAtomConfig : public ::protozero::Message {
+ public:
+  using Decoder = StatsdPullAtomConfig_Decoder;
+  enum : int32_t {
+    kPullAtomIdFieldNumber = 1,
+    kRawPullAtomIdFieldNumber = 2,
+    kPullFrequencyMsFieldNumber = 3,
+    kPackagesFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StatsdPullAtomConfig"; }
+
+
+  using FieldMetadata_PullAtomId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::AtomId,
+      StatsdPullAtomConfig>;
+
+  static constexpr FieldMetadata_PullAtomId kPullAtomId{};
+  void add_pull_atom_id(::perfetto::protos::pbzero::AtomId value) {
+    static constexpr uint32_t field_id = FieldMetadata_PullAtomId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RawPullAtomId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      StatsdPullAtomConfig>;
+
+  static constexpr FieldMetadata_RawPullAtomId kRawPullAtomId{};
+  void add_raw_pull_atom_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RawPullAtomId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PullFrequencyMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      StatsdPullAtomConfig>;
+
+  static constexpr FieldMetadata_PullFrequencyMs kPullFrequencyMs{};
+  void set_pull_frequency_ms(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PullFrequencyMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Packages =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      StatsdPullAtomConfig>;
+
+  static constexpr FieldMetadata_Packages kPackages{};
+  void add_packages(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Packages::kFieldId, data, size);
+  }
+  void add_packages(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Packages::kFieldId, chars.data, chars.size);
+  }
+  void add_packages(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Packages::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class StatsdTracingConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StatsdTracingConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StatsdTracingConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StatsdTracingConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_push_atom_id() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> push_atom_id() const { return GetRepeated<int32_t>(1); }
+  bool has_raw_push_atom_id() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> raw_push_atom_id() const { return GetRepeated<int32_t>(2); }
+  bool has_pull_config() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> pull_config() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class StatsdTracingConfig : public ::protozero::Message {
+ public:
+  using Decoder = StatsdTracingConfig_Decoder;
+  enum : int32_t {
+    kPushAtomIdFieldNumber = 1,
+    kRawPushAtomIdFieldNumber = 2,
+    kPullConfigFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StatsdTracingConfig"; }
+
+
+  using FieldMetadata_PushAtomId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::AtomId,
+      StatsdTracingConfig>;
+
+  static constexpr FieldMetadata_PushAtomId kPushAtomId{};
+  void add_push_atom_id(::perfetto::protos::pbzero::AtomId value) {
+    static constexpr uint32_t field_id = FieldMetadata_PushAtomId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RawPushAtomId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      StatsdTracingConfig>;
+
+  static constexpr FieldMetadata_RawPushAtomId kRawPushAtomId{};
+  void add_raw_push_atom_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RawPushAtomId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PullConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StatsdPullAtomConfig,
+      StatsdTracingConfig>;
+
+  static constexpr FieldMetadata_PullConfig kPullConfig{};
+  template <typename T = StatsdPullAtomConfig> T* add_pull_config() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum MeminfoCounters : int32_t;
+namespace perfetto_pbzero_enum_SysStatsConfig {
+enum StatCounters : int32_t;
+}  // namespace perfetto_pbzero_enum_SysStatsConfig
+using SysStatsConfig_StatCounters = perfetto_pbzero_enum_SysStatsConfig::StatCounters;
+enum VmstatCounters : int32_t;
+
+namespace perfetto_pbzero_enum_SysStatsConfig {
+enum StatCounters : int32_t {
+  STAT_UNSPECIFIED = 0,
+  STAT_CPU_TIMES = 1,
+  STAT_IRQ_COUNTS = 2,
+  STAT_SOFTIRQ_COUNTS = 3,
+  STAT_FORK_COUNT = 4,
+};
+} // namespace perfetto_pbzero_enum_SysStatsConfig
+using SysStatsConfig_StatCounters = perfetto_pbzero_enum_SysStatsConfig::StatCounters;
+
+
+constexpr SysStatsConfig_StatCounters SysStatsConfig_StatCounters_MIN = SysStatsConfig_StatCounters::STAT_UNSPECIFIED;
+constexpr SysStatsConfig_StatCounters SysStatsConfig_StatCounters_MAX = SysStatsConfig_StatCounters::STAT_FORK_COUNT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* SysStatsConfig_StatCounters_Name(::perfetto::protos::pbzero::SysStatsConfig_StatCounters value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::SysStatsConfig_StatCounters::STAT_UNSPECIFIED:
+    return "STAT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::SysStatsConfig_StatCounters::STAT_CPU_TIMES:
+    return "STAT_CPU_TIMES";
+
+  case ::perfetto::protos::pbzero::SysStatsConfig_StatCounters::STAT_IRQ_COUNTS:
+    return "STAT_IRQ_COUNTS";
+
+  case ::perfetto::protos::pbzero::SysStatsConfig_StatCounters::STAT_SOFTIRQ_COUNTS:
+    return "STAT_SOFTIRQ_COUNTS";
+
+  case ::perfetto::protos::pbzero::SysStatsConfig_StatCounters::STAT_FORK_COUNT:
+    return "STAT_FORK_COUNT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class SysStatsConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SysStatsConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStatsConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStatsConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_meminfo_period_ms() const { return at<1>().valid(); }
+  uint32_t meminfo_period_ms() const { return at<1>().as_uint32(); }
+  bool has_meminfo_counters() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> meminfo_counters() const { return GetRepeated<int32_t>(2); }
+  bool has_vmstat_period_ms() const { return at<3>().valid(); }
+  uint32_t vmstat_period_ms() const { return at<3>().as_uint32(); }
+  bool has_vmstat_counters() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> vmstat_counters() const { return GetRepeated<int32_t>(4); }
+  bool has_stat_period_ms() const { return at<5>().valid(); }
+  uint32_t stat_period_ms() const { return at<5>().as_uint32(); }
+  bool has_stat_counters() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> stat_counters() const { return GetRepeated<int32_t>(6); }
+  bool has_devfreq_period_ms() const { return at<7>().valid(); }
+  uint32_t devfreq_period_ms() const { return at<7>().as_uint32(); }
+  bool has_cpufreq_period_ms() const { return at<8>().valid(); }
+  uint32_t cpufreq_period_ms() const { return at<8>().as_uint32(); }
+  bool has_buddyinfo_period_ms() const { return at<9>().valid(); }
+  uint32_t buddyinfo_period_ms() const { return at<9>().as_uint32(); }
+  bool has_diskstat_period_ms() const { return at<10>().valid(); }
+  uint32_t diskstat_period_ms() const { return at<10>().as_uint32(); }
+  bool has_psi_period_ms() const { return at<11>().valid(); }
+  uint32_t psi_period_ms() const { return at<11>().as_uint32(); }
+};
+
+class SysStatsConfig : public ::protozero::Message {
+ public:
+  using Decoder = SysStatsConfig_Decoder;
+  enum : int32_t {
+    kMeminfoPeriodMsFieldNumber = 1,
+    kMeminfoCountersFieldNumber = 2,
+    kVmstatPeriodMsFieldNumber = 3,
+    kVmstatCountersFieldNumber = 4,
+    kStatPeriodMsFieldNumber = 5,
+    kStatCountersFieldNumber = 6,
+    kDevfreqPeriodMsFieldNumber = 7,
+    kCpufreqPeriodMsFieldNumber = 8,
+    kBuddyinfoPeriodMsFieldNumber = 9,
+    kDiskstatPeriodMsFieldNumber = 10,
+    kPsiPeriodMsFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStatsConfig"; }
+
+
+  using StatCounters = ::perfetto::protos::pbzero::SysStatsConfig_StatCounters;
+  static inline const char* StatCounters_Name(StatCounters value) {
+    return ::perfetto::protos::pbzero::SysStatsConfig_StatCounters_Name(value);
+  }
+  static inline const StatCounters STAT_UNSPECIFIED = StatCounters::STAT_UNSPECIFIED;
+  static inline const StatCounters STAT_CPU_TIMES = StatCounters::STAT_CPU_TIMES;
+  static inline const StatCounters STAT_IRQ_COUNTS = StatCounters::STAT_IRQ_COUNTS;
+  static inline const StatCounters STAT_SOFTIRQ_COUNTS = StatCounters::STAT_SOFTIRQ_COUNTS;
+  static inline const StatCounters STAT_FORK_COUNT = StatCounters::STAT_FORK_COUNT;
+
+  using FieldMetadata_MeminfoPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_MeminfoPeriodMs kMeminfoPeriodMs{};
+  void set_meminfo_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MeminfoPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MeminfoCounters =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::MeminfoCounters,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_MeminfoCounters kMeminfoCounters{};
+  void add_meminfo_counters(::perfetto::protos::pbzero::MeminfoCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_MeminfoCounters::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VmstatPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_VmstatPeriodMs kVmstatPeriodMs{};
+  void set_vmstat_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmstatPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VmstatCounters =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::VmstatCounters,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_VmstatCounters kVmstatCounters{};
+  void add_vmstat_counters(::perfetto::protos::pbzero::VmstatCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmstatCounters::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StatPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_StatPeriodMs kStatPeriodMs{};
+  void set_stat_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StatPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StatCounters =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::SysStatsConfig_StatCounters,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_StatCounters kStatCounters{};
+  void add_stat_counters(::perfetto::protos::pbzero::SysStatsConfig_StatCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_StatCounters::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DevfreqPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_DevfreqPeriodMs kDevfreqPeriodMs{};
+  void set_devfreq_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevfreqPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpufreqPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_CpufreqPeriodMs kCpufreqPeriodMs{};
+  void set_cpufreq_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpufreqPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BuddyinfoPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_BuddyinfoPeriodMs kBuddyinfoPeriodMs{};
+  void set_buddyinfo_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BuddyinfoPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DiskstatPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_DiskstatPeriodMs kDiskstatPeriodMs{};
+  void set_diskstat_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DiskstatPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PsiPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStatsConfig>;
+
+  static constexpr FieldMetadata_PsiPeriodMs kPsiPeriodMs{};
+  void set_psi_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PsiPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/system_info/system_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYSTEM_INFO_SYSTEM_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYSTEM_INFO_SYSTEM_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SystemInfoConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SystemInfoConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SystemInfoConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SystemInfoConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class SystemInfoConfig : public ::protozero::Message {
+ public:
+  using Decoder = SystemInfoConfig_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.SystemInfoConfig"; }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/track_event/track_event_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACK_EVENT_TRACK_EVENT_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class TrackEventConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TrackEventConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEventConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEventConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_disabled_categories() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> disabled_categories() const { return GetRepeated<::protozero::ConstChars>(1); }
+  bool has_enabled_categories() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> enabled_categories() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_disabled_tags() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> disabled_tags() const { return GetRepeated<::protozero::ConstChars>(3); }
+  bool has_enabled_tags() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> enabled_tags() const { return GetRepeated<::protozero::ConstChars>(4); }
+  bool has_disable_incremental_timestamps() const { return at<5>().valid(); }
+  bool disable_incremental_timestamps() const { return at<5>().as_bool(); }
+  bool has_timestamp_unit_multiplier() const { return at<6>().valid(); }
+  uint64_t timestamp_unit_multiplier() const { return at<6>().as_uint64(); }
+  bool has_filter_debug_annotations() const { return at<7>().valid(); }
+  bool filter_debug_annotations() const { return at<7>().as_bool(); }
+  bool has_enable_thread_time_sampling() const { return at<8>().valid(); }
+  bool enable_thread_time_sampling() const { return at<8>().as_bool(); }
+  bool has_filter_dynamic_event_names() const { return at<9>().valid(); }
+  bool filter_dynamic_event_names() const { return at<9>().as_bool(); }
+};
+
+class TrackEventConfig : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventConfig_Decoder;
+  enum : int32_t {
+    kDisabledCategoriesFieldNumber = 1,
+    kEnabledCategoriesFieldNumber = 2,
+    kDisabledTagsFieldNumber = 3,
+    kEnabledTagsFieldNumber = 4,
+    kDisableIncrementalTimestampsFieldNumber = 5,
+    kTimestampUnitMultiplierFieldNumber = 6,
+    kFilterDebugAnnotationsFieldNumber = 7,
+    kEnableThreadTimeSamplingFieldNumber = 8,
+    kFilterDynamicEventNamesFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEventConfig"; }
+
+
+  using FieldMetadata_DisabledCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_DisabledCategories kDisabledCategories{};
+  void add_disabled_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DisabledCategories::kFieldId, data, size);
+  }
+  void add_disabled_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DisabledCategories::kFieldId, chars.data, chars.size);
+  }
+  void add_disabled_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisabledCategories::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnabledCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_EnabledCategories kEnabledCategories{};
+  void add_enabled_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EnabledCategories::kFieldId, data, size);
+  }
+  void add_enabled_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EnabledCategories::kFieldId, chars.data, chars.size);
+  }
+  void add_enabled_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnabledCategories::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisabledTags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_DisabledTags kDisabledTags{};
+  void add_disabled_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DisabledTags::kFieldId, data, size);
+  }
+  void add_disabled_tags(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DisabledTags::kFieldId, chars.data, chars.size);
+  }
+  void add_disabled_tags(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisabledTags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnabledTags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_EnabledTags kEnabledTags{};
+  void add_enabled_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EnabledTags::kFieldId, data, size);
+  }
+  void add_enabled_tags(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EnabledTags::kFieldId, chars.data, chars.size);
+  }
+  void add_enabled_tags(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnabledTags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisableIncrementalTimestamps =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_DisableIncrementalTimestamps kDisableIncrementalTimestamps{};
+  void set_disable_incremental_timestamps(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableIncrementalTimestamps::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimestampUnitMultiplier =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_TimestampUnitMultiplier kTimestampUnitMultiplier{};
+  void set_timestamp_unit_multiplier(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampUnitMultiplier::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FilterDebugAnnotations =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_FilterDebugAnnotations kFilterDebugAnnotations{};
+  void set_filter_debug_annotations(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_FilterDebugAnnotations::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnableThreadTimeSampling =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_EnableThreadTimeSampling kEnableThreadTimeSampling{};
+  void set_enable_thread_time_sampling(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnableThreadTimeSampling::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FilterDynamicEventNames =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TrackEventConfig>;
+
+  static constexpr FieldMetadata_FilterDynamicEventNames kFilterDynamicEventNames{};
+  void set_filter_dynamic_event_names(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_FilterDynamicEventNames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/chrome/chrome_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeConfig {
+enum ClientPriority : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeConfig
+using ChromeConfig_ClientPriority = perfetto_pbzero_enum_ChromeConfig::ClientPriority;
+
+namespace perfetto_pbzero_enum_ChromeConfig {
+enum ClientPriority : int32_t {
+  UNKNOWN = 0,
+  BACKGROUND = 1,
+  USER_INITIATED = 2,
+};
+} // namespace perfetto_pbzero_enum_ChromeConfig
+using ChromeConfig_ClientPriority = perfetto_pbzero_enum_ChromeConfig::ClientPriority;
+
+
+constexpr ChromeConfig_ClientPriority ChromeConfig_ClientPriority_MIN = ChromeConfig_ClientPriority::UNKNOWN;
+constexpr ChromeConfig_ClientPriority ChromeConfig_ClientPriority_MAX = ChromeConfig_ClientPriority::USER_INITIATED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeConfig_ClientPriority_Name(::perfetto::protos::pbzero::ChromeConfig_ClientPriority value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeConfig_ClientPriority::UNKNOWN:
+    return "UNKNOWN";
+
+  case ::perfetto::protos::pbzero::ChromeConfig_ClientPriority::BACKGROUND:
+    return "BACKGROUND";
+
+  case ::perfetto::protos::pbzero::ChromeConfig_ClientPriority::USER_INITIATED:
+    return "USER_INITIATED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trace_config() const { return at<1>().valid(); }
+  ::protozero::ConstChars trace_config() const { return at<1>().as_string(); }
+  bool has_privacy_filtering_enabled() const { return at<2>().valid(); }
+  bool privacy_filtering_enabled() const { return at<2>().as_bool(); }
+  bool has_convert_to_legacy_json() const { return at<3>().valid(); }
+  bool convert_to_legacy_json() const { return at<3>().as_bool(); }
+  bool has_client_priority() const { return at<4>().valid(); }
+  int32_t client_priority() const { return at<4>().as_int32(); }
+  bool has_json_agent_label_filter() const { return at<5>().valid(); }
+  ::protozero::ConstChars json_agent_label_filter() const { return at<5>().as_string(); }
+};
+
+class ChromeConfig : public ::protozero::Message {
+ public:
+  using Decoder = ChromeConfig_Decoder;
+  enum : int32_t {
+    kTraceConfigFieldNumber = 1,
+    kPrivacyFilteringEnabledFieldNumber = 2,
+    kConvertToLegacyJsonFieldNumber = 3,
+    kClientPriorityFieldNumber = 4,
+    kJsonAgentLabelFilterFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeConfig"; }
+
+
+  using ClientPriority = ::perfetto::protos::pbzero::ChromeConfig_ClientPriority;
+  static inline const char* ClientPriority_Name(ClientPriority value) {
+    return ::perfetto::protos::pbzero::ChromeConfig_ClientPriority_Name(value);
+  }
+  static inline const ClientPriority UNKNOWN = ClientPriority::UNKNOWN;
+  static inline const ClientPriority BACKGROUND = ClientPriority::BACKGROUND;
+  static inline const ClientPriority USER_INITIATED = ClientPriority::USER_INITIATED;
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeConfig>;
+
+  static constexpr FieldMetadata_TraceConfig kTraceConfig{};
+  void set_trace_config(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceConfig::kFieldId, data, size);
+  }
+  void set_trace_config(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceConfig::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_config(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceConfig::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrivacyFilteringEnabled =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeConfig>;
+
+  static constexpr FieldMetadata_PrivacyFilteringEnabled kPrivacyFilteringEnabled{};
+  void set_privacy_filtering_enabled(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrivacyFilteringEnabled::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ConvertToLegacyJson =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeConfig>;
+
+  static constexpr FieldMetadata_ConvertToLegacyJson kConvertToLegacyJson{};
+  void set_convert_to_legacy_json(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ConvertToLegacyJson::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ClientPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeConfig_ClientPriority,
+      ChromeConfig>;
+
+  static constexpr FieldMetadata_ClientPriority kClientPriority{};
+  void set_client_priority(::perfetto::protos::pbzero::ChromeConfig_ClientPriority value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientPriority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_JsonAgentLabelFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeConfig>;
+
+  static constexpr FieldMetadata_JsonAgentLabelFilter kJsonAgentLabelFilter{};
+  void set_json_agent_label_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_JsonAgentLabelFilter::kFieldId, data, size);
+  }
+  void set_json_agent_label_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_JsonAgentLabelFilter::kFieldId, chars.data, chars.size);
+  }
+  void set_json_agent_label_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_JsonAgentLabelFilter::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/chrome/scenario_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_SCENARIO_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_SCENARIO_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class NestedScenarioConfig;
+class ScenarioConfig;
+class TraceConfig;
+class TriggerRule;
+class TriggerRule_HistogramTrigger;
+class TriggerRule_RepeatingInterval;
+
+class ChromeFieldTracingConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeFieldTracingConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeFieldTracingConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeFieldTracingConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_scenarios() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> scenarios() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class ChromeFieldTracingConfig : public ::protozero::Message {
+ public:
+  using Decoder = ChromeFieldTracingConfig_Decoder;
+  enum : int32_t {
+    kScenariosFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeFieldTracingConfig"; }
+
+
+  using FieldMetadata_Scenarios =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ScenarioConfig,
+      ChromeFieldTracingConfig>;
+
+  static constexpr FieldMetadata_Scenarios kScenarios{};
+  template <typename T = ScenarioConfig> T* add_scenarios() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ScenarioConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ScenarioConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ScenarioConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ScenarioConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_scenario_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars scenario_name() const { return at<1>().as_string(); }
+  bool has_start_rules() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> start_rules() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_stop_rules() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> stop_rules() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_upload_rules() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> upload_rules() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_setup_rules() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> setup_rules() const { return GetRepeated<::protozero::ConstBytes>(5); }
+  bool has_trace_config() const { return at<6>().valid(); }
+  ::protozero::ConstBytes trace_config() const { return at<6>().as_bytes(); }
+  bool has_nested_scenarios() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> nested_scenarios() const { return GetRepeated<::protozero::ConstBytes>(7); }
+};
+
+class ScenarioConfig : public ::protozero::Message {
+ public:
+  using Decoder = ScenarioConfig_Decoder;
+  enum : int32_t {
+    kScenarioNameFieldNumber = 1,
+    kStartRulesFieldNumber = 2,
+    kStopRulesFieldNumber = 3,
+    kUploadRulesFieldNumber = 4,
+    kSetupRulesFieldNumber = 5,
+    kTraceConfigFieldNumber = 6,
+    kNestedScenariosFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ScenarioConfig"; }
+
+
+  using FieldMetadata_ScenarioName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_ScenarioName kScenarioName{};
+  void set_scenario_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ScenarioName::kFieldId, data, size);
+  }
+  void set_scenario_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ScenarioName::kFieldId, chars.data, chars.size);
+  }
+  void set_scenario_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScenarioName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartRules =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_StartRules kStartRules{};
+  template <typename T = TriggerRule> T* add_start_rules() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_StopRules =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_StopRules kStopRules{};
+  template <typename T = TriggerRule> T* add_stop_rules() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_UploadRules =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_UploadRules kUploadRules{};
+  template <typename T = TriggerRule> T* add_upload_rules() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_SetupRules =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_SetupRules kSetupRules{};
+  template <typename T = TriggerRule> T* add_setup_rules() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_TraceConfig kTraceConfig{};
+  template <typename T = TraceConfig> T* set_trace_config() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_NestedScenarios =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NestedScenarioConfig,
+      ScenarioConfig>;
+
+  static constexpr FieldMetadata_NestedScenarios kNestedScenarios{};
+  template <typename T = NestedScenarioConfig> T* add_nested_scenarios() {
+    return BeginNestedMessage<T>(7);
+  }
+
+};
+
+class NestedScenarioConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  NestedScenarioConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NestedScenarioConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NestedScenarioConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_scenario_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars scenario_name() const { return at<1>().as_string(); }
+  bool has_start_rules() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> start_rules() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_stop_rules() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> stop_rules() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_upload_rules() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> upload_rules() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class NestedScenarioConfig : public ::protozero::Message {
+ public:
+  using Decoder = NestedScenarioConfig_Decoder;
+  enum : int32_t {
+    kScenarioNameFieldNumber = 1,
+    kStartRulesFieldNumber = 2,
+    kStopRulesFieldNumber = 3,
+    kUploadRulesFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NestedScenarioConfig"; }
+
+
+  using FieldMetadata_ScenarioName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      NestedScenarioConfig>;
+
+  static constexpr FieldMetadata_ScenarioName kScenarioName{};
+  void set_scenario_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ScenarioName::kFieldId, data, size);
+  }
+  void set_scenario_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ScenarioName::kFieldId, chars.data, chars.size);
+  }
+  void set_scenario_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScenarioName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartRules =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      NestedScenarioConfig>;
+
+  static constexpr FieldMetadata_StartRules kStartRules{};
+  template <typename T = TriggerRule> T* add_start_rules() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_StopRules =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      NestedScenarioConfig>;
+
+  static constexpr FieldMetadata_StopRules kStopRules{};
+  template <typename T = TriggerRule> T* add_stop_rules() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_UploadRules =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule,
+      NestedScenarioConfig>;
+
+  static constexpr FieldMetadata_UploadRules kUploadRules{};
+  template <typename T = TriggerRule> T* add_upload_rules() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class TriggerRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TriggerRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TriggerRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TriggerRule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_trigger_chance() const { return at<2>().valid(); }
+  float trigger_chance() const { return at<2>().as_float(); }
+  bool has_delay_ms() const { return at<3>().valid(); }
+  uint64_t delay_ms() const { return at<3>().as_uint64(); }
+  bool has_activation_delay_ms() const { return at<8>().valid(); }
+  uint64_t activation_delay_ms() const { return at<8>().as_uint64(); }
+  bool has_manual_trigger_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars manual_trigger_name() const { return at<4>().as_string(); }
+  bool has_histogram() const { return at<5>().valid(); }
+  ::protozero::ConstBytes histogram() const { return at<5>().as_bytes(); }
+  bool has_repeating_interval() const { return at<6>().valid(); }
+  ::protozero::ConstBytes repeating_interval() const { return at<6>().as_bytes(); }
+};
+
+class TriggerRule : public ::protozero::Message {
+ public:
+  using Decoder = TriggerRule_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kTriggerChanceFieldNumber = 2,
+    kDelayMsFieldNumber = 3,
+    kActivationDelayMsFieldNumber = 8,
+    kManualTriggerNameFieldNumber = 4,
+    kHistogramFieldNumber = 5,
+    kRepeatingIntervalFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TriggerRule"; }
+
+  using HistogramTrigger = ::perfetto::protos::pbzero::TriggerRule_HistogramTrigger;
+  using RepeatingInterval = ::perfetto::protos::pbzero::TriggerRule_RepeatingInterval;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TriggerChance =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_TriggerChance kTriggerChance{};
+  void set_trigger_chance(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggerChance::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_DelayMs kDelayMs{};
+  void set_delay_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DelayMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ActivationDelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_ActivationDelayMs kActivationDelayMs{};
+  void set_activation_delay_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActivationDelayMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ManualTriggerName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_ManualTriggerName kManualTriggerName{};
+  void set_manual_trigger_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ManualTriggerName::kFieldId, data, size);
+  }
+  void set_manual_trigger_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ManualTriggerName::kFieldId, chars.data, chars.size);
+  }
+  void set_manual_trigger_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ManualTriggerName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Histogram =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule_HistogramTrigger,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_Histogram kHistogram{};
+  template <typename T = TriggerRule_HistogramTrigger> T* set_histogram() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_RepeatingInterval =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TriggerRule_RepeatingInterval,
+      TriggerRule>;
+
+  static constexpr FieldMetadata_RepeatingInterval kRepeatingInterval{};
+  template <typename T = TriggerRule_RepeatingInterval> T* set_repeating_interval() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class TriggerRule_RepeatingInterval_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TriggerRule_RepeatingInterval_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TriggerRule_RepeatingInterval_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TriggerRule_RepeatingInterval_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_period_ms() const { return at<1>().valid(); }
+  uint64_t period_ms() const { return at<1>().as_uint64(); }
+  bool has_randomized() const { return at<2>().valid(); }
+  bool randomized() const { return at<2>().as_bool(); }
+};
+
+class TriggerRule_RepeatingInterval : public ::protozero::Message {
+ public:
+  using Decoder = TriggerRule_RepeatingInterval_Decoder;
+  enum : int32_t {
+    kPeriodMsFieldNumber = 1,
+    kRandomizedFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TriggerRule.RepeatingInterval"; }
+
+
+  using FieldMetadata_PeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TriggerRule_RepeatingInterval>;
+
+  static constexpr FieldMetadata_PeriodMs kPeriodMs{};
+  void set_period_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Randomized =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TriggerRule_RepeatingInterval>;
+
+  static constexpr FieldMetadata_Randomized kRandomized{};
+  void set_randomized(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Randomized::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TriggerRule_HistogramTrigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TriggerRule_HistogramTrigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TriggerRule_HistogramTrigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TriggerRule_HistogramTrigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_histogram_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars histogram_name() const { return at<1>().as_string(); }
+  bool has_min_value() const { return at<2>().valid(); }
+  int64_t min_value() const { return at<2>().as_int64(); }
+  bool has_max_value() const { return at<3>().valid(); }
+  int64_t max_value() const { return at<3>().as_int64(); }
+};
+
+class TriggerRule_HistogramTrigger : public ::protozero::Message {
+ public:
+  using Decoder = TriggerRule_HistogramTrigger_Decoder;
+  enum : int32_t {
+    kHistogramNameFieldNumber = 1,
+    kMinValueFieldNumber = 2,
+    kMaxValueFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TriggerRule.HistogramTrigger"; }
+
+
+  using FieldMetadata_HistogramName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TriggerRule_HistogramTrigger>;
+
+  static constexpr FieldMetadata_HistogramName kHistogramName{};
+  void set_histogram_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HistogramName::kFieldId, data, size);
+  }
+  void set_histogram_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HistogramName::kFieldId, chars.data, chars.size);
+  }
+  void set_histogram_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HistogramName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MinValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TriggerRule_HistogramTrigger>;
+
+  static constexpr FieldMetadata_MinValue kMinValue{};
+  void set_min_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TriggerRule_HistogramTrigger>;
+
+  static constexpr FieldMetadata_MaxValue kMaxValue{};
+  void set_max_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/data_source_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_DATA_SOURCE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidGameInterventionListConfig;
+class AndroidLogConfig;
+class AndroidPolledStateConfig;
+class AndroidPowerConfig;
+class AndroidSdkSyspropGuardConfig;
+class AndroidSystemPropertyConfig;
+class ChromeConfig;
+class EtwConfig;
+class FtraceConfig;
+class GpuCounterConfig;
+class HeapprofdConfig;
+class InodeFileConfig;
+class InterceptorConfig;
+class JavaHprofConfig;
+class NetworkPacketTraceConfig;
+class PackagesListConfig;
+class PerfEventConfig;
+class ProcessStatsConfig;
+class StatsdTracingConfig;
+class SurfaceFlingerLayersConfig;
+class SurfaceFlingerTransactionsConfig;
+class SysStatsConfig;
+class SystemInfoConfig;
+class TestConfig;
+class TrackEventConfig;
+class VulkanMemoryConfig;
+namespace perfetto_pbzero_enum_DataSourceConfig {
+enum SessionInitiator : int32_t;
+}  // namespace perfetto_pbzero_enum_DataSourceConfig
+using DataSourceConfig_SessionInitiator = perfetto_pbzero_enum_DataSourceConfig::SessionInitiator;
+
+namespace perfetto_pbzero_enum_DataSourceConfig {
+enum SessionInitiator : int32_t {
+  SESSION_INITIATOR_UNSPECIFIED = 0,
+  SESSION_INITIATOR_TRUSTED_SYSTEM = 1,
+};
+} // namespace perfetto_pbzero_enum_DataSourceConfig
+using DataSourceConfig_SessionInitiator = perfetto_pbzero_enum_DataSourceConfig::SessionInitiator;
+
+
+constexpr DataSourceConfig_SessionInitiator DataSourceConfig_SessionInitiator_MIN = DataSourceConfig_SessionInitiator::SESSION_INITIATOR_UNSPECIFIED;
+constexpr DataSourceConfig_SessionInitiator DataSourceConfig_SessionInitiator_MAX = DataSourceConfig_SessionInitiator::SESSION_INITIATOR_TRUSTED_SYSTEM;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* DataSourceConfig_SessionInitiator_Name(::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator::SESSION_INITIATOR_UNSPECIFIED:
+    return "SESSION_INITIATOR_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator::SESSION_INITIATOR_TRUSTED_SYSTEM:
+    return "SESSION_INITIATOR_TRUSTED_SYSTEM";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class DataSourceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/125, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DataSourceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DataSourceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DataSourceConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_target_buffer() const { return at<2>().valid(); }
+  uint32_t target_buffer() const { return at<2>().as_uint32(); }
+  bool has_trace_duration_ms() const { return at<3>().valid(); }
+  uint32_t trace_duration_ms() const { return at<3>().as_uint32(); }
+  bool has_prefer_suspend_clock_for_duration() const { return at<122>().valid(); }
+  bool prefer_suspend_clock_for_duration() const { return at<122>().as_bool(); }
+  bool has_stop_timeout_ms() const { return at<7>().valid(); }
+  uint32_t stop_timeout_ms() const { return at<7>().as_uint32(); }
+  bool has_enable_extra_guardrails() const { return at<6>().valid(); }
+  bool enable_extra_guardrails() const { return at<6>().as_bool(); }
+  bool has_session_initiator() const { return at<8>().valid(); }
+  int32_t session_initiator() const { return at<8>().as_int32(); }
+  bool has_tracing_session_id() const { return at<4>().valid(); }
+  uint64_t tracing_session_id() const { return at<4>().as_uint64(); }
+  bool has_ftrace_config() const { return at<100>().valid(); }
+  ::protozero::ConstBytes ftrace_config() const { return at<100>().as_bytes(); }
+  bool has_inode_file_config() const { return at<102>().valid(); }
+  ::protozero::ConstBytes inode_file_config() const { return at<102>().as_bytes(); }
+  bool has_process_stats_config() const { return at<103>().valid(); }
+  ::protozero::ConstBytes process_stats_config() const { return at<103>().as_bytes(); }
+  bool has_sys_stats_config() const { return at<104>().valid(); }
+  ::protozero::ConstBytes sys_stats_config() const { return at<104>().as_bytes(); }
+  bool has_heapprofd_config() const { return at<105>().valid(); }
+  ::protozero::ConstBytes heapprofd_config() const { return at<105>().as_bytes(); }
+  bool has_java_hprof_config() const { return at<110>().valid(); }
+  ::protozero::ConstBytes java_hprof_config() const { return at<110>().as_bytes(); }
+  bool has_android_power_config() const { return at<106>().valid(); }
+  ::protozero::ConstBytes android_power_config() const { return at<106>().as_bytes(); }
+  bool has_android_log_config() const { return at<107>().valid(); }
+  ::protozero::ConstBytes android_log_config() const { return at<107>().as_bytes(); }
+  bool has_gpu_counter_config() const { return at<108>().valid(); }
+  ::protozero::ConstBytes gpu_counter_config() const { return at<108>().as_bytes(); }
+  bool has_android_game_intervention_list_config() const { return at<116>().valid(); }
+  ::protozero::ConstBytes android_game_intervention_list_config() const { return at<116>().as_bytes(); }
+  bool has_packages_list_config() const { return at<109>().valid(); }
+  ::protozero::ConstBytes packages_list_config() const { return at<109>().as_bytes(); }
+  bool has_perf_event_config() const { return at<111>().valid(); }
+  ::protozero::ConstBytes perf_event_config() const { return at<111>().as_bytes(); }
+  bool has_vulkan_memory_config() const { return at<112>().valid(); }
+  ::protozero::ConstBytes vulkan_memory_config() const { return at<112>().as_bytes(); }
+  bool has_track_event_config() const { return at<113>().valid(); }
+  ::protozero::ConstBytes track_event_config() const { return at<113>().as_bytes(); }
+  bool has_android_polled_state_config() const { return at<114>().valid(); }
+  ::protozero::ConstBytes android_polled_state_config() const { return at<114>().as_bytes(); }
+  bool has_android_system_property_config() const { return at<118>().valid(); }
+  ::protozero::ConstBytes android_system_property_config() const { return at<118>().as_bytes(); }
+  bool has_statsd_tracing_config() const { return at<117>().valid(); }
+  ::protozero::ConstBytes statsd_tracing_config() const { return at<117>().as_bytes(); }
+  bool has_system_info_config() const { return at<119>().valid(); }
+  ::protozero::ConstBytes system_info_config() const { return at<119>().as_bytes(); }
+  bool has_chrome_config() const { return at<101>().valid(); }
+  ::protozero::ConstBytes chrome_config() const { return at<101>().as_bytes(); }
+  bool has_interceptor_config() const { return at<115>().valid(); }
+  ::protozero::ConstBytes interceptor_config() const { return at<115>().as_bytes(); }
+  bool has_network_packet_trace_config() const { return at<120>().valid(); }
+  ::protozero::ConstBytes network_packet_trace_config() const { return at<120>().as_bytes(); }
+  bool has_surfaceflinger_layers_config() const { return at<121>().valid(); }
+  ::protozero::ConstBytes surfaceflinger_layers_config() const { return at<121>().as_bytes(); }
+  bool has_surfaceflinger_transactions_config() const { return at<123>().valid(); }
+  ::protozero::ConstBytes surfaceflinger_transactions_config() const { return at<123>().as_bytes(); }
+  bool has_android_sdk_sysprop_guard_config() const { return at<124>().valid(); }
+  ::protozero::ConstBytes android_sdk_sysprop_guard_config() const { return at<124>().as_bytes(); }
+  bool has_etw_config() const { return at<125>().valid(); }
+  ::protozero::ConstBytes etw_config() const { return at<125>().as_bytes(); }
+  // field legacy_config omitted because its id is too high
+  // field for_testing omitted because its id is too high
+};
+
+class DataSourceConfig : public ::protozero::Message {
+ public:
+  using Decoder = DataSourceConfig_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kTargetBufferFieldNumber = 2,
+    kTraceDurationMsFieldNumber = 3,
+    kPreferSuspendClockForDurationFieldNumber = 122,
+    kStopTimeoutMsFieldNumber = 7,
+    kEnableExtraGuardrailsFieldNumber = 6,
+    kSessionInitiatorFieldNumber = 8,
+    kTracingSessionIdFieldNumber = 4,
+    kFtraceConfigFieldNumber = 100,
+    kInodeFileConfigFieldNumber = 102,
+    kProcessStatsConfigFieldNumber = 103,
+    kSysStatsConfigFieldNumber = 104,
+    kHeapprofdConfigFieldNumber = 105,
+    kJavaHprofConfigFieldNumber = 110,
+    kAndroidPowerConfigFieldNumber = 106,
+    kAndroidLogConfigFieldNumber = 107,
+    kGpuCounterConfigFieldNumber = 108,
+    kAndroidGameInterventionListConfigFieldNumber = 116,
+    kPackagesListConfigFieldNumber = 109,
+    kPerfEventConfigFieldNumber = 111,
+    kVulkanMemoryConfigFieldNumber = 112,
+    kTrackEventConfigFieldNumber = 113,
+    kAndroidPolledStateConfigFieldNumber = 114,
+    kAndroidSystemPropertyConfigFieldNumber = 118,
+    kStatsdTracingConfigFieldNumber = 117,
+    kSystemInfoConfigFieldNumber = 119,
+    kChromeConfigFieldNumber = 101,
+    kInterceptorConfigFieldNumber = 115,
+    kNetworkPacketTraceConfigFieldNumber = 120,
+    kSurfaceflingerLayersConfigFieldNumber = 121,
+    kSurfaceflingerTransactionsConfigFieldNumber = 123,
+    kAndroidSdkSyspropGuardConfigFieldNumber = 124,
+    kEtwConfigFieldNumber = 125,
+    kLegacyConfigFieldNumber = 1000,
+    kForTestingFieldNumber = 1001,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DataSourceConfig"; }
+
+
+  using SessionInitiator = ::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator;
+  static inline const char* SessionInitiator_Name(SessionInitiator value) {
+    return ::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator_Name(value);
+  }
+  static inline const SessionInitiator SESSION_INITIATOR_UNSPECIFIED = SessionInitiator::SESSION_INITIATOR_UNSPECIFIED;
+  static inline const SessionInitiator SESSION_INITIATOR_TRUSTED_SYSTEM = SessionInitiator::SESSION_INITIATOR_TRUSTED_SYSTEM;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_TargetBuffer kTargetBuffer{};
+  void set_target_buffer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetBuffer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceDurationMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_TraceDurationMs kTraceDurationMs{};
+  void set_trace_duration_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceDurationMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PreferSuspendClockForDuration =
+    ::protozero::proto_utils::FieldMetadata<
+      122,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_PreferSuspendClockForDuration kPreferSuspendClockForDuration{};
+  void set_prefer_suspend_clock_for_duration(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreferSuspendClockForDuration::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StopTimeoutMs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_StopTimeoutMs kStopTimeoutMs{};
+  void set_stop_timeout_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StopTimeoutMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnableExtraGuardrails =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_EnableExtraGuardrails kEnableExtraGuardrails{};
+  void set_enable_extra_guardrails(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnableExtraGuardrails::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SessionInitiator =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_SessionInitiator kSessionInitiator{};
+  void set_session_initiator(::perfetto::protos::pbzero::DataSourceConfig_SessionInitiator value) {
+    static constexpr uint32_t field_id = FieldMetadata_SessionInitiator::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TracingSessionId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_TracingSessionId kTracingSessionId{};
+  void set_tracing_session_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingSessionId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FtraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      100,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_FtraceConfig kFtraceConfig{};
+  template <typename T = FtraceConfig> T* set_ftrace_config() {
+    return BeginNestedMessage<T>(100);
+  }
+
+  void set_ftrace_config_raw(const std::string& raw) {
+    return AppendBytes(100, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_InodeFileConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      102,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InodeFileConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_InodeFileConfig kInodeFileConfig{};
+  template <typename T = InodeFileConfig> T* set_inode_file_config() {
+    return BeginNestedMessage<T>(102);
+  }
+
+  void set_inode_file_config_raw(const std::string& raw) {
+    return AppendBytes(102, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_ProcessStatsConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      103,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessStatsConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_ProcessStatsConfig kProcessStatsConfig{};
+  template <typename T = ProcessStatsConfig> T* set_process_stats_config() {
+    return BeginNestedMessage<T>(103);
+  }
+
+  void set_process_stats_config_raw(const std::string& raw) {
+    return AppendBytes(103, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_SysStatsConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      104,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStatsConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_SysStatsConfig kSysStatsConfig{};
+  template <typename T = SysStatsConfig> T* set_sys_stats_config() {
+    return BeginNestedMessage<T>(104);
+  }
+
+  void set_sys_stats_config_raw(const std::string& raw) {
+    return AppendBytes(104, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_HeapprofdConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      105,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapprofdConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_HeapprofdConfig kHeapprofdConfig{};
+  template <typename T = HeapprofdConfig> T* set_heapprofd_config() {
+    return BeginNestedMessage<T>(105);
+  }
+
+  void set_heapprofd_config_raw(const std::string& raw) {
+    return AppendBytes(105, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_JavaHprofConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      110,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      JavaHprofConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_JavaHprofConfig kJavaHprofConfig{};
+  template <typename T = JavaHprofConfig> T* set_java_hprof_config() {
+    return BeginNestedMessage<T>(110);
+  }
+
+  void set_java_hprof_config_raw(const std::string& raw) {
+    return AppendBytes(110, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidPowerConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      106,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidPowerConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidPowerConfig kAndroidPowerConfig{};
+  template <typename T = AndroidPowerConfig> T* set_android_power_config() {
+    return BeginNestedMessage<T>(106);
+  }
+
+  void set_android_power_config_raw(const std::string& raw) {
+    return AppendBytes(106, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidLogConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      107,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidLogConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidLogConfig kAndroidLogConfig{};
+  template <typename T = AndroidLogConfig> T* set_android_log_config() {
+    return BeginNestedMessage<T>(107);
+  }
+
+  void set_android_log_config_raw(const std::string& raw) {
+    return AppendBytes(107, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_GpuCounterConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      108,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_GpuCounterConfig kGpuCounterConfig{};
+  template <typename T = GpuCounterConfig> T* set_gpu_counter_config() {
+    return BeginNestedMessage<T>(108);
+  }
+
+  void set_gpu_counter_config_raw(const std::string& raw) {
+    return AppendBytes(108, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidGameInterventionListConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      116,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidGameInterventionListConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidGameInterventionListConfig kAndroidGameInterventionListConfig{};
+  template <typename T = AndroidGameInterventionListConfig> T* set_android_game_intervention_list_config() {
+    return BeginNestedMessage<T>(116);
+  }
+
+  void set_android_game_intervention_list_config_raw(const std::string& raw) {
+    return AppendBytes(116, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_PackagesListConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      109,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PackagesListConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_PackagesListConfig kPackagesListConfig{};
+  template <typename T = PackagesListConfig> T* set_packages_list_config() {
+    return BeginNestedMessage<T>(109);
+  }
+
+  void set_packages_list_config_raw(const std::string& raw) {
+    return AppendBytes(109, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_PerfEventConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      111,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEventConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_PerfEventConfig kPerfEventConfig{};
+  template <typename T = PerfEventConfig> T* set_perf_event_config() {
+    return BeginNestedMessage<T>(111);
+  }
+
+  void set_perf_event_config_raw(const std::string& raw) {
+    return AppendBytes(111, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_VulkanMemoryConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      112,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanMemoryConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_VulkanMemoryConfig kVulkanMemoryConfig{};
+  template <typename T = VulkanMemoryConfig> T* set_vulkan_memory_config() {
+    return BeginNestedMessage<T>(112);
+  }
+
+  void set_vulkan_memory_config_raw(const std::string& raw) {
+    return AppendBytes(112, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_TrackEventConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      113,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_TrackEventConfig kTrackEventConfig{};
+  template <typename T = TrackEventConfig> T* set_track_event_config() {
+    return BeginNestedMessage<T>(113);
+  }
+
+  void set_track_event_config_raw(const std::string& raw) {
+    return AppendBytes(113, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidPolledStateConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      114,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidPolledStateConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidPolledStateConfig kAndroidPolledStateConfig{};
+  template <typename T = AndroidPolledStateConfig> T* set_android_polled_state_config() {
+    return BeginNestedMessage<T>(114);
+  }
+
+  void set_android_polled_state_config_raw(const std::string& raw) {
+    return AppendBytes(114, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidSystemPropertyConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      118,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidSystemPropertyConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidSystemPropertyConfig kAndroidSystemPropertyConfig{};
+  template <typename T = AndroidSystemPropertyConfig> T* set_android_system_property_config() {
+    return BeginNestedMessage<T>(118);
+  }
+
+  void set_android_system_property_config_raw(const std::string& raw) {
+    return AppendBytes(118, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_StatsdTracingConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      117,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StatsdTracingConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_StatsdTracingConfig kStatsdTracingConfig{};
+  template <typename T = StatsdTracingConfig> T* set_statsd_tracing_config() {
+    return BeginNestedMessage<T>(117);
+  }
+
+  void set_statsd_tracing_config_raw(const std::string& raw) {
+    return AppendBytes(117, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_SystemInfoConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      119,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SystemInfoConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_SystemInfoConfig kSystemInfoConfig{};
+  template <typename T = SystemInfoConfig> T* set_system_info_config() {
+    return BeginNestedMessage<T>(119);
+  }
+
+
+  using FieldMetadata_ChromeConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      101,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_ChromeConfig kChromeConfig{};
+  template <typename T = ChromeConfig> T* set_chrome_config() {
+    return BeginNestedMessage<T>(101);
+  }
+
+
+  using FieldMetadata_InterceptorConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      115,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InterceptorConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_InterceptorConfig kInterceptorConfig{};
+  template <typename T = InterceptorConfig> T* set_interceptor_config() {
+    return BeginNestedMessage<T>(115);
+  }
+
+
+  using FieldMetadata_NetworkPacketTraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      120,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketTraceConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_NetworkPacketTraceConfig kNetworkPacketTraceConfig{};
+  template <typename T = NetworkPacketTraceConfig> T* set_network_packet_trace_config() {
+    return BeginNestedMessage<T>(120);
+  }
+
+  void set_network_packet_trace_config_raw(const std::string& raw) {
+    return AppendBytes(120, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_SurfaceflingerLayersConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      121,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SurfaceFlingerLayersConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_SurfaceflingerLayersConfig kSurfaceflingerLayersConfig{};
+  template <typename T = SurfaceFlingerLayersConfig> T* set_surfaceflinger_layers_config() {
+    return BeginNestedMessage<T>(121);
+  }
+
+  void set_surfaceflinger_layers_config_raw(const std::string& raw) {
+    return AppendBytes(121, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_SurfaceflingerTransactionsConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      123,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SurfaceFlingerTransactionsConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_SurfaceflingerTransactionsConfig kSurfaceflingerTransactionsConfig{};
+  template <typename T = SurfaceFlingerTransactionsConfig> T* set_surfaceflinger_transactions_config() {
+    return BeginNestedMessage<T>(123);
+  }
+
+  void set_surfaceflinger_transactions_config_raw(const std::string& raw) {
+    return AppendBytes(123, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_AndroidSdkSyspropGuardConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      124,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidSdkSyspropGuardConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_AndroidSdkSyspropGuardConfig kAndroidSdkSyspropGuardConfig{};
+  template <typename T = AndroidSdkSyspropGuardConfig> T* set_android_sdk_sysprop_guard_config() {
+    return BeginNestedMessage<T>(124);
+  }
+
+  void set_android_sdk_sysprop_guard_config_raw(const std::string& raw) {
+    return AppendBytes(124, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_EtwConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      125,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EtwConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_EtwConfig kEtwConfig{};
+  template <typename T = EtwConfig> T* set_etw_config() {
+    return BeginNestedMessage<T>(125);
+  }
+
+  void set_etw_config_raw(const std::string& raw) {
+    return AppendBytes(125, raw.data(), raw.size());
+  }
+
+
+  using FieldMetadata_LegacyConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      1000,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_LegacyConfig kLegacyConfig{};
+  void set_legacy_config(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LegacyConfig::kFieldId, data, size);
+  }
+  void set_legacy_config(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LegacyConfig::kFieldId, chars.data, chars.size);
+  }
+  void set_legacy_config(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacyConfig::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      1001,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestConfig,
+      DataSourceConfig>;
+
+  static constexpr FieldMetadata_ForTesting kForTesting{};
+  template <typename T = TestConfig> T* set_for_testing() {
+    return BeginNestedMessage<T>(1001);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/etw/etw_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ETW_ETW_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ETW_ETW_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_EtwConfig {
+enum KernelFlag : int32_t;
+}  // namespace perfetto_pbzero_enum_EtwConfig
+using EtwConfig_KernelFlag = perfetto_pbzero_enum_EtwConfig::KernelFlag;
+
+namespace perfetto_pbzero_enum_EtwConfig {
+enum KernelFlag : int32_t {
+  CSWITCH = 0,
+  DISPATCHER = 1,
+};
+} // namespace perfetto_pbzero_enum_EtwConfig
+using EtwConfig_KernelFlag = perfetto_pbzero_enum_EtwConfig::KernelFlag;
+
+
+constexpr EtwConfig_KernelFlag EtwConfig_KernelFlag_MIN = EtwConfig_KernelFlag::CSWITCH;
+constexpr EtwConfig_KernelFlag EtwConfig_KernelFlag_MAX = EtwConfig_KernelFlag::DISPATCHER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* EtwConfig_KernelFlag_Name(::perfetto::protos::pbzero::EtwConfig_KernelFlag value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::EtwConfig_KernelFlag::CSWITCH:
+    return "CSWITCH";
+
+  case ::perfetto::protos::pbzero::EtwConfig_KernelFlag::DISPATCHER:
+    return "DISPATCHER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class EtwConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  EtwConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EtwConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EtwConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_kernel_flags() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> kernel_flags() const { return GetRepeated<int32_t>(1); }
+};
+
+class EtwConfig : public ::protozero::Message {
+ public:
+  using Decoder = EtwConfig_Decoder;
+  enum : int32_t {
+    kKernelFlagsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EtwConfig"; }
+
+
+  using KernelFlag = ::perfetto::protos::pbzero::EtwConfig_KernelFlag;
+  static inline const char* KernelFlag_Name(KernelFlag value) {
+    return ::perfetto::protos::pbzero::EtwConfig_KernelFlag_Name(value);
+  }
+  static inline const KernelFlag CSWITCH = KernelFlag::CSWITCH;
+  static inline const KernelFlag DISPATCHER = KernelFlag::DISPATCHER;
+
+  using FieldMetadata_KernelFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::EtwConfig_KernelFlag,
+      EtwConfig>;
+
+  static constexpr FieldMetadata_KernelFlags kKernelFlags{};
+  void add_kernel_flags(::perfetto::protos::pbzero::EtwConfig_KernelFlag value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/interceptor_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ConsoleConfig;
+
+class InterceptorConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/100, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InterceptorConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InterceptorConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InterceptorConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_console_config() const { return at<100>().valid(); }
+  ::protozero::ConstBytes console_config() const { return at<100>().as_bytes(); }
+};
+
+class InterceptorConfig : public ::protozero::Message {
+ public:
+  using Decoder = InterceptorConfig_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kConsoleConfigFieldNumber = 100,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InterceptorConfig"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InterceptorConfig>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ConsoleConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      100,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ConsoleConfig,
+      InterceptorConfig>;
+
+  static constexpr FieldMetadata_ConsoleConfig kConsoleConfig{};
+  template <typename T = ConsoleConfig> T* set_console_config() {
+    return BeginNestedMessage<T>(100);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/stress_test_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class StressTestConfig_WriterTiming;
+class TraceConfig;
+
+class StressTestConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  StressTestConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StressTestConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StressTestConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trace_config() const { return at<1>().valid(); }
+  ::protozero::ConstBytes trace_config() const { return at<1>().as_bytes(); }
+  bool has_shmem_size_kb() const { return at<2>().valid(); }
+  uint32_t shmem_size_kb() const { return at<2>().as_uint32(); }
+  bool has_shmem_page_size_kb() const { return at<3>().valid(); }
+  uint32_t shmem_page_size_kb() const { return at<3>().as_uint32(); }
+  bool has_num_processes() const { return at<4>().valid(); }
+  uint32_t num_processes() const { return at<4>().as_uint32(); }
+  bool has_num_threads() const { return at<5>().valid(); }
+  uint32_t num_threads() const { return at<5>().as_uint32(); }
+  bool has_max_events() const { return at<6>().valid(); }
+  uint32_t max_events() const { return at<6>().as_uint32(); }
+  bool has_nesting() const { return at<7>().valid(); }
+  uint32_t nesting() const { return at<7>().as_uint32(); }
+  bool has_steady_state_timings() const { return at<8>().valid(); }
+  ::protozero::ConstBytes steady_state_timings() const { return at<8>().as_bytes(); }
+  bool has_burst_period_ms() const { return at<9>().valid(); }
+  uint32_t burst_period_ms() const { return at<9>().as_uint32(); }
+  bool has_burst_duration_ms() const { return at<10>().valid(); }
+  uint32_t burst_duration_ms() const { return at<10>().as_uint32(); }
+  bool has_burst_timings() const { return at<11>().valid(); }
+  ::protozero::ConstBytes burst_timings() const { return at<11>().as_bytes(); }
+};
+
+class StressTestConfig : public ::protozero::Message {
+ public:
+  using Decoder = StressTestConfig_Decoder;
+  enum : int32_t {
+    kTraceConfigFieldNumber = 1,
+    kShmemSizeKbFieldNumber = 2,
+    kShmemPageSizeKbFieldNumber = 3,
+    kNumProcessesFieldNumber = 4,
+    kNumThreadsFieldNumber = 5,
+    kMaxEventsFieldNumber = 6,
+    kNestingFieldNumber = 7,
+    kSteadyStateTimingsFieldNumber = 8,
+    kBurstPeriodMsFieldNumber = 9,
+    kBurstDurationMsFieldNumber = 10,
+    kBurstTimingsFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StressTestConfig"; }
+
+  using WriterTiming = ::perfetto::protos::pbzero::StressTestConfig_WriterTiming;
+
+  using FieldMetadata_TraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_TraceConfig kTraceConfig{};
+  template <typename T = TraceConfig> T* set_trace_config() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ShmemSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_ShmemSizeKb kShmemSizeKb{};
+  void set_shmem_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmemSizeKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ShmemPageSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_ShmemPageSizeKb kShmemPageSizeKb{};
+  void set_shmem_page_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmemPageSizeKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumProcesses =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_NumProcesses kNumProcesses{};
+  void set_num_processes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumProcesses::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumThreads =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_NumThreads kNumThreads{};
+  void set_num_threads(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumThreads::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_MaxEvents kMaxEvents{};
+  void set_max_events(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nesting =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_Nesting kNesting{};
+  void set_nesting(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nesting::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SteadyStateTimings =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StressTestConfig_WriterTiming,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_SteadyStateTimings kSteadyStateTimings{};
+  template <typename T = StressTestConfig_WriterTiming> T* set_steady_state_timings() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_BurstPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_BurstPeriodMs kBurstPeriodMs{};
+  void set_burst_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BurstPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BurstDurationMs =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_BurstDurationMs kBurstDurationMs{};
+  void set_burst_duration_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BurstDurationMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BurstTimings =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      StressTestConfig_WriterTiming,
+      StressTestConfig>;
+
+  static constexpr FieldMetadata_BurstTimings kBurstTimings{};
+  template <typename T = StressTestConfig_WriterTiming> T* set_burst_timings() {
+    return BeginNestedMessage<T>(11);
+  }
+
+};
+
+class StressTestConfig_WriterTiming_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  StressTestConfig_WriterTiming_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StressTestConfig_WriterTiming_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StressTestConfig_WriterTiming_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_payload_mean() const { return at<1>().valid(); }
+  double payload_mean() const { return at<1>().as_double(); }
+  bool has_payload_stddev() const { return at<2>().valid(); }
+  double payload_stddev() const { return at<2>().as_double(); }
+  bool has_rate_mean() const { return at<3>().valid(); }
+  double rate_mean() const { return at<3>().as_double(); }
+  bool has_rate_stddev() const { return at<4>().valid(); }
+  double rate_stddev() const { return at<4>().as_double(); }
+  bool has_payload_write_time_ms() const { return at<5>().valid(); }
+  uint32_t payload_write_time_ms() const { return at<5>().as_uint32(); }
+};
+
+class StressTestConfig_WriterTiming : public ::protozero::Message {
+ public:
+  using Decoder = StressTestConfig_WriterTiming_Decoder;
+  enum : int32_t {
+    kPayloadMeanFieldNumber = 1,
+    kPayloadStddevFieldNumber = 2,
+    kRateMeanFieldNumber = 3,
+    kRateStddevFieldNumber = 4,
+    kPayloadWriteTimeMsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StressTestConfig.WriterTiming"; }
+
+
+  using FieldMetadata_PayloadMean =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      StressTestConfig_WriterTiming>;
+
+  static constexpr FieldMetadata_PayloadMean kPayloadMean{};
+  void set_payload_mean(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_PayloadMean::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PayloadStddev =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      StressTestConfig_WriterTiming>;
+
+  static constexpr FieldMetadata_PayloadStddev kPayloadStddev{};
+  void set_payload_stddev(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_PayloadStddev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RateMean =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      StressTestConfig_WriterTiming>;
+
+  static constexpr FieldMetadata_RateMean kRateMean{};
+  void set_rate_mean(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_RateMean::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RateStddev =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      StressTestConfig_WriterTiming>;
+
+  static constexpr FieldMetadata_RateStddev kRateStddev{};
+  void set_rate_stddev(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_RateStddev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PayloadWriteTimeMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StressTestConfig_WriterTiming>;
+
+  static constexpr FieldMetadata_PayloadWriteTimeMs kPayloadWriteTimeMs{};
+  void set_payload_write_time_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PayloadWriteTimeMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/test_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TestConfig_DummyFields;
+
+class TestConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TestConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_message_count() const { return at<1>().valid(); }
+  uint32_t message_count() const { return at<1>().as_uint32(); }
+  bool has_max_messages_per_second() const { return at<2>().valid(); }
+  uint32_t max_messages_per_second() const { return at<2>().as_uint32(); }
+  bool has_seed() const { return at<3>().valid(); }
+  uint32_t seed() const { return at<3>().as_uint32(); }
+  bool has_message_size() const { return at<4>().valid(); }
+  uint32_t message_size() const { return at<4>().as_uint32(); }
+  bool has_send_batch_on_register() const { return at<5>().valid(); }
+  bool send_batch_on_register() const { return at<5>().as_bool(); }
+  bool has_dummy_fields() const { return at<6>().valid(); }
+  ::protozero::ConstBytes dummy_fields() const { return at<6>().as_bytes(); }
+};
+
+class TestConfig : public ::protozero::Message {
+ public:
+  using Decoder = TestConfig_Decoder;
+  enum : int32_t {
+    kMessageCountFieldNumber = 1,
+    kMaxMessagesPerSecondFieldNumber = 2,
+    kSeedFieldNumber = 3,
+    kMessageSizeFieldNumber = 4,
+    kSendBatchOnRegisterFieldNumber = 5,
+    kDummyFieldsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestConfig"; }
+
+  using DummyFields = ::perfetto::protos::pbzero::TestConfig_DummyFields;
+
+  using FieldMetadata_MessageCount =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig>;
+
+  static constexpr FieldMetadata_MessageCount kMessageCount{};
+  void set_message_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxMessagesPerSecond =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig>;
+
+  static constexpr FieldMetadata_MaxMessagesPerSecond kMaxMessagesPerSecond{};
+  void set_max_messages_per_second(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxMessagesPerSecond::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig>;
+
+  static constexpr FieldMetadata_Seed kSeed{};
+  void set_seed(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MessageSize =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig>;
+
+  static constexpr FieldMetadata_MessageSize kMessageSize{};
+  void set_message_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SendBatchOnRegister =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TestConfig>;
+
+  static constexpr FieldMetadata_SendBatchOnRegister kSendBatchOnRegister{};
+  void set_send_batch_on_register(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SendBatchOnRegister::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DummyFields =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestConfig_DummyFields,
+      TestConfig>;
+
+  static constexpr FieldMetadata_DummyFields kDummyFields{};
+  template <typename T = TestConfig_DummyFields> T* set_dummy_fields() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class TestConfig_DummyFields_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/14, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TestConfig_DummyFields_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestConfig_DummyFields_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestConfig_DummyFields_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_field_uint32() const { return at<1>().valid(); }
+  uint32_t field_uint32() const { return at<1>().as_uint32(); }
+  bool has_field_int32() const { return at<2>().valid(); }
+  int32_t field_int32() const { return at<2>().as_int32(); }
+  bool has_field_uint64() const { return at<3>().valid(); }
+  uint64_t field_uint64() const { return at<3>().as_uint64(); }
+  bool has_field_int64() const { return at<4>().valid(); }
+  int64_t field_int64() const { return at<4>().as_int64(); }
+  bool has_field_fixed64() const { return at<5>().valid(); }
+  uint64_t field_fixed64() const { return at<5>().as_uint64(); }
+  bool has_field_sfixed64() const { return at<6>().valid(); }
+  int64_t field_sfixed64() const { return at<6>().as_int64(); }
+  bool has_field_fixed32() const { return at<7>().valid(); }
+  uint32_t field_fixed32() const { return at<7>().as_uint32(); }
+  bool has_field_sfixed32() const { return at<8>().valid(); }
+  int32_t field_sfixed32() const { return at<8>().as_int32(); }
+  bool has_field_double() const { return at<9>().valid(); }
+  double field_double() const { return at<9>().as_double(); }
+  bool has_field_float() const { return at<10>().valid(); }
+  float field_float() const { return at<10>().as_float(); }
+  bool has_field_sint64() const { return at<11>().valid(); }
+  int64_t field_sint64() const { return at<11>().as_int64(); }
+  bool has_field_sint32() const { return at<12>().valid(); }
+  int32_t field_sint32() const { return at<12>().as_int32(); }
+  bool has_field_string() const { return at<13>().valid(); }
+  ::protozero::ConstChars field_string() const { return at<13>().as_string(); }
+  bool has_field_bytes() const { return at<14>().valid(); }
+  ::protozero::ConstBytes field_bytes() const { return at<14>().as_bytes(); }
+};
+
+class TestConfig_DummyFields : public ::protozero::Message {
+ public:
+  using Decoder = TestConfig_DummyFields_Decoder;
+  enum : int32_t {
+    kFieldUint32FieldNumber = 1,
+    kFieldInt32FieldNumber = 2,
+    kFieldUint64FieldNumber = 3,
+    kFieldInt64FieldNumber = 4,
+    kFieldFixed64FieldNumber = 5,
+    kFieldSfixed64FieldNumber = 6,
+    kFieldFixed32FieldNumber = 7,
+    kFieldSfixed32FieldNumber = 8,
+    kFieldDoubleFieldNumber = 9,
+    kFieldFloatFieldNumber = 10,
+    kFieldSint64FieldNumber = 11,
+    kFieldSint32FieldNumber = 12,
+    kFieldStringFieldNumber = 13,
+    kFieldBytesFieldNumber = 14,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestConfig.DummyFields"; }
+
+
+  using FieldMetadata_FieldUint32 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldUint32 kFieldUint32{};
+  void set_field_uint32(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldUint32::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldInt32 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldInt32 kFieldInt32{};
+  void set_field_int32(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldInt32::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldUint64 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldUint64 kFieldUint64{};
+  void set_field_uint64(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldUint64::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldInt64 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldInt64 kFieldInt64{};
+  void set_field_int64(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldInt64::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldFixed64 =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldFixed64 kFieldFixed64{};
+  void set_field_fixed64(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldFixed64::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldSfixed64 =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed64,
+      int64_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldSfixed64 kFieldSfixed64{};
+  void set_field_sfixed64(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldSfixed64::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldFixed32 =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldFixed32 kFieldFixed32{};
+  void set_field_fixed32(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldFixed32::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldSfixed32 =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed32,
+      int32_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldSfixed32 kFieldSfixed32{};
+  void set_field_sfixed32(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldSfixed32::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldDouble =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldDouble kFieldDouble{};
+  void set_field_double(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldDouble::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldFloat =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldFloat kFieldFloat{};
+  void set_field_float(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldFloat::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldSint64 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint64,
+      int64_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldSint64 kFieldSint64{};
+  void set_field_sint64(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldSint64::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldSint32 =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldSint32 kFieldSint32{};
+  void set_field_sint32(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldSint32::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldString =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldString kFieldString{};
+  void set_field_string(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FieldString::kFieldId, data, size);
+  }
+  void set_field_string(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FieldString::kFieldId, chars.data, chars.size);
+  }
+  void set_field_string(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldString::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TestConfig_DummyFields>;
+
+  static constexpr FieldMetadata_FieldBytes kFieldBytes{};
+  void set_field_bytes(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_FieldBytes::kFieldId, data, size);
+  }
+  void set_field_bytes(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_FieldBytes::kFieldId, bytes.data, bytes.size);
+  }
+  void set_field_bytes(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FieldBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/config/trace_config.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DataSourceConfig;
+class TraceConfig_AndroidReportConfig;
+class TraceConfig_BufferConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_CmdTraceStartDelay;
+class TraceConfig_DataSource;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_ProducerConfig;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_TraceFilter;
+class TraceConfig_TraceFilter_StringFilterChain;
+class TraceConfig_TraceFilter_StringFilterRule;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+enum BuiltinClock : int32_t;
+namespace perfetto_pbzero_enum_TraceConfig_BufferConfig {
+enum FillPolicy : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig_BufferConfig
+using TraceConfig_BufferConfig_FillPolicy = perfetto_pbzero_enum_TraceConfig_BufferConfig::FillPolicy;
+namespace perfetto_pbzero_enum_TraceConfig {
+enum CompressionType : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_CompressionType = perfetto_pbzero_enum_TraceConfig::CompressionType;
+namespace perfetto_pbzero_enum_TraceConfig {
+enum LockdownModeOperation : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_LockdownModeOperation = perfetto_pbzero_enum_TraceConfig::LockdownModeOperation;
+namespace perfetto_pbzero_enum_TraceConfig {
+enum StatsdLogging : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_StatsdLogging = perfetto_pbzero_enum_TraceConfig::StatsdLogging;
+namespace perfetto_pbzero_enum_TraceConfig_TraceFilter {
+enum StringFilterPolicy : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig_TraceFilter
+using TraceConfig_TraceFilter_StringFilterPolicy = perfetto_pbzero_enum_TraceConfig_TraceFilter::StringFilterPolicy;
+namespace perfetto_pbzero_enum_TraceConfig_TriggerConfig {
+enum TriggerMode : int32_t;
+}  // namespace perfetto_pbzero_enum_TraceConfig_TriggerConfig
+using TraceConfig_TriggerConfig_TriggerMode = perfetto_pbzero_enum_TraceConfig_TriggerConfig::TriggerMode;
+
+namespace perfetto_pbzero_enum_TraceConfig {
+enum LockdownModeOperation : int32_t {
+  LOCKDOWN_UNCHANGED = 0,
+  LOCKDOWN_CLEAR = 1,
+  LOCKDOWN_SET = 2,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_LockdownModeOperation = perfetto_pbzero_enum_TraceConfig::LockdownModeOperation;
+
+
+constexpr TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation::LOCKDOWN_UNCHANGED;
+constexpr TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation::LOCKDOWN_SET;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_LockdownModeOperation_Name(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation::LOCKDOWN_UNCHANGED:
+    return "LOCKDOWN_UNCHANGED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation::LOCKDOWN_CLEAR:
+    return "LOCKDOWN_CLEAR";
+
+  case ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation::LOCKDOWN_SET:
+    return "LOCKDOWN_SET";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TraceConfig {
+enum CompressionType : int32_t {
+  COMPRESSION_TYPE_UNSPECIFIED = 0,
+  COMPRESSION_TYPE_DEFLATE = 1,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_CompressionType = perfetto_pbzero_enum_TraceConfig::CompressionType;
+
+
+constexpr TraceConfig_CompressionType TraceConfig_CompressionType_MIN = TraceConfig_CompressionType::COMPRESSION_TYPE_UNSPECIFIED;
+constexpr TraceConfig_CompressionType TraceConfig_CompressionType_MAX = TraceConfig_CompressionType::COMPRESSION_TYPE_DEFLATE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_CompressionType_Name(::perfetto::protos::pbzero::TraceConfig_CompressionType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_CompressionType::COMPRESSION_TYPE_UNSPECIFIED:
+    return "COMPRESSION_TYPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_CompressionType::COMPRESSION_TYPE_DEFLATE:
+    return "COMPRESSION_TYPE_DEFLATE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TraceConfig {
+enum StatsdLogging : int32_t {
+  STATSD_LOGGING_UNSPECIFIED = 0,
+  STATSD_LOGGING_ENABLED = 1,
+  STATSD_LOGGING_DISABLED = 2,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig
+using TraceConfig_StatsdLogging = perfetto_pbzero_enum_TraceConfig::StatsdLogging;
+
+
+constexpr TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MIN = TraceConfig_StatsdLogging::STATSD_LOGGING_UNSPECIFIED;
+constexpr TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MAX = TraceConfig_StatsdLogging::STATSD_LOGGING_DISABLED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_StatsdLogging_Name(::perfetto::protos::pbzero::TraceConfig_StatsdLogging value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_StatsdLogging::STATSD_LOGGING_UNSPECIFIED:
+    return "STATSD_LOGGING_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_StatsdLogging::STATSD_LOGGING_ENABLED:
+    return "STATSD_LOGGING_ENABLED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_StatsdLogging::STATSD_LOGGING_DISABLED:
+    return "STATSD_LOGGING_DISABLED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TraceConfig_TraceFilter {
+enum StringFilterPolicy : int32_t {
+  SFP_UNSPECIFIED = 0,
+  SFP_MATCH_REDACT_GROUPS = 1,
+  SFP_ATRACE_MATCH_REDACT_GROUPS = 2,
+  SFP_MATCH_BREAK = 3,
+  SFP_ATRACE_MATCH_BREAK = 4,
+  SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS = 5,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig_TraceFilter
+using TraceConfig_TraceFilter_StringFilterPolicy = perfetto_pbzero_enum_TraceConfig_TraceFilter::StringFilterPolicy;
+
+
+constexpr TraceConfig_TraceFilter_StringFilterPolicy TraceConfig_TraceFilter_StringFilterPolicy_MIN = TraceConfig_TraceFilter_StringFilterPolicy::SFP_UNSPECIFIED;
+constexpr TraceConfig_TraceFilter_StringFilterPolicy TraceConfig_TraceFilter_StringFilterPolicy_MAX = TraceConfig_TraceFilter_StringFilterPolicy::SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_TraceFilter_StringFilterPolicy_Name(::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_UNSPECIFIED:
+    return "SFP_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_MATCH_REDACT_GROUPS:
+    return "SFP_MATCH_REDACT_GROUPS";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_ATRACE_MATCH_REDACT_GROUPS:
+    return "SFP_ATRACE_MATCH_REDACT_GROUPS";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_MATCH_BREAK:
+    return "SFP_MATCH_BREAK";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_ATRACE_MATCH_BREAK:
+    return "SFP_ATRACE_MATCH_BREAK";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy::SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS:
+    return "SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TraceConfig_TriggerConfig {
+enum TriggerMode : int32_t {
+  UNSPECIFIED = 0,
+  START_TRACING = 1,
+  STOP_TRACING = 2,
+  CLONE_SNAPSHOT = 4,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig_TriggerConfig
+using TraceConfig_TriggerConfig_TriggerMode = perfetto_pbzero_enum_TraceConfig_TriggerConfig::TriggerMode;
+
+
+constexpr TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode::UNSPECIFIED;
+constexpr TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode::CLONE_SNAPSHOT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_TriggerConfig_TriggerMode_Name(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode::START_TRACING:
+    return "START_TRACING";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode::STOP_TRACING:
+    return "STOP_TRACING";
+
+  case ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode::CLONE_SNAPSHOT:
+    return "CLONE_SNAPSHOT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TraceConfig_BufferConfig {
+enum FillPolicy : int32_t {
+  UNSPECIFIED = 0,
+  RING_BUFFER = 1,
+  DISCARD = 2,
+};
+} // namespace perfetto_pbzero_enum_TraceConfig_BufferConfig
+using TraceConfig_BufferConfig_FillPolicy = perfetto_pbzero_enum_TraceConfig_BufferConfig::FillPolicy;
+
+
+constexpr TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MIN = TraceConfig_BufferConfig_FillPolicy::UNSPECIFIED;
+constexpr TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MAX = TraceConfig_BufferConfig_FillPolicy::DISCARD;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TraceConfig_BufferConfig_FillPolicy_Name(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy::RING_BUFFER:
+    return "RING_BUFFER";
+
+  case ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy::DISCARD:
+    return "DISCARD";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class TraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/37, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TraceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffers() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buffers() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_data_sources() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> data_sources() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_builtin_data_sources() const { return at<20>().valid(); }
+  ::protozero::ConstBytes builtin_data_sources() const { return at<20>().as_bytes(); }
+  bool has_duration_ms() const { return at<3>().valid(); }
+  uint32_t duration_ms() const { return at<3>().as_uint32(); }
+  bool has_prefer_suspend_clock_for_duration() const { return at<36>().valid(); }
+  bool prefer_suspend_clock_for_duration() const { return at<36>().as_bool(); }
+  bool has_enable_extra_guardrails() const { return at<4>().valid(); }
+  bool enable_extra_guardrails() const { return at<4>().as_bool(); }
+  bool has_lockdown_mode() const { return at<5>().valid(); }
+  int32_t lockdown_mode() const { return at<5>().as_int32(); }
+  bool has_producers() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> producers() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_statsd_metadata() const { return at<7>().valid(); }
+  ::protozero::ConstBytes statsd_metadata() const { return at<7>().as_bytes(); }
+  bool has_write_into_file() const { return at<8>().valid(); }
+  bool write_into_file() const { return at<8>().as_bool(); }
+  bool has_output_path() const { return at<29>().valid(); }
+  ::protozero::ConstChars output_path() const { return at<29>().as_string(); }
+  bool has_file_write_period_ms() const { return at<9>().valid(); }
+  uint32_t file_write_period_ms() const { return at<9>().as_uint32(); }
+  bool has_max_file_size_bytes() const { return at<10>().valid(); }
+  uint64_t max_file_size_bytes() const { return at<10>().as_uint64(); }
+  bool has_guardrail_overrides() const { return at<11>().valid(); }
+  ::protozero::ConstBytes guardrail_overrides() const { return at<11>().as_bytes(); }
+  bool has_deferred_start() const { return at<12>().valid(); }
+  bool deferred_start() const { return at<12>().as_bool(); }
+  bool has_flush_period_ms() const { return at<13>().valid(); }
+  uint32_t flush_period_ms() const { return at<13>().as_uint32(); }
+  bool has_flush_timeout_ms() const { return at<14>().valid(); }
+  uint32_t flush_timeout_ms() const { return at<14>().as_uint32(); }
+  bool has_data_source_stop_timeout_ms() const { return at<23>().valid(); }
+  uint32_t data_source_stop_timeout_ms() const { return at<23>().as_uint32(); }
+  bool has_notify_traceur() const { return at<16>().valid(); }
+  bool notify_traceur() const { return at<16>().as_bool(); }
+  bool has_bugreport_score() const { return at<30>().valid(); }
+  int32_t bugreport_score() const { return at<30>().as_int32(); }
+  bool has_trigger_config() const { return at<17>().valid(); }
+  ::protozero::ConstBytes trigger_config() const { return at<17>().as_bytes(); }
+  bool has_activate_triggers() const { return at<18>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> activate_triggers() const { return GetRepeated<::protozero::ConstChars>(18); }
+  bool has_incremental_state_config() const { return at<21>().valid(); }
+  ::protozero::ConstBytes incremental_state_config() const { return at<21>().as_bytes(); }
+  bool has_allow_user_build_tracing() const { return at<19>().valid(); }
+  bool allow_user_build_tracing() const { return at<19>().as_bool(); }
+  bool has_unique_session_name() const { return at<22>().valid(); }
+  ::protozero::ConstChars unique_session_name() const { return at<22>().as_string(); }
+  bool has_compression_type() const { return at<24>().valid(); }
+  int32_t compression_type() const { return at<24>().as_int32(); }
+  bool has_compress_from_cli() const { return at<37>().valid(); }
+  bool compress_from_cli() const { return at<37>().as_bool(); }
+  bool has_incident_report_config() const { return at<25>().valid(); }
+  ::protozero::ConstBytes incident_report_config() const { return at<25>().as_bytes(); }
+  bool has_statsd_logging() const { return at<31>().valid(); }
+  int32_t statsd_logging() const { return at<31>().as_int32(); }
+  bool has_trace_uuid_msb() const { return at<27>().valid(); }
+  int64_t trace_uuid_msb() const { return at<27>().as_int64(); }
+  bool has_trace_uuid_lsb() const { return at<28>().valid(); }
+  int64_t trace_uuid_lsb() const { return at<28>().as_int64(); }
+  bool has_trace_filter() const { return at<33>().valid(); }
+  ::protozero::ConstBytes trace_filter() const { return at<33>().as_bytes(); }
+  bool has_android_report_config() const { return at<34>().valid(); }
+  ::protozero::ConstBytes android_report_config() const { return at<34>().as_bytes(); }
+  bool has_cmd_trace_start_delay() const { return at<35>().valid(); }
+  ::protozero::ConstBytes cmd_trace_start_delay() const { return at<35>().as_bytes(); }
+};
+
+class TraceConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_Decoder;
+  enum : int32_t {
+    kBuffersFieldNumber = 1,
+    kDataSourcesFieldNumber = 2,
+    kBuiltinDataSourcesFieldNumber = 20,
+    kDurationMsFieldNumber = 3,
+    kPreferSuspendClockForDurationFieldNumber = 36,
+    kEnableExtraGuardrailsFieldNumber = 4,
+    kLockdownModeFieldNumber = 5,
+    kProducersFieldNumber = 6,
+    kStatsdMetadataFieldNumber = 7,
+    kWriteIntoFileFieldNumber = 8,
+    kOutputPathFieldNumber = 29,
+    kFileWritePeriodMsFieldNumber = 9,
+    kMaxFileSizeBytesFieldNumber = 10,
+    kGuardrailOverridesFieldNumber = 11,
+    kDeferredStartFieldNumber = 12,
+    kFlushPeriodMsFieldNumber = 13,
+    kFlushTimeoutMsFieldNumber = 14,
+    kDataSourceStopTimeoutMsFieldNumber = 23,
+    kNotifyTraceurFieldNumber = 16,
+    kBugreportScoreFieldNumber = 30,
+    kTriggerConfigFieldNumber = 17,
+    kActivateTriggersFieldNumber = 18,
+    kIncrementalStateConfigFieldNumber = 21,
+    kAllowUserBuildTracingFieldNumber = 19,
+    kUniqueSessionNameFieldNumber = 22,
+    kCompressionTypeFieldNumber = 24,
+    kCompressFromCliFieldNumber = 37,
+    kIncidentReportConfigFieldNumber = 25,
+    kStatsdLoggingFieldNumber = 31,
+    kTraceUuidMsbFieldNumber = 27,
+    kTraceUuidLsbFieldNumber = 28,
+    kTraceFilterFieldNumber = 33,
+    kAndroidReportConfigFieldNumber = 34,
+    kCmdTraceStartDelayFieldNumber = 35,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig"; }
+
+  using BufferConfig = ::perfetto::protos::pbzero::TraceConfig_BufferConfig;
+  using DataSource = ::perfetto::protos::pbzero::TraceConfig_DataSource;
+  using BuiltinDataSource = ::perfetto::protos::pbzero::TraceConfig_BuiltinDataSource;
+  using ProducerConfig = ::perfetto::protos::pbzero::TraceConfig_ProducerConfig;
+  using StatsdMetadata = ::perfetto::protos::pbzero::TraceConfig_StatsdMetadata;
+  using GuardrailOverrides = ::perfetto::protos::pbzero::TraceConfig_GuardrailOverrides;
+  using TriggerConfig = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig;
+  using IncrementalStateConfig = ::perfetto::protos::pbzero::TraceConfig_IncrementalStateConfig;
+  using IncidentReportConfig = ::perfetto::protos::pbzero::TraceConfig_IncidentReportConfig;
+  using TraceFilter = ::perfetto::protos::pbzero::TraceConfig_TraceFilter;
+  using AndroidReportConfig = ::perfetto::protos::pbzero::TraceConfig_AndroidReportConfig;
+  using CmdTraceStartDelay = ::perfetto::protos::pbzero::TraceConfig_CmdTraceStartDelay;
+
+  using LockdownModeOperation = ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation;
+  static inline const char* LockdownModeOperation_Name(LockdownModeOperation value) {
+    return ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation_Name(value);
+  }
+
+  using CompressionType = ::perfetto::protos::pbzero::TraceConfig_CompressionType;
+  static inline const char* CompressionType_Name(CompressionType value) {
+    return ::perfetto::protos::pbzero::TraceConfig_CompressionType_Name(value);
+  }
+
+  using StatsdLogging = ::perfetto::protos::pbzero::TraceConfig_StatsdLogging;
+  static inline const char* StatsdLogging_Name(StatsdLogging value) {
+    return ::perfetto::protos::pbzero::TraceConfig_StatsdLogging_Name(value);
+  }
+  static inline const LockdownModeOperation LOCKDOWN_UNCHANGED = LockdownModeOperation::LOCKDOWN_UNCHANGED;
+  static inline const LockdownModeOperation LOCKDOWN_CLEAR = LockdownModeOperation::LOCKDOWN_CLEAR;
+  static inline const LockdownModeOperation LOCKDOWN_SET = LockdownModeOperation::LOCKDOWN_SET;
+  static inline const CompressionType COMPRESSION_TYPE_UNSPECIFIED = CompressionType::COMPRESSION_TYPE_UNSPECIFIED;
+  static inline const CompressionType COMPRESSION_TYPE_DEFLATE = CompressionType::COMPRESSION_TYPE_DEFLATE;
+  static inline const StatsdLogging STATSD_LOGGING_UNSPECIFIED = StatsdLogging::STATSD_LOGGING_UNSPECIFIED;
+  static inline const StatsdLogging STATSD_LOGGING_ENABLED = StatsdLogging::STATSD_LOGGING_ENABLED;
+  static inline const StatsdLogging STATSD_LOGGING_DISABLED = StatsdLogging::STATSD_LOGGING_DISABLED;
+
+  using FieldMetadata_Buffers =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_BufferConfig,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_Buffers kBuffers{};
+  template <typename T = TraceConfig_BufferConfig> T* add_buffers() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_DataSources =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_DataSource,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_DataSources kDataSources{};
+  template <typename T = TraceConfig_DataSource> T* add_data_sources() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_BuiltinDataSources =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_BuiltinDataSource,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_BuiltinDataSources kBuiltinDataSources{};
+  template <typename T = TraceConfig_BuiltinDataSource> T* set_builtin_data_sources() {
+    return BeginNestedMessage<T>(20);
+  }
+
+
+  using FieldMetadata_DurationMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_DurationMs kDurationMs{};
+  void set_duration_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DurationMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PreferSuspendClockForDuration =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_PreferSuspendClockForDuration kPreferSuspendClockForDuration{};
+  void set_prefer_suspend_clock_for_duration(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreferSuspendClockForDuration::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnableExtraGuardrails =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_EnableExtraGuardrails kEnableExtraGuardrails{};
+  void set_enable_extra_guardrails(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnableExtraGuardrails::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LockdownMode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_LockdownMode kLockdownMode{};
+  void set_lockdown_mode(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value) {
+    static constexpr uint32_t field_id = FieldMetadata_LockdownMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Producers =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_ProducerConfig,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_Producers kProducers{};
+  template <typename T = TraceConfig_ProducerConfig> T* add_producers() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_StatsdMetadata =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_StatsdMetadata,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_StatsdMetadata kStatsdMetadata{};
+  template <typename T = TraceConfig_StatsdMetadata> T* set_statsd_metadata() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_WriteIntoFile =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_WriteIntoFile kWriteIntoFile{};
+  void set_write_into_file(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriteIntoFile::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OutputPath =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_OutputPath kOutputPath{};
+  void set_output_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_OutputPath::kFieldId, data, size);
+  }
+  void set_output_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_OutputPath::kFieldId, chars.data, chars.size);
+  }
+  void set_output_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_OutputPath::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FileWritePeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_FileWritePeriodMs kFileWritePeriodMs{};
+  void set_file_write_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FileWritePeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxFileSizeBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_MaxFileSizeBytes kMaxFileSizeBytes{};
+  void set_max_file_size_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxFileSizeBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GuardrailOverrides =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_GuardrailOverrides,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_GuardrailOverrides kGuardrailOverrides{};
+  template <typename T = TraceConfig_GuardrailOverrides> T* set_guardrail_overrides() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_DeferredStart =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_DeferredStart kDeferredStart{};
+  void set_deferred_start(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeferredStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FlushPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_FlushPeriodMs kFlushPeriodMs{};
+  void set_flush_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FlushTimeoutMs =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_FlushTimeoutMs kFlushTimeoutMs{};
+  void set_flush_timeout_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushTimeoutMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataSourceStopTimeoutMs =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_DataSourceStopTimeoutMs kDataSourceStopTimeoutMs{};
+  void set_data_source_stop_timeout_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSourceStopTimeoutMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NotifyTraceur =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_NotifyTraceur kNotifyTraceur{};
+  void set_notify_traceur(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NotifyTraceur::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BugreportScore =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_BugreportScore kBugreportScore{};
+  void set_bugreport_score(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BugreportScore::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TriggerConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TriggerConfig,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_TriggerConfig kTriggerConfig{};
+  template <typename T = TraceConfig_TriggerConfig> T* set_trigger_config() {
+    return BeginNestedMessage<T>(17);
+  }
+
+
+  using FieldMetadata_ActivateTriggers =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_ActivateTriggers kActivateTriggers{};
+  void add_activate_triggers(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ActivateTriggers::kFieldId, data, size);
+  }
+  void add_activate_triggers(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ActivateTriggers::kFieldId, chars.data, chars.size);
+  }
+  void add_activate_triggers(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActivateTriggers::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IncrementalStateConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_IncrementalStateConfig,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_IncrementalStateConfig kIncrementalStateConfig{};
+  template <typename T = TraceConfig_IncrementalStateConfig> T* set_incremental_state_config() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_AllowUserBuildTracing =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_AllowUserBuildTracing kAllowUserBuildTracing{};
+  void set_allow_user_build_tracing(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllowUserBuildTracing::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UniqueSessionName =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_UniqueSessionName kUniqueSessionName{};
+  void set_unique_session_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, data, size);
+  }
+  void set_unique_session_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, chars.data, chars.size);
+  }
+  void set_unique_session_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_UniqueSessionName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CompressionType =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TraceConfig_CompressionType,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_CompressionType kCompressionType{};
+  void set_compression_type(::perfetto::protos::pbzero::TraceConfig_CompressionType value) {
+    static constexpr uint32_t field_id = FieldMetadata_CompressionType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CompressFromCli =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_CompressFromCli kCompressFromCli{};
+  void set_compress_from_cli(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CompressFromCli::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IncidentReportConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_IncidentReportConfig,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_IncidentReportConfig kIncidentReportConfig{};
+  template <typename T = TraceConfig_IncidentReportConfig> T* set_incident_report_config() {
+    return BeginNestedMessage<T>(25);
+  }
+
+
+  using FieldMetadata_StatsdLogging =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TraceConfig_StatsdLogging,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_StatsdLogging kStatsdLogging{};
+  void set_statsd_logging(::perfetto::protos::pbzero::TraceConfig_StatsdLogging value) {
+    static constexpr uint32_t field_id = FieldMetadata_StatsdLogging::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceUuidMsb =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_TraceUuidMsb kTraceUuidMsb{};
+  void set_trace_uuid_msb(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceUuidMsb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceUuidLsb =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_TraceUuidLsb kTraceUuidLsb{};
+  void set_trace_uuid_lsb(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceUuidLsb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TraceFilter,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_TraceFilter kTraceFilter{};
+  template <typename T = TraceConfig_TraceFilter> T* set_trace_filter() {
+    return BeginNestedMessage<T>(33);
+  }
+
+
+  using FieldMetadata_AndroidReportConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_AndroidReportConfig,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_AndroidReportConfig kAndroidReportConfig{};
+  template <typename T = TraceConfig_AndroidReportConfig> T* set_android_report_config() {
+    return BeginNestedMessage<T>(34);
+  }
+
+
+  using FieldMetadata_CmdTraceStartDelay =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_CmdTraceStartDelay,
+      TraceConfig>;
+
+  static constexpr FieldMetadata_CmdTraceStartDelay kCmdTraceStartDelay{};
+  template <typename T = TraceConfig_CmdTraceStartDelay> T* set_cmd_trace_start_delay() {
+    return BeginNestedMessage<T>(35);
+  }
+
+};
+
+class TraceConfig_CmdTraceStartDelay_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_CmdTraceStartDelay_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_CmdTraceStartDelay_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_CmdTraceStartDelay_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_min_delay_ms() const { return at<1>().valid(); }
+  uint32_t min_delay_ms() const { return at<1>().as_uint32(); }
+  bool has_max_delay_ms() const { return at<2>().valid(); }
+  uint32_t max_delay_ms() const { return at<2>().as_uint32(); }
+};
+
+class TraceConfig_CmdTraceStartDelay : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_CmdTraceStartDelay_Decoder;
+  enum : int32_t {
+    kMinDelayMsFieldNumber = 1,
+    kMaxDelayMsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.CmdTraceStartDelay"; }
+
+
+  using FieldMetadata_MinDelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_CmdTraceStartDelay>;
+
+  static constexpr FieldMetadata_MinDelayMs kMinDelayMs{};
+  void set_min_delay_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinDelayMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxDelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_CmdTraceStartDelay>;
+
+  static constexpr FieldMetadata_MaxDelayMs kMaxDelayMs{};
+  void set_max_delay_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxDelayMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_AndroidReportConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_AndroidReportConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_AndroidReportConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_AndroidReportConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_reporter_service_package() const { return at<1>().valid(); }
+  ::protozero::ConstChars reporter_service_package() const { return at<1>().as_string(); }
+  bool has_reporter_service_class() const { return at<2>().valid(); }
+  ::protozero::ConstChars reporter_service_class() const { return at<2>().as_string(); }
+  bool has_skip_report() const { return at<3>().valid(); }
+  bool skip_report() const { return at<3>().as_bool(); }
+  bool has_use_pipe_in_framework_for_testing() const { return at<4>().valid(); }
+  bool use_pipe_in_framework_for_testing() const { return at<4>().as_bool(); }
+};
+
+class TraceConfig_AndroidReportConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_AndroidReportConfig_Decoder;
+  enum : int32_t {
+    kReporterServicePackageFieldNumber = 1,
+    kReporterServiceClassFieldNumber = 2,
+    kSkipReportFieldNumber = 3,
+    kUsePipeInFrameworkForTestingFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.AndroidReportConfig"; }
+
+
+  using FieldMetadata_ReporterServicePackage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_AndroidReportConfig>;
+
+  static constexpr FieldMetadata_ReporterServicePackage kReporterServicePackage{};
+  void set_reporter_service_package(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ReporterServicePackage::kFieldId, data, size);
+  }
+  void set_reporter_service_package(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ReporterServicePackage::kFieldId, chars.data, chars.size);
+  }
+  void set_reporter_service_package(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReporterServicePackage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReporterServiceClass =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_AndroidReportConfig>;
+
+  static constexpr FieldMetadata_ReporterServiceClass kReporterServiceClass{};
+  void set_reporter_service_class(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ReporterServiceClass::kFieldId, data, size);
+  }
+  void set_reporter_service_class(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ReporterServiceClass::kFieldId, chars.data, chars.size);
+  }
+  void set_reporter_service_class(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReporterServiceClass::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SkipReport =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_AndroidReportConfig>;
+
+  static constexpr FieldMetadata_SkipReport kSkipReport{};
+  void set_skip_report(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkipReport::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UsePipeInFrameworkForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_AndroidReportConfig>;
+
+  static constexpr FieldMetadata_UsePipeInFrameworkForTesting kUsePipeInFrameworkForTesting{};
+  void set_use_pipe_in_framework_for_testing(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_UsePipeInFrameworkForTesting::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_TraceFilter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_TraceFilter_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_TraceFilter_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_TraceFilter_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytecode() const { return at<1>().valid(); }
+  ::protozero::ConstBytes bytecode() const { return at<1>().as_bytes(); }
+  bool has_bytecode_v2() const { return at<2>().valid(); }
+  ::protozero::ConstBytes bytecode_v2() const { return at<2>().as_bytes(); }
+  bool has_string_filter_chain() const { return at<3>().valid(); }
+  ::protozero::ConstBytes string_filter_chain() const { return at<3>().as_bytes(); }
+};
+
+class TraceConfig_TraceFilter : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_TraceFilter_Decoder;
+  enum : int32_t {
+    kBytecodeFieldNumber = 1,
+    kBytecodeV2FieldNumber = 2,
+    kStringFilterChainFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.TraceFilter"; }
+
+  using StringFilterRule = ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterRule;
+  using StringFilterChain = ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterChain;
+
+  using StringFilterPolicy = ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy;
+  static inline const char* StringFilterPolicy_Name(StringFilterPolicy value) {
+    return ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy_Name(value);
+  }
+  static inline const StringFilterPolicy SFP_UNSPECIFIED = StringFilterPolicy::SFP_UNSPECIFIED;
+  static inline const StringFilterPolicy SFP_MATCH_REDACT_GROUPS = StringFilterPolicy::SFP_MATCH_REDACT_GROUPS;
+  static inline const StringFilterPolicy SFP_ATRACE_MATCH_REDACT_GROUPS = StringFilterPolicy::SFP_ATRACE_MATCH_REDACT_GROUPS;
+  static inline const StringFilterPolicy SFP_MATCH_BREAK = StringFilterPolicy::SFP_MATCH_BREAK;
+  static inline const StringFilterPolicy SFP_ATRACE_MATCH_BREAK = StringFilterPolicy::SFP_ATRACE_MATCH_BREAK;
+  static inline const StringFilterPolicy SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS = StringFilterPolicy::SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS;
+
+  using FieldMetadata_Bytecode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TraceConfig_TraceFilter>;
+
+  static constexpr FieldMetadata_Bytecode kBytecode{};
+  void set_bytecode(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Bytecode::kFieldId, data, size);
+  }
+  void set_bytecode(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Bytecode::kFieldId, bytes.data, bytes.size);
+  }
+  void set_bytecode(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytecode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BytecodeV2 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      TraceConfig_TraceFilter>;
+
+  static constexpr FieldMetadata_BytecodeV2 kBytecodeV2{};
+  void set_bytecode_v2(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_BytecodeV2::kFieldId, data, size);
+  }
+  void set_bytecode_v2(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_BytecodeV2::kFieldId, bytes.data, bytes.size);
+  }
+  void set_bytecode_v2(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytecodeV2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringFilterChain =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TraceFilter_StringFilterChain,
+      TraceConfig_TraceFilter>;
+
+  static constexpr FieldMetadata_StringFilterChain kStringFilterChain{};
+  template <typename T = TraceConfig_TraceFilter_StringFilterChain> T* set_string_filter_chain() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class TraceConfig_TraceFilter_StringFilterChain_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TraceConfig_TraceFilter_StringFilterChain_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_TraceFilter_StringFilterChain_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_TraceFilter_StringFilterChain_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rules() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> rules() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class TraceConfig_TraceFilter_StringFilterChain : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_TraceFilter_StringFilterChain_Decoder;
+  enum : int32_t {
+    kRulesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.TraceFilter.StringFilterChain"; }
+
+
+  using FieldMetadata_Rules =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TraceFilter_StringFilterRule,
+      TraceConfig_TraceFilter_StringFilterChain>;
+
+  static constexpr FieldMetadata_Rules kRules{};
+  template <typename T = TraceConfig_TraceFilter_StringFilterRule> T* add_rules() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class TraceConfig_TraceFilter_StringFilterRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_TraceFilter_StringFilterRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_TraceFilter_StringFilterRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_TraceFilter_StringFilterRule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_policy() const { return at<1>().valid(); }
+  int32_t policy() const { return at<1>().as_int32(); }
+  bool has_regex_pattern() const { return at<2>().valid(); }
+  ::protozero::ConstChars regex_pattern() const { return at<2>().as_string(); }
+  bool has_atrace_payload_starts_with() const { return at<3>().valid(); }
+  ::protozero::ConstChars atrace_payload_starts_with() const { return at<3>().as_string(); }
+};
+
+class TraceConfig_TraceFilter_StringFilterRule : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_TraceFilter_StringFilterRule_Decoder;
+  enum : int32_t {
+    kPolicyFieldNumber = 1,
+    kRegexPatternFieldNumber = 2,
+    kAtracePayloadStartsWithFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.TraceFilter.StringFilterRule"; }
+
+
+  using FieldMetadata_Policy =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy,
+      TraceConfig_TraceFilter_StringFilterRule>;
+
+  static constexpr FieldMetadata_Policy kPolicy{};
+  void set_policy(::perfetto::protos::pbzero::TraceConfig_TraceFilter_StringFilterPolicy value) {
+    static constexpr uint32_t field_id = FieldMetadata_Policy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RegexPattern =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_TraceFilter_StringFilterRule>;
+
+  static constexpr FieldMetadata_RegexPattern kRegexPattern{};
+  void set_regex_pattern(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_RegexPattern::kFieldId, data, size);
+  }
+  void set_regex_pattern(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_RegexPattern::kFieldId, chars.data, chars.size);
+  }
+  void set_regex_pattern(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_RegexPattern::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AtracePayloadStartsWith =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_TraceFilter_StringFilterRule>;
+
+  static constexpr FieldMetadata_AtracePayloadStartsWith kAtracePayloadStartsWith{};
+  void set_atrace_payload_starts_with(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AtracePayloadStartsWith::kFieldId, data, size);
+  }
+  void set_atrace_payload_starts_with(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AtracePayloadStartsWith::kFieldId, chars.data, chars.size);
+  }
+  void set_atrace_payload_starts_with(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AtracePayloadStartsWith::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_IncidentReportConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_IncidentReportConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_IncidentReportConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_IncidentReportConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_destination_package() const { return at<1>().valid(); }
+  ::protozero::ConstChars destination_package() const { return at<1>().as_string(); }
+  bool has_destination_class() const { return at<2>().valid(); }
+  ::protozero::ConstChars destination_class() const { return at<2>().as_string(); }
+  bool has_privacy_level() const { return at<3>().valid(); }
+  int32_t privacy_level() const { return at<3>().as_int32(); }
+  bool has_skip_incidentd() const { return at<5>().valid(); }
+  bool skip_incidentd() const { return at<5>().as_bool(); }
+  bool has_skip_dropbox() const { return at<4>().valid(); }
+  bool skip_dropbox() const { return at<4>().as_bool(); }
+};
+
+class TraceConfig_IncidentReportConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_IncidentReportConfig_Decoder;
+  enum : int32_t {
+    kDestinationPackageFieldNumber = 1,
+    kDestinationClassFieldNumber = 2,
+    kPrivacyLevelFieldNumber = 3,
+    kSkipIncidentdFieldNumber = 5,
+    kSkipDropboxFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.IncidentReportConfig"; }
+
+
+  using FieldMetadata_DestinationPackage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_IncidentReportConfig>;
+
+  static constexpr FieldMetadata_DestinationPackage kDestinationPackage{};
+  void set_destination_package(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DestinationPackage::kFieldId, data, size);
+  }
+  void set_destination_package(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DestinationPackage::kFieldId, chars.data, chars.size);
+  }
+  void set_destination_package(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DestinationPackage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DestinationClass =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_IncidentReportConfig>;
+
+  static constexpr FieldMetadata_DestinationClass kDestinationClass{};
+  void set_destination_class(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DestinationClass::kFieldId, data, size);
+  }
+  void set_destination_class(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DestinationClass::kFieldId, chars.data, chars.size);
+  }
+  void set_destination_class(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DestinationClass::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrivacyLevel =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TraceConfig_IncidentReportConfig>;
+
+  static constexpr FieldMetadata_PrivacyLevel kPrivacyLevel{};
+  void set_privacy_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrivacyLevel::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SkipIncidentd =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_IncidentReportConfig>;
+
+  static constexpr FieldMetadata_SkipIncidentd kSkipIncidentd{};
+  void set_skip_incidentd(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkipIncidentd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SkipDropbox =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_IncidentReportConfig>;
+
+  static constexpr FieldMetadata_SkipDropbox kSkipDropbox{};
+  void set_skip_dropbox(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkipDropbox::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_IncrementalStateConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_IncrementalStateConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_IncrementalStateConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_IncrementalStateConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_clear_period_ms() const { return at<1>().valid(); }
+  uint32_t clear_period_ms() const { return at<1>().as_uint32(); }
+};
+
+class TraceConfig_IncrementalStateConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_IncrementalStateConfig_Decoder;
+  enum : int32_t {
+    kClearPeriodMsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.IncrementalStateConfig"; }
+
+
+  using FieldMetadata_ClearPeriodMs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_IncrementalStateConfig>;
+
+  static constexpr FieldMetadata_ClearPeriodMs kClearPeriodMs{};
+  void set_clear_period_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClearPeriodMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_TriggerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TraceConfig_TriggerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_TriggerConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_TriggerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trigger_mode() const { return at<1>().valid(); }
+  int32_t trigger_mode() const { return at<1>().as_int32(); }
+  bool has_use_clone_snapshot_if_available() const { return at<5>().valid(); }
+  bool use_clone_snapshot_if_available() const { return at<5>().as_bool(); }
+  bool has_triggers() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> triggers() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_trigger_timeout_ms() const { return at<3>().valid(); }
+  uint32_t trigger_timeout_ms() const { return at<3>().as_uint32(); }
+};
+
+class TraceConfig_TriggerConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_TriggerConfig_Decoder;
+  enum : int32_t {
+    kTriggerModeFieldNumber = 1,
+    kUseCloneSnapshotIfAvailableFieldNumber = 5,
+    kTriggersFieldNumber = 2,
+    kTriggerTimeoutMsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.TriggerConfig"; }
+
+  using Trigger = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_Trigger;
+
+  using TriggerMode = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode;
+  static inline const char* TriggerMode_Name(TriggerMode value) {
+    return ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode_Name(value);
+  }
+  static inline const TriggerMode UNSPECIFIED = TriggerMode::UNSPECIFIED;
+  static inline const TriggerMode START_TRACING = TriggerMode::START_TRACING;
+  static inline const TriggerMode STOP_TRACING = TriggerMode::STOP_TRACING;
+  static inline const TriggerMode CLONE_SNAPSHOT = TriggerMode::CLONE_SNAPSHOT;
+
+  using FieldMetadata_TriggerMode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode,
+      TraceConfig_TriggerConfig>;
+
+  static constexpr FieldMetadata_TriggerMode kTriggerMode{};
+  void set_trigger_mode(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggerMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UseCloneSnapshotIfAvailable =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_TriggerConfig>;
+
+  static constexpr FieldMetadata_UseCloneSnapshotIfAvailable kUseCloneSnapshotIfAvailable{};
+  void set_use_clone_snapshot_if_available(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_UseCloneSnapshotIfAvailable::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Triggers =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TraceConfig_TriggerConfig_Trigger,
+      TraceConfig_TriggerConfig>;
+
+  static constexpr FieldMetadata_Triggers kTriggers{};
+  template <typename T = TraceConfig_TriggerConfig_Trigger> T* add_triggers() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_TriggerTimeoutMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_TriggerConfig>;
+
+  static constexpr FieldMetadata_TriggerTimeoutMs kTriggerTimeoutMs{};
+  void set_trigger_timeout_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggerTimeoutMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_TriggerConfig_Trigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_TriggerConfig_Trigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_TriggerConfig_Trigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_TriggerConfig_Trigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_producer_name_regex() const { return at<2>().valid(); }
+  ::protozero::ConstChars producer_name_regex() const { return at<2>().as_string(); }
+  bool has_stop_delay_ms() const { return at<3>().valid(); }
+  uint32_t stop_delay_ms() const { return at<3>().as_uint32(); }
+  bool has_max_per_24_h() const { return at<4>().valid(); }
+  uint32_t max_per_24_h() const { return at<4>().as_uint32(); }
+  bool has_skip_probability() const { return at<5>().valid(); }
+  double skip_probability() const { return at<5>().as_double(); }
+};
+
+class TraceConfig_TriggerConfig_Trigger : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_TriggerConfig_Trigger_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kProducerNameRegexFieldNumber = 2,
+    kStopDelayMsFieldNumber = 3,
+    kMaxPer24HFieldNumber = 4,
+    kSkipProbabilityFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.TriggerConfig.Trigger"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_TriggerConfig_Trigger>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProducerNameRegex =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_TriggerConfig_Trigger>;
+
+  static constexpr FieldMetadata_ProducerNameRegex kProducerNameRegex{};
+  void set_producer_name_regex(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameRegex::kFieldId, data, size);
+  }
+  void set_producer_name_regex(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerNameRegex::kFieldId, chars.data, chars.size);
+  }
+  void set_producer_name_regex(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducerNameRegex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StopDelayMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_TriggerConfig_Trigger>;
+
+  static constexpr FieldMetadata_StopDelayMs kStopDelayMs{};
+  void set_stop_delay_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StopDelayMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxPer24H =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_TriggerConfig_Trigger>;
+
+  static constexpr FieldMetadata_MaxPer24H kMaxPer24H{};
+  void set_max_per_24_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxPer24H::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SkipProbability =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      TraceConfig_TriggerConfig_Trigger>;
+
+  static constexpr FieldMetadata_SkipProbability kSkipProbability{};
+  void set_skip_probability(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkipProbability::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_GuardrailOverrides_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_GuardrailOverrides_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_GuardrailOverrides_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_GuardrailOverrides_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_max_upload_per_day_bytes() const { return at<1>().valid(); }
+  uint64_t max_upload_per_day_bytes() const { return at<1>().as_uint64(); }
+  bool has_max_tracing_buffer_size_kb() const { return at<2>().valid(); }
+  uint32_t max_tracing_buffer_size_kb() const { return at<2>().as_uint32(); }
+};
+
+class TraceConfig_GuardrailOverrides : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_GuardrailOverrides_Decoder;
+  enum : int32_t {
+    kMaxUploadPerDayBytesFieldNumber = 1,
+    kMaxTracingBufferSizeKbFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.GuardrailOverrides"; }
+
+
+  using FieldMetadata_MaxUploadPerDayBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TraceConfig_GuardrailOverrides>;
+
+  static constexpr FieldMetadata_MaxUploadPerDayBytes kMaxUploadPerDayBytes{};
+  void set_max_upload_per_day_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxUploadPerDayBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxTracingBufferSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_GuardrailOverrides>;
+
+  static constexpr FieldMetadata_MaxTracingBufferSizeKb kMaxTracingBufferSizeKb{};
+  void set_max_tracing_buffer_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxTracingBufferSizeKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_StatsdMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_StatsdMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_StatsdMetadata_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_StatsdMetadata_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_triggering_alert_id() const { return at<1>().valid(); }
+  int64_t triggering_alert_id() const { return at<1>().as_int64(); }
+  bool has_triggering_config_uid() const { return at<2>().valid(); }
+  int32_t triggering_config_uid() const { return at<2>().as_int32(); }
+  bool has_triggering_config_id() const { return at<3>().valid(); }
+  int64_t triggering_config_id() const { return at<3>().as_int64(); }
+  bool has_triggering_subscription_id() const { return at<4>().valid(); }
+  int64_t triggering_subscription_id() const { return at<4>().as_int64(); }
+};
+
+class TraceConfig_StatsdMetadata : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_StatsdMetadata_Decoder;
+  enum : int32_t {
+    kTriggeringAlertIdFieldNumber = 1,
+    kTriggeringConfigUidFieldNumber = 2,
+    kTriggeringConfigIdFieldNumber = 3,
+    kTriggeringSubscriptionIdFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.StatsdMetadata"; }
+
+
+  using FieldMetadata_TriggeringAlertId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceConfig_StatsdMetadata>;
+
+  static constexpr FieldMetadata_TriggeringAlertId kTriggeringAlertId{};
+  void set_triggering_alert_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggeringAlertId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TriggeringConfigUid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TraceConfig_StatsdMetadata>;
+
+  static constexpr FieldMetadata_TriggeringConfigUid kTriggeringConfigUid{};
+  void set_triggering_config_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggeringConfigUid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TriggeringConfigId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceConfig_StatsdMetadata>;
+
+  static constexpr FieldMetadata_TriggeringConfigId kTriggeringConfigId{};
+  void set_triggering_config_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggeringConfigId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TriggeringSubscriptionId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceConfig_StatsdMetadata>;
+
+  static constexpr FieldMetadata_TriggeringSubscriptionId kTriggeringSubscriptionId{};
+  void set_triggering_subscription_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggeringSubscriptionId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_ProducerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_ProducerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_ProducerConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_ProducerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_producer_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars producer_name() const { return at<1>().as_string(); }
+  bool has_shm_size_kb() const { return at<2>().valid(); }
+  uint32_t shm_size_kb() const { return at<2>().as_uint32(); }
+  bool has_page_size_kb() const { return at<3>().valid(); }
+  uint32_t page_size_kb() const { return at<3>().as_uint32(); }
+};
+
+class TraceConfig_ProducerConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_ProducerConfig_Decoder;
+  enum : int32_t {
+    kProducerNameFieldNumber = 1,
+    kShmSizeKbFieldNumber = 2,
+    kPageSizeKbFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.ProducerConfig"; }
+
+
+  using FieldMetadata_ProducerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_ProducerConfig>;
+
+  static constexpr FieldMetadata_ProducerName kProducerName{};
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
+  }
+  void set_producer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, chars.data, chars.size);
+  }
+  void set_producer_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducerName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ShmSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_ProducerConfig>;
+
+  static constexpr FieldMetadata_ShmSizeKb kShmSizeKb{};
+  void set_shm_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmSizeKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PageSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_ProducerConfig>;
+
+  static constexpr FieldMetadata_PageSizeKb kPageSizeKb{};
+  void set_page_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PageSizeKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_BuiltinDataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_BuiltinDataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_BuiltinDataSource_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_BuiltinDataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_disable_clock_snapshotting() const { return at<1>().valid(); }
+  bool disable_clock_snapshotting() const { return at<1>().as_bool(); }
+  bool has_disable_trace_config() const { return at<2>().valid(); }
+  bool disable_trace_config() const { return at<2>().as_bool(); }
+  bool has_disable_system_info() const { return at<3>().valid(); }
+  bool disable_system_info() const { return at<3>().as_bool(); }
+  bool has_disable_service_events() const { return at<4>().valid(); }
+  bool disable_service_events() const { return at<4>().as_bool(); }
+  bool has_primary_trace_clock() const { return at<5>().valid(); }
+  int32_t primary_trace_clock() const { return at<5>().as_int32(); }
+  bool has_snapshot_interval_ms() const { return at<6>().valid(); }
+  uint32_t snapshot_interval_ms() const { return at<6>().as_uint32(); }
+  bool has_prefer_suspend_clock_for_snapshot() const { return at<7>().valid(); }
+  bool prefer_suspend_clock_for_snapshot() const { return at<7>().as_bool(); }
+  bool has_disable_chunk_usage_histograms() const { return at<8>().valid(); }
+  bool disable_chunk_usage_histograms() const { return at<8>().as_bool(); }
+};
+
+class TraceConfig_BuiltinDataSource : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_BuiltinDataSource_Decoder;
+  enum : int32_t {
+    kDisableClockSnapshottingFieldNumber = 1,
+    kDisableTraceConfigFieldNumber = 2,
+    kDisableSystemInfoFieldNumber = 3,
+    kDisableServiceEventsFieldNumber = 4,
+    kPrimaryTraceClockFieldNumber = 5,
+    kSnapshotIntervalMsFieldNumber = 6,
+    kPreferSuspendClockForSnapshotFieldNumber = 7,
+    kDisableChunkUsageHistogramsFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.BuiltinDataSource"; }
+
+
+  using FieldMetadata_DisableClockSnapshotting =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_DisableClockSnapshotting kDisableClockSnapshotting{};
+  void set_disable_clock_snapshotting(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableClockSnapshotting::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisableTraceConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_DisableTraceConfig kDisableTraceConfig{};
+  void set_disable_trace_config(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableTraceConfig::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisableSystemInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_DisableSystemInfo kDisableSystemInfo{};
+  void set_disable_system_info(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableSystemInfo::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisableServiceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_DisableServiceEvents kDisableServiceEvents{};
+  void set_disable_service_events(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableServiceEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrimaryTraceClock =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::BuiltinClock,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock{};
+  void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrimaryTraceClock::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SnapshotIntervalMs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_SnapshotIntervalMs kSnapshotIntervalMs{};
+  void set_snapshot_interval_ms(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SnapshotIntervalMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PreferSuspendClockForSnapshot =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_PreferSuspendClockForSnapshot kPreferSuspendClockForSnapshot{};
+  void set_prefer_suspend_clock_for_snapshot(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreferSuspendClockForSnapshot::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisableChunkUsageHistograms =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BuiltinDataSource>;
+
+  static constexpr FieldMetadata_DisableChunkUsageHistograms kDisableChunkUsageHistograms{};
+  void set_disable_chunk_usage_histograms(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisableChunkUsageHistograms::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_DataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TraceConfig_DataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_DataSource_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_DataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_config() const { return at<1>().valid(); }
+  ::protozero::ConstBytes config() const { return at<1>().as_bytes(); }
+  bool has_producer_name_filter() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> producer_name_filter() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_producer_name_regex_filter() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> producer_name_regex_filter() const { return GetRepeated<::protozero::ConstChars>(3); }
+};
+
+class TraceConfig_DataSource : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_DataSource_Decoder;
+  enum : int32_t {
+    kConfigFieldNumber = 1,
+    kProducerNameFilterFieldNumber = 2,
+    kProducerNameRegexFilterFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.DataSource"; }
+
+
+  using FieldMetadata_Config =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DataSourceConfig,
+      TraceConfig_DataSource>;
+
+  static constexpr FieldMetadata_Config kConfig{};
+  template <typename T = DataSourceConfig> T* set_config() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ProducerNameFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_DataSource>;
+
+  static constexpr FieldMetadata_ProducerNameFilter kProducerNameFilter{};
+  void add_producer_name_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameFilter::kFieldId, data, size);
+  }
+  void add_producer_name_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerNameFilter::kFieldId, chars.data, chars.size);
+  }
+  void add_producer_name_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducerNameFilter::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProducerNameRegexFilter =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TraceConfig_DataSource>;
+
+  static constexpr FieldMetadata_ProducerNameRegexFilter kProducerNameRegexFilter{};
+  void add_producer_name_regex_filter(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerNameRegexFilter::kFieldId, data, size);
+  }
+  void add_producer_name_regex_filter(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerNameRegexFilter::kFieldId, chars.data, chars.size);
+  }
+  void add_producer_name_regex_filter(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducerNameRegexFilter::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TraceConfig_BufferConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceConfig_BufferConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceConfig_BufferConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceConfig_BufferConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_size_kb() const { return at<1>().valid(); }
+  uint32_t size_kb() const { return at<1>().as_uint32(); }
+  bool has_fill_policy() const { return at<4>().valid(); }
+  int32_t fill_policy() const { return at<4>().as_int32(); }
+  bool has_transfer_on_clone() const { return at<5>().valid(); }
+  bool transfer_on_clone() const { return at<5>().as_bool(); }
+  bool has_clear_before_clone() const { return at<6>().valid(); }
+  bool clear_before_clone() const { return at<6>().as_bool(); }
+};
+
+class TraceConfig_BufferConfig : public ::protozero::Message {
+ public:
+  using Decoder = TraceConfig_BufferConfig_Decoder;
+  enum : int32_t {
+    kSizeKbFieldNumber = 1,
+    kFillPolicyFieldNumber = 4,
+    kTransferOnCloneFieldNumber = 5,
+    kClearBeforeCloneFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceConfig.BufferConfig"; }
+
+
+  using FillPolicy = ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy;
+  static inline const char* FillPolicy_Name(FillPolicy value) {
+    return ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy_Name(value);
+  }
+  static inline const FillPolicy UNSPECIFIED = FillPolicy::UNSPECIFIED;
+  static inline const FillPolicy RING_BUFFER = FillPolicy::RING_BUFFER;
+  static inline const FillPolicy DISCARD = FillPolicy::DISCARD;
+
+  using FieldMetadata_SizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TraceConfig_BufferConfig>;
+
+  static constexpr FieldMetadata_SizeKb kSizeKb{};
+  void set_size_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SizeKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FillPolicy =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy,
+      TraceConfig_BufferConfig>;
+
+  static constexpr FieldMetadata_FillPolicy kFillPolicy{};
+  void set_fill_policy(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value) {
+    static constexpr uint32_t field_id = FieldMetadata_FillPolicy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TransferOnClone =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BufferConfig>;
+
+  static constexpr FieldMetadata_TransferOnClone kTransferOnClone{};
+  void set_transfer_on_clone(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TransferOnClone::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ClearBeforeClone =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TraceConfig_BufferConfig>;
+
+  static constexpr FieldMetadata_ClearBeforeClone kClearBeforeClone{};
+  void set_clear_before_clone(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClearBeforeClone::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/clock_snapshot.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CLOCK_SNAPSHOT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CLOCK_SNAPSHOT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ClockSnapshot_Clock;
+enum BuiltinClock : int32_t;
+
+namespace perfetto_pbzero_enum_ClockSnapshot_Clock {
+enum BuiltinClocks : int32_t {
+  UNKNOWN = 0,
+  REALTIME = 1,
+  REALTIME_COARSE = 2,
+  MONOTONIC = 3,
+  MONOTONIC_COARSE = 4,
+  MONOTONIC_RAW = 5,
+  BOOTTIME = 6,
+  BUILTIN_CLOCK_MAX_ID = 63,
+};
+} // namespace perfetto_pbzero_enum_ClockSnapshot_Clock
+using ClockSnapshot_Clock_BuiltinClocks = perfetto_pbzero_enum_ClockSnapshot_Clock::BuiltinClocks;
+
+
+constexpr ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MIN = ClockSnapshot_Clock_BuiltinClocks::UNKNOWN;
+constexpr ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MAX = ClockSnapshot_Clock_BuiltinClocks::BUILTIN_CLOCK_MAX_ID;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ClockSnapshot_Clock_BuiltinClocks_Name(::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::UNKNOWN:
+    return "UNKNOWN";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::REALTIME:
+    return "REALTIME";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::REALTIME_COARSE:
+    return "REALTIME_COARSE";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::MONOTONIC:
+    return "MONOTONIC";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::MONOTONIC_COARSE:
+    return "MONOTONIC_COARSE";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::MONOTONIC_RAW:
+    return "MONOTONIC_RAW";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::BOOTTIME:
+    return "BOOTTIME";
+
+  case ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks::BUILTIN_CLOCK_MAX_ID:
+    return "BUILTIN_CLOCK_MAX_ID";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ClockSnapshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ClockSnapshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClockSnapshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClockSnapshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_clocks() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> clocks() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_primary_trace_clock() const { return at<2>().valid(); }
+  int32_t primary_trace_clock() const { return at<2>().as_int32(); }
+};
+
+class ClockSnapshot : public ::protozero::Message {
+ public:
+  using Decoder = ClockSnapshot_Decoder;
+  enum : int32_t {
+    kClocksFieldNumber = 1,
+    kPrimaryTraceClockFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClockSnapshot"; }
+
+  using Clock = ::perfetto::protos::pbzero::ClockSnapshot_Clock;
+
+  using FieldMetadata_Clocks =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockSnapshot_Clock,
+      ClockSnapshot>;
+
+  static constexpr FieldMetadata_Clocks kClocks{};
+  template <typename T = ClockSnapshot_Clock> T* add_clocks() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_PrimaryTraceClock =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::BuiltinClock,
+      ClockSnapshot>;
+
+  static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock{};
+  void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrimaryTraceClock::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ClockSnapshot_Clock_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClockSnapshot_Clock_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClockSnapshot_Clock_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClockSnapshot_Clock_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_clock_id() const { return at<1>().valid(); }
+  uint32_t clock_id() const { return at<1>().as_uint32(); }
+  bool has_timestamp() const { return at<2>().valid(); }
+  uint64_t timestamp() const { return at<2>().as_uint64(); }
+  bool has_is_incremental() const { return at<3>().valid(); }
+  bool is_incremental() const { return at<3>().as_bool(); }
+  bool has_unit_multiplier_ns() const { return at<4>().valid(); }
+  uint64_t unit_multiplier_ns() const { return at<4>().as_uint64(); }
+};
+
+class ClockSnapshot_Clock : public ::protozero::Message {
+ public:
+  using Decoder = ClockSnapshot_Clock_Decoder;
+  enum : int32_t {
+    kClockIdFieldNumber = 1,
+    kTimestampFieldNumber = 2,
+    kIsIncrementalFieldNumber = 3,
+    kUnitMultiplierNsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClockSnapshot.Clock"; }
+
+
+  using BuiltinClocks = ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks;
+  static inline const char* BuiltinClocks_Name(BuiltinClocks value) {
+    return ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks_Name(value);
+  }
+  static inline const BuiltinClocks UNKNOWN = BuiltinClocks::UNKNOWN;
+  static inline const BuiltinClocks REALTIME = BuiltinClocks::REALTIME;
+  static inline const BuiltinClocks REALTIME_COARSE = BuiltinClocks::REALTIME_COARSE;
+  static inline const BuiltinClocks MONOTONIC = BuiltinClocks::MONOTONIC;
+  static inline const BuiltinClocks MONOTONIC_COARSE = BuiltinClocks::MONOTONIC_COARSE;
+  static inline const BuiltinClocks MONOTONIC_RAW = BuiltinClocks::MONOTONIC_RAW;
+  static inline const BuiltinClocks BOOTTIME = BuiltinClocks::BOOTTIME;
+  static inline const BuiltinClocks BUILTIN_CLOCK_MAX_ID = BuiltinClocks::BUILTIN_CLOCK_MAX_ID;
+
+  using FieldMetadata_ClockId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ClockSnapshot_Clock>;
+
+  static constexpr FieldMetadata_ClockId kClockId{};
+  void set_clock_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClockId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockSnapshot_Clock>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsIncremental =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ClockSnapshot_Clock>;
+
+  static constexpr FieldMetadata_IsIncremental kIsIncremental{};
+  void set_is_incremental(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsIncremental::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UnitMultiplierNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockSnapshot_Clock>;
+
+  static constexpr FieldMetadata_UnitMultiplierNs kUnitMultiplierNs{};
+  void set_unit_multiplier_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnitMultiplierNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/trace_uuid.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_UUID_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_UUID_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class TraceUuid_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TraceUuid_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TraceUuid_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TraceUuid_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_msb() const { return at<1>().valid(); }
+  int64_t msb() const { return at<1>().as_int64(); }
+  bool has_lsb() const { return at<2>().valid(); }
+  int64_t lsb() const { return at<2>().as_int64(); }
+};
+
+class TraceUuid : public ::protozero::Message {
+ public:
+  using Decoder = TraceUuid_Decoder;
+  enum : int32_t {
+    kMsbFieldNumber = 1,
+    kLsbFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TraceUuid"; }
+
+
+  using FieldMetadata_Msb =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceUuid>;
+
+  static constexpr FieldMetadata_Msb kMsb{};
+  void set_msb(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Msb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lsb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TraceUuid>;
+
+  static constexpr FieldMetadata_Lsb kLsb{};
+  void set_lsb(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lsb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/trigger.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRIGGER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRIGGER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class Trigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Trigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Trigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Trigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trigger_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars trigger_name() const { return at<1>().as_string(); }
+  bool has_producer_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars producer_name() const { return at<2>().as_string(); }
+  bool has_trusted_producer_uid() const { return at<3>().valid(); }
+  int32_t trusted_producer_uid() const { return at<3>().as_int32(); }
+};
+
+class Trigger : public ::protozero::Message {
+ public:
+  using Decoder = Trigger_Decoder;
+  enum : int32_t {
+    kTriggerNameFieldNumber = 1,
+    kProducerNameFieldNumber = 2,
+    kTrustedProducerUidFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Trigger"; }
+
+
+  using FieldMetadata_TriggerName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Trigger>;
+
+  static constexpr FieldMetadata_TriggerName kTriggerName{};
+  void set_trigger_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TriggerName::kFieldId, data, size);
+  }
+  void set_trigger_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TriggerName::kFieldId, chars.data, chars.size);
+  }
+  void set_trigger_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggerName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProducerName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Trigger>;
+
+  static constexpr FieldMetadata_ProducerName kProducerName{};
+  void set_producer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
+  }
+  void set_producer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProducerName::kFieldId, chars.data, chars.size);
+  }
+  void set_producer_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProducerName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TrustedProducerUid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Trigger>;
+
+  static constexpr FieldMetadata_TrustedProducerUid kTrustedProducerUid{};
+  void set_trusted_producer_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TrustedProducerUid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/system_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class Utsname;
+
+class SystemInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SystemInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SystemInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SystemInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_utsname() const { return at<1>().valid(); }
+  ::protozero::ConstBytes utsname() const { return at<1>().as_bytes(); }
+  bool has_android_build_fingerprint() const { return at<2>().valid(); }
+  ::protozero::ConstChars android_build_fingerprint() const { return at<2>().as_string(); }
+  bool has_hz() const { return at<3>().valid(); }
+  int64_t hz() const { return at<3>().as_int64(); }
+  bool has_tracing_service_version() const { return at<4>().valid(); }
+  ::protozero::ConstChars tracing_service_version() const { return at<4>().as_string(); }
+  bool has_android_sdk_version() const { return at<5>().valid(); }
+  uint64_t android_sdk_version() const { return at<5>().as_uint64(); }
+  bool has_page_size() const { return at<6>().valid(); }
+  uint32_t page_size() const { return at<6>().as_uint32(); }
+  bool has_timezone_off_mins() const { return at<7>().valid(); }
+  int32_t timezone_off_mins() const { return at<7>().as_int32(); }
+};
+
+class SystemInfo : public ::protozero::Message {
+ public:
+  using Decoder = SystemInfo_Decoder;
+  enum : int32_t {
+    kUtsnameFieldNumber = 1,
+    kAndroidBuildFingerprintFieldNumber = 2,
+    kHzFieldNumber = 3,
+    kTracingServiceVersionFieldNumber = 4,
+    kAndroidSdkVersionFieldNumber = 5,
+    kPageSizeFieldNumber = 6,
+    kTimezoneOffMinsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SystemInfo"; }
+
+
+  using FieldMetadata_Utsname =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Utsname,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_Utsname kUtsname{};
+  template <typename T = Utsname> T* set_utsname() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_AndroidBuildFingerprint =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_AndroidBuildFingerprint kAndroidBuildFingerprint{};
+  void set_android_build_fingerprint(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AndroidBuildFingerprint::kFieldId, data, size);
+  }
+  void set_android_build_fingerprint(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AndroidBuildFingerprint::kFieldId, chars.data, chars.size);
+  }
+  void set_android_build_fingerprint(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AndroidBuildFingerprint::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Hz =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_Hz kHz{};
+  void set_hz(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hz::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TracingServiceVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_TracingServiceVersion kTracingServiceVersion{};
+  void set_tracing_service_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, data, size);
+  }
+  void set_tracing_service_version(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, chars.data, chars.size);
+  }
+  void set_tracing_service_version(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingServiceVersion::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AndroidSdkVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_AndroidSdkVersion kAndroidSdkVersion{};
+  void set_android_sdk_version(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AndroidSdkVersion::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PageSize =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_PageSize kPageSize{};
+  void set_page_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PageSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimezoneOffMins =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SystemInfo>;
+
+  static constexpr FieldMetadata_TimezoneOffMins kTimezoneOffMins{};
+  void set_timezone_off_mins(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimezoneOffMins::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Utsname_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Utsname_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Utsname_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Utsname_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_sysname() const { return at<1>().valid(); }
+  ::protozero::ConstChars sysname() const { return at<1>().as_string(); }
+  bool has_version() const { return at<2>().valid(); }
+  ::protozero::ConstChars version() const { return at<2>().as_string(); }
+  bool has_release() const { return at<3>().valid(); }
+  ::protozero::ConstChars release() const { return at<3>().as_string(); }
+  bool has_machine() const { return at<4>().valid(); }
+  ::protozero::ConstChars machine() const { return at<4>().as_string(); }
+};
+
+class Utsname : public ::protozero::Message {
+ public:
+  using Decoder = Utsname_Decoder;
+  enum : int32_t {
+    kSysnameFieldNumber = 1,
+    kVersionFieldNumber = 2,
+    kReleaseFieldNumber = 3,
+    kMachineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Utsname"; }
+
+
+  using FieldMetadata_Sysname =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Utsname>;
+
+  static constexpr FieldMetadata_Sysname kSysname{};
+  void set_sysname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Sysname::kFieldId, data, size);
+  }
+  void set_sysname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Sysname::kFieldId, chars.data, chars.size);
+  }
+  void set_sysname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sysname::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Version =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Utsname>;
+
+  static constexpr FieldMetadata_Version kVersion{};
+  void set_version(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Version::kFieldId, data, size);
+  }
+  void set_version(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Version::kFieldId, chars.data, chars.size);
+  }
+  void set_version(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Version::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Release =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Utsname>;
+
+  static constexpr FieldMetadata_Release kRelease{};
+  void set_release(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Release::kFieldId, data, size);
+  }
+  void set_release(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Release::kFieldId, chars.data, chars.size);
+  }
+  void set_release(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Release::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Machine =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Utsname>;
+
+  static constexpr FieldMetadata_Machine kMachine{};
+  void set_machine(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Machine::kFieldId, data, size);
+  }
+  void set_machine(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Machine::kFieldId, chars.data, chars.size);
+  }
+  void set_machine(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Machine::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/android_game_intervention_list.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_GAME_INTERVENTION_LIST_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_GAME_INTERVENTION_LIST_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidGameInterventionList_GameModeInfo;
+class AndroidGameInterventionList_GamePackageInfo;
+
+class AndroidGameInterventionList_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidGameInterventionList_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidGameInterventionList_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidGameInterventionList_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_game_packages() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> game_packages() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_parse_error() const { return at<2>().valid(); }
+  bool parse_error() const { return at<2>().as_bool(); }
+  bool has_read_error() const { return at<3>().valid(); }
+  bool read_error() const { return at<3>().as_bool(); }
+};
+
+class AndroidGameInterventionList : public ::protozero::Message {
+ public:
+  using Decoder = AndroidGameInterventionList_Decoder;
+  enum : int32_t {
+    kGamePackagesFieldNumber = 1,
+    kParseErrorFieldNumber = 2,
+    kReadErrorFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidGameInterventionList"; }
+
+  using GameModeInfo = ::perfetto::protos::pbzero::AndroidGameInterventionList_GameModeInfo;
+  using GamePackageInfo = ::perfetto::protos::pbzero::AndroidGameInterventionList_GamePackageInfo;
+
+  using FieldMetadata_GamePackages =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidGameInterventionList_GamePackageInfo,
+      AndroidGameInterventionList>;
+
+  static constexpr FieldMetadata_GamePackages kGamePackages{};
+  template <typename T = AndroidGameInterventionList_GamePackageInfo> T* add_game_packages() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ParseError =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidGameInterventionList>;
+
+  static constexpr FieldMetadata_ParseError kParseError{};
+  void set_parse_error(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParseError::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReadError =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidGameInterventionList>;
+
+  static constexpr FieldMetadata_ReadError kReadError{};
+  void set_read_error(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadError::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidGameInterventionList_GamePackageInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidGameInterventionList_GamePackageInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidGameInterventionList_GamePackageInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidGameInterventionList_GamePackageInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_uid() const { return at<2>().valid(); }
+  uint64_t uid() const { return at<2>().as_uint64(); }
+  bool has_current_mode() const { return at<3>().valid(); }
+  uint32_t current_mode() const { return at<3>().as_uint32(); }
+  bool has_game_mode_info() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> game_mode_info() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class AndroidGameInterventionList_GamePackageInfo : public ::protozero::Message {
+ public:
+  using Decoder = AndroidGameInterventionList_GamePackageInfo_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kUidFieldNumber = 2,
+    kCurrentModeFieldNumber = 3,
+    kGameModeInfoFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidGameInterventionList.GamePackageInfo"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidGameInterventionList_GamePackageInfo>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidGameInterventionList_GamePackageInfo>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CurrentMode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidGameInterventionList_GamePackageInfo>;
+
+  static constexpr FieldMetadata_CurrentMode kCurrentMode{};
+  void set_current_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GameModeInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidGameInterventionList_GameModeInfo,
+      AndroidGameInterventionList_GamePackageInfo>;
+
+  static constexpr FieldMetadata_GameModeInfo kGameModeInfo{};
+  template <typename T = AndroidGameInterventionList_GameModeInfo> T* add_game_mode_info() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class AndroidGameInterventionList_GameModeInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidGameInterventionList_GameModeInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidGameInterventionList_GameModeInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidGameInterventionList_GameModeInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  uint32_t mode() const { return at<1>().as_uint32(); }
+  bool has_use_angle() const { return at<2>().valid(); }
+  bool use_angle() const { return at<2>().as_bool(); }
+  bool has_resolution_downscale() const { return at<3>().valid(); }
+  float resolution_downscale() const { return at<3>().as_float(); }
+  bool has_fps() const { return at<4>().valid(); }
+  float fps() const { return at<4>().as_float(); }
+};
+
+class AndroidGameInterventionList_GameModeInfo : public ::protozero::Message {
+ public:
+  using Decoder = AndroidGameInterventionList_GameModeInfo_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+    kUseAngleFieldNumber = 2,
+    kResolutionDownscaleFieldNumber = 3,
+    kFpsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidGameInterventionList.GameModeInfo"; }
+
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidGameInterventionList_GameModeInfo>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UseAngle =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      AndroidGameInterventionList_GameModeInfo>;
+
+  static constexpr FieldMetadata_UseAngle kUseAngle{};
+  void set_use_angle(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_UseAngle::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResolutionDownscale =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidGameInterventionList_GameModeInfo>;
+
+  static constexpr FieldMetadata_ResolutionDownscale kResolutionDownscale{};
+  void set_resolution_downscale(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResolutionDownscale::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fps =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidGameInterventionList_GameModeInfo>;
+
+  static constexpr FieldMetadata_Fps kFps{};
+  void set_fps(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fps::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/android_log.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_LOG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_LOG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidLogPacket_LogEvent;
+class AndroidLogPacket_LogEvent_Arg;
+class AndroidLogPacket_Stats;
+enum AndroidLogId : int32_t;
+enum AndroidLogPriority : int32_t;
+
+class AndroidLogPacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidLogPacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidLogPacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidLogPacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_events() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> events() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_stats() const { return at<2>().valid(); }
+  ::protozero::ConstBytes stats() const { return at<2>().as_bytes(); }
+};
+
+class AndroidLogPacket : public ::protozero::Message {
+ public:
+  using Decoder = AndroidLogPacket_Decoder;
+  enum : int32_t {
+    kEventsFieldNumber = 1,
+    kStatsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidLogPacket"; }
+
+  using LogEvent = ::perfetto::protos::pbzero::AndroidLogPacket_LogEvent;
+  using Stats = ::perfetto::protos::pbzero::AndroidLogPacket_Stats;
+
+  using FieldMetadata_Events =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidLogPacket_LogEvent,
+      AndroidLogPacket>;
+
+  static constexpr FieldMetadata_Events kEvents{};
+  template <typename T = AndroidLogPacket_LogEvent> T* add_events() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Stats =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidLogPacket_Stats,
+      AndroidLogPacket>;
+
+  static constexpr FieldMetadata_Stats kStats{};
+  template <typename T = AndroidLogPacket_Stats> T* set_stats() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class AndroidLogPacket_Stats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidLogPacket_Stats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidLogPacket_Stats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidLogPacket_Stats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_num_total() const { return at<1>().valid(); }
+  uint64_t num_total() const { return at<1>().as_uint64(); }
+  bool has_num_failed() const { return at<2>().valid(); }
+  uint64_t num_failed() const { return at<2>().as_uint64(); }
+  bool has_num_skipped() const { return at<3>().valid(); }
+  uint64_t num_skipped() const { return at<3>().as_uint64(); }
+};
+
+class AndroidLogPacket_Stats : public ::protozero::Message {
+ public:
+  using Decoder = AndroidLogPacket_Stats_Decoder;
+  enum : int32_t {
+    kNumTotalFieldNumber = 1,
+    kNumFailedFieldNumber = 2,
+    kNumSkippedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidLogPacket.Stats"; }
+
+
+  using FieldMetadata_NumTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidLogPacket_Stats>;
+
+  static constexpr FieldMetadata_NumTotal kNumTotal{};
+  void set_num_total(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumTotal::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidLogPacket_Stats>;
+
+  static constexpr FieldMetadata_NumFailed kNumFailed{};
+  void set_num_failed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumFailed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumSkipped =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidLogPacket_Stats>;
+
+  static constexpr FieldMetadata_NumSkipped kNumSkipped{};
+  void set_num_skipped(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumSkipped::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidLogPacket_LogEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidLogPacket_LogEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidLogPacket_LogEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidLogPacket_LogEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_log_id() const { return at<1>().valid(); }
+  int32_t log_id() const { return at<1>().as_int32(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_tid() const { return at<3>().valid(); }
+  int32_t tid() const { return at<3>().as_int32(); }
+  bool has_uid() const { return at<4>().valid(); }
+  int32_t uid() const { return at<4>().as_int32(); }
+  bool has_timestamp() const { return at<5>().valid(); }
+  uint64_t timestamp() const { return at<5>().as_uint64(); }
+  bool has_tag() const { return at<6>().valid(); }
+  ::protozero::ConstChars tag() const { return at<6>().as_string(); }
+  bool has_prio() const { return at<7>().valid(); }
+  int32_t prio() const { return at<7>().as_int32(); }
+  bool has_message() const { return at<8>().valid(); }
+  ::protozero::ConstChars message() const { return at<8>().as_string(); }
+  bool has_args() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> args() const { return GetRepeated<::protozero::ConstBytes>(9); }
+};
+
+class AndroidLogPacket_LogEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidLogPacket_LogEvent_Decoder;
+  enum : int32_t {
+    kLogIdFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTidFieldNumber = 3,
+    kUidFieldNumber = 4,
+    kTimestampFieldNumber = 5,
+    kTagFieldNumber = 6,
+    kPrioFieldNumber = 7,
+    kMessageFieldNumber = 8,
+    kArgsFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidLogPacket.LogEvent"; }
+
+  using Arg = ::perfetto::protos::pbzero::AndroidLogPacket_LogEvent_Arg;
+
+  using FieldMetadata_LogId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::AndroidLogId,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_LogId kLogId{};
+  void set_log_id(::perfetto::protos::pbzero::AndroidLogId value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::AndroidLogPriority,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(::perfetto::protos::pbzero::AndroidLogPriority value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Message =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Message kMessage{};
+  void set_message(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Message::kFieldId, data, size);
+  }
+  void set_message(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Message::kFieldId, chars.data, chars.size);
+  }
+  void set_message(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Message::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Args =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidLogPacket_LogEvent_Arg,
+      AndroidLogPacket_LogEvent>;
+
+  static constexpr FieldMetadata_Args kArgs{};
+  template <typename T = AndroidLogPacket_LogEvent_Arg> T* add_args() {
+    return BeginNestedMessage<T>(9);
+  }
+
+};
+
+class AndroidLogPacket_LogEvent_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidLogPacket_LogEvent_Arg_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidLogPacket_LogEvent_Arg_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidLogPacket_LogEvent_Arg_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_int_value() const { return at<2>().valid(); }
+  int64_t int_value() const { return at<2>().as_int64(); }
+  bool has_float_value() const { return at<3>().valid(); }
+  float float_value() const { return at<3>().as_float(); }
+  bool has_string_value() const { return at<4>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<4>().as_string(); }
+};
+
+class AndroidLogPacket_LogEvent_Arg : public ::protozero::Message {
+ public:
+  using Decoder = AndroidLogPacket_LogEvent_Arg_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kIntValueFieldNumber = 2,
+    kFloatValueFieldNumber = 3,
+    kStringValueFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidLogPacket.LogEvent.Arg"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogPacket_LogEvent_Arg>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidLogPacket_LogEvent_Arg>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FloatValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      AndroidLogPacket_LogEvent_Arg>;
+
+  static constexpr FieldMetadata_FloatValue kFloatValue{};
+  void set_float_value(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_FloatValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidLogPacket_LogEvent_Arg>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/android_system_property.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_SYSTEM_PROPERTY_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_ANDROID_SYSTEM_PROPERTY_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidSystemProperty_PropertyValue;
+
+class AndroidSystemProperty_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidSystemProperty_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidSystemProperty_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidSystemProperty_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_values() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> values() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class AndroidSystemProperty : public ::protozero::Message {
+ public:
+  using Decoder = AndroidSystemProperty_Decoder;
+  enum : int32_t {
+    kValuesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidSystemProperty"; }
+
+  using PropertyValue = ::perfetto::protos::pbzero::AndroidSystemProperty_PropertyValue;
+
+  using FieldMetadata_Values =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidSystemProperty_PropertyValue,
+      AndroidSystemProperty>;
+
+  static constexpr FieldMetadata_Values kValues{};
+  template <typename T = AndroidSystemProperty_PropertyValue> T* add_values() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class AndroidSystemProperty_PropertyValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidSystemProperty_PropertyValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidSystemProperty_PropertyValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidSystemProperty_PropertyValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class AndroidSystemProperty_PropertyValue : public ::protozero::Message {
+ public:
+  using Decoder = AndroidSystemProperty_PropertyValue_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidSystemProperty.PropertyValue"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidSystemProperty_PropertyValue>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidSystemProperty_PropertyValue>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/camera_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_CAMERA_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_CAMERA_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidCameraFrameEvent_CameraNodeProcessingDetails;
+class AndroidCameraSessionStats_CameraGraph;
+class AndroidCameraSessionStats_CameraGraph_CameraEdge;
+class AndroidCameraSessionStats_CameraGraph_CameraNode;
+namespace perfetto_pbzero_enum_AndroidCameraFrameEvent {
+enum CaptureResultStatus : int32_t;
+}  // namespace perfetto_pbzero_enum_AndroidCameraFrameEvent
+using AndroidCameraFrameEvent_CaptureResultStatus = perfetto_pbzero_enum_AndroidCameraFrameEvent::CaptureResultStatus;
+
+namespace perfetto_pbzero_enum_AndroidCameraFrameEvent {
+enum CaptureResultStatus : int32_t {
+  STATUS_UNSPECIFIED = 0,
+  STATUS_OK = 1,
+  STATUS_EARLY_METADATA_ERROR = 2,
+  STATUS_FINAL_METADATA_ERROR = 3,
+  STATUS_BUFFER_ERROR = 4,
+  STATUS_FLUSH_ERROR = 5,
+};
+} // namespace perfetto_pbzero_enum_AndroidCameraFrameEvent
+using AndroidCameraFrameEvent_CaptureResultStatus = perfetto_pbzero_enum_AndroidCameraFrameEvent::CaptureResultStatus;
+
+
+constexpr AndroidCameraFrameEvent_CaptureResultStatus AndroidCameraFrameEvent_CaptureResultStatus_MIN = AndroidCameraFrameEvent_CaptureResultStatus::STATUS_UNSPECIFIED;
+constexpr AndroidCameraFrameEvent_CaptureResultStatus AndroidCameraFrameEvent_CaptureResultStatus_MAX = AndroidCameraFrameEvent_CaptureResultStatus::STATUS_FLUSH_ERROR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* AndroidCameraFrameEvent_CaptureResultStatus_Name(::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_UNSPECIFIED:
+    return "STATUS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_OK:
+    return "STATUS_OK";
+
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_EARLY_METADATA_ERROR:
+    return "STATUS_EARLY_METADATA_ERROR";
+
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_FINAL_METADATA_ERROR:
+    return "STATUS_FINAL_METADATA_ERROR";
+
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_BUFFER_ERROR:
+    return "STATUS_BUFFER_ERROR";
+
+  case ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus::STATUS_FLUSH_ERROR:
+    return "STATUS_FLUSH_ERROR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class AndroidCameraSessionStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidCameraSessionStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraSessionStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraSessionStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_session_id() const { return at<1>().valid(); }
+  uint64_t session_id() const { return at<1>().as_uint64(); }
+  bool has_graph() const { return at<2>().valid(); }
+  ::protozero::ConstBytes graph() const { return at<2>().as_bytes(); }
+};
+
+class AndroidCameraSessionStats : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraSessionStats_Decoder;
+  enum : int32_t {
+    kSessionIdFieldNumber = 1,
+    kGraphFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraSessionStats"; }
+
+  using CameraGraph = ::perfetto::protos::pbzero::AndroidCameraSessionStats_CameraGraph;
+
+  using FieldMetadata_SessionId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidCameraSessionStats>;
+
+  static constexpr FieldMetadata_SessionId kSessionId{};
+  void set_session_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SessionId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Graph =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraSessionStats_CameraGraph,
+      AndroidCameraSessionStats>;
+
+  static constexpr FieldMetadata_Graph kGraph{};
+  template <typename T = AndroidCameraSessionStats_CameraGraph> T* set_graph() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class AndroidCameraSessionStats_CameraGraph_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidCameraSessionStats_CameraGraph_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraSessionStats_CameraGraph_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraSessionStats_CameraGraph_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nodes() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> nodes() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_edges() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> edges() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class AndroidCameraSessionStats_CameraGraph : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraSessionStats_CameraGraph_Decoder;
+  enum : int32_t {
+    kNodesFieldNumber = 1,
+    kEdgesFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraSessionStats.CameraGraph"; }
+
+  using CameraNode = ::perfetto::protos::pbzero::AndroidCameraSessionStats_CameraGraph_CameraNode;
+  using CameraEdge = ::perfetto::protos::pbzero::AndroidCameraSessionStats_CameraGraph_CameraEdge;
+
+  using FieldMetadata_Nodes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraSessionStats_CameraGraph_CameraNode,
+      AndroidCameraSessionStats_CameraGraph>;
+
+  static constexpr FieldMetadata_Nodes kNodes{};
+  template <typename T = AndroidCameraSessionStats_CameraGraph_CameraNode> T* add_nodes() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Edges =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge,
+      AndroidCameraSessionStats_CameraGraph>;
+
+  static constexpr FieldMetadata_Edges kEdges{};
+  template <typename T = AndroidCameraSessionStats_CameraGraph_CameraEdge> T* add_edges() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class AndroidCameraSessionStats_CameraGraph_CameraEdge_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidCameraSessionStats_CameraGraph_CameraEdge_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraSessionStats_CameraGraph_CameraEdge_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraSessionStats_CameraGraph_CameraEdge_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_output_node_id() const { return at<1>().valid(); }
+  int64_t output_node_id() const { return at<1>().as_int64(); }
+  bool has_output_id() const { return at<2>().valid(); }
+  int64_t output_id() const { return at<2>().as_int64(); }
+  bool has_input_node_id() const { return at<3>().valid(); }
+  int64_t input_node_id() const { return at<3>().as_int64(); }
+  bool has_input_id() const { return at<4>().valid(); }
+  int64_t input_id() const { return at<4>().as_int64(); }
+  bool has_vendor_data_version() const { return at<5>().valid(); }
+  int32_t vendor_data_version() const { return at<5>().as_int32(); }
+  bool has_vendor_data() const { return at<6>().valid(); }
+  ::protozero::ConstBytes vendor_data() const { return at<6>().as_bytes(); }
+};
+
+class AndroidCameraSessionStats_CameraGraph_CameraEdge : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraSessionStats_CameraGraph_CameraEdge_Decoder;
+  enum : int32_t {
+    kOutputNodeIdFieldNumber = 1,
+    kOutputIdFieldNumber = 2,
+    kInputNodeIdFieldNumber = 3,
+    kInputIdFieldNumber = 4,
+    kVendorDataVersionFieldNumber = 5,
+    kVendorDataFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraSessionStats.CameraGraph.CameraEdge"; }
+
+
+  using FieldMetadata_OutputNodeId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_OutputNodeId kOutputNodeId{};
+  void set_output_node_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OutputNodeId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OutputId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_OutputId kOutputId{};
+  void set_output_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OutputId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InputNodeId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_InputNodeId kInputNodeId{};
+  void set_input_node_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputNodeId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InputId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_InputId kInputId{};
+  void set_input_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VendorDataVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_VendorDataVersion kVendorDataVersion{};
+  void set_vendor_data_version(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorDataVersion::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VendorData =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      AndroidCameraSessionStats_CameraGraph_CameraEdge>;
+
+  static constexpr FieldMetadata_VendorData kVendorData{};
+  void set_vendor_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, data, size);
+  }
+  void set_vendor_data(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, bytes.data, bytes.size);
+  }
+  void set_vendor_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorData::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidCameraSessionStats_CameraGraph_CameraNode_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidCameraSessionStats_CameraGraph_CameraNode_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraSessionStats_CameraGraph_CameraNode_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraSessionStats_CameraGraph_CameraNode_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_node_id() const { return at<1>().valid(); }
+  int64_t node_id() const { return at<1>().as_int64(); }
+  bool has_input_ids() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> input_ids() const { return GetRepeated<int64_t>(2); }
+  bool has_output_ids() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> output_ids() const { return GetRepeated<int64_t>(3); }
+  bool has_vendor_data_version() const { return at<4>().valid(); }
+  int32_t vendor_data_version() const { return at<4>().as_int32(); }
+  bool has_vendor_data() const { return at<5>().valid(); }
+  ::protozero::ConstBytes vendor_data() const { return at<5>().as_bytes(); }
+};
+
+class AndroidCameraSessionStats_CameraGraph_CameraNode : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraSessionStats_CameraGraph_CameraNode_Decoder;
+  enum : int32_t {
+    kNodeIdFieldNumber = 1,
+    kInputIdsFieldNumber = 2,
+    kOutputIdsFieldNumber = 3,
+    kVendorDataVersionFieldNumber = 4,
+    kVendorDataFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraSessionStats.CameraGraph.CameraNode"; }
+
+
+  using FieldMetadata_NodeId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraNode>;
+
+  static constexpr FieldMetadata_NodeId kNodeId{};
+  void set_node_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NodeId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InputIds =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraNode>;
+
+  static constexpr FieldMetadata_InputIds kInputIds{};
+  void add_input_ids(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OutputIds =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraSessionStats_CameraGraph_CameraNode>;
+
+  static constexpr FieldMetadata_OutputIds kOutputIds{};
+  void add_output_ids(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OutputIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VendorDataVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraSessionStats_CameraGraph_CameraNode>;
+
+  static constexpr FieldMetadata_VendorDataVersion kVendorDataVersion{};
+  void set_vendor_data_version(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorDataVersion::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VendorData =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      AndroidCameraSessionStats_CameraGraph_CameraNode>;
+
+  static constexpr FieldMetadata_VendorData kVendorData{};
+  void set_vendor_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, data, size);
+  }
+  void set_vendor_data(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, bytes.data, bytes.size);
+  }
+  void set_vendor_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorData::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidCameraFrameEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/16, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidCameraFrameEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraFrameEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraFrameEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_session_id() const { return at<1>().valid(); }
+  uint64_t session_id() const { return at<1>().as_uint64(); }
+  bool has_camera_id() const { return at<2>().valid(); }
+  uint32_t camera_id() const { return at<2>().as_uint32(); }
+  bool has_frame_number() const { return at<3>().valid(); }
+  int64_t frame_number() const { return at<3>().as_int64(); }
+  bool has_request_id() const { return at<4>().valid(); }
+  int64_t request_id() const { return at<4>().as_int64(); }
+  bool has_request_received_ns() const { return at<5>().valid(); }
+  int64_t request_received_ns() const { return at<5>().as_int64(); }
+  bool has_request_processing_started_ns() const { return at<6>().valid(); }
+  int64_t request_processing_started_ns() const { return at<6>().as_int64(); }
+  bool has_start_of_exposure_ns() const { return at<7>().valid(); }
+  int64_t start_of_exposure_ns() const { return at<7>().as_int64(); }
+  bool has_start_of_frame_ns() const { return at<8>().valid(); }
+  int64_t start_of_frame_ns() const { return at<8>().as_int64(); }
+  bool has_responses_all_sent_ns() const { return at<9>().valid(); }
+  int64_t responses_all_sent_ns() const { return at<9>().as_int64(); }
+  bool has_capture_result_status() const { return at<10>().valid(); }
+  int32_t capture_result_status() const { return at<10>().as_int32(); }
+  bool has_skipped_sensor_frames() const { return at<11>().valid(); }
+  int32_t skipped_sensor_frames() const { return at<11>().as_int32(); }
+  bool has_capture_intent() const { return at<12>().valid(); }
+  int32_t capture_intent() const { return at<12>().as_int32(); }
+  bool has_num_streams() const { return at<13>().valid(); }
+  int32_t num_streams() const { return at<13>().as_int32(); }
+  bool has_node_processing_details() const { return at<14>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> node_processing_details() const { return GetRepeated<::protozero::ConstBytes>(14); }
+  bool has_vendor_data_version() const { return at<15>().valid(); }
+  int32_t vendor_data_version() const { return at<15>().as_int32(); }
+  bool has_vendor_data() const { return at<16>().valid(); }
+  ::protozero::ConstBytes vendor_data() const { return at<16>().as_bytes(); }
+};
+
+class AndroidCameraFrameEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraFrameEvent_Decoder;
+  enum : int32_t {
+    kSessionIdFieldNumber = 1,
+    kCameraIdFieldNumber = 2,
+    kFrameNumberFieldNumber = 3,
+    kRequestIdFieldNumber = 4,
+    kRequestReceivedNsFieldNumber = 5,
+    kRequestProcessingStartedNsFieldNumber = 6,
+    kStartOfExposureNsFieldNumber = 7,
+    kStartOfFrameNsFieldNumber = 8,
+    kResponsesAllSentNsFieldNumber = 9,
+    kCaptureResultStatusFieldNumber = 10,
+    kSkippedSensorFramesFieldNumber = 11,
+    kCaptureIntentFieldNumber = 12,
+    kNumStreamsFieldNumber = 13,
+    kNodeProcessingDetailsFieldNumber = 14,
+    kVendorDataVersionFieldNumber = 15,
+    kVendorDataFieldNumber = 16,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraFrameEvent"; }
+
+  using CameraNodeProcessingDetails = ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CameraNodeProcessingDetails;
+
+  using CaptureResultStatus = ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus;
+  static inline const char* CaptureResultStatus_Name(CaptureResultStatus value) {
+    return ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus_Name(value);
+  }
+  static inline const CaptureResultStatus STATUS_UNSPECIFIED = CaptureResultStatus::STATUS_UNSPECIFIED;
+  static inline const CaptureResultStatus STATUS_OK = CaptureResultStatus::STATUS_OK;
+  static inline const CaptureResultStatus STATUS_EARLY_METADATA_ERROR = CaptureResultStatus::STATUS_EARLY_METADATA_ERROR;
+  static inline const CaptureResultStatus STATUS_FINAL_METADATA_ERROR = CaptureResultStatus::STATUS_FINAL_METADATA_ERROR;
+  static inline const CaptureResultStatus STATUS_BUFFER_ERROR = CaptureResultStatus::STATUS_BUFFER_ERROR;
+  static inline const CaptureResultStatus STATUS_FLUSH_ERROR = CaptureResultStatus::STATUS_FLUSH_ERROR;
+
+  using FieldMetadata_SessionId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_SessionId kSessionId{};
+  void set_session_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SessionId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CameraId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_CameraId kCameraId{};
+  void set_camera_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CameraId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_FrameNumber kFrameNumber{};
+  void set_frame_number(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RequestId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_RequestId kRequestId{};
+  void set_request_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RequestId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RequestReceivedNs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_RequestReceivedNs kRequestReceivedNs{};
+  void set_request_received_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RequestReceivedNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RequestProcessingStartedNs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_RequestProcessingStartedNs kRequestProcessingStartedNs{};
+  void set_request_processing_started_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RequestProcessingStartedNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartOfExposureNs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_StartOfExposureNs kStartOfExposureNs{};
+  void set_start_of_exposure_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartOfExposureNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartOfFrameNs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_StartOfFrameNs kStartOfFrameNs{};
+  void set_start_of_frame_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartOfFrameNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResponsesAllSentNs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_ResponsesAllSentNs kResponsesAllSentNs{};
+  void set_responses_all_sent_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResponsesAllSentNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CaptureResultStatus =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_CaptureResultStatus kCaptureResultStatus{};
+  void set_capture_result_status(::perfetto::protos::pbzero::AndroidCameraFrameEvent_CaptureResultStatus value) {
+    static constexpr uint32_t field_id = FieldMetadata_CaptureResultStatus::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SkippedSensorFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_SkippedSensorFrames kSkippedSensorFrames{};
+  void set_skipped_sensor_frames(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkippedSensorFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CaptureIntent =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_CaptureIntent kCaptureIntent{};
+  void set_capture_intent(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CaptureIntent::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumStreams =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_NumStreams kNumStreams{};
+  void set_num_streams(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumStreams::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NodeProcessingDetails =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidCameraFrameEvent_CameraNodeProcessingDetails,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_NodeProcessingDetails kNodeProcessingDetails{};
+  template <typename T = AndroidCameraFrameEvent_CameraNodeProcessingDetails> T* add_node_processing_details() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_VendorDataVersion =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_VendorDataVersion kVendorDataVersion{};
+  void set_vendor_data_version(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorDataVersion::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VendorData =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      AndroidCameraFrameEvent>;
+
+  static constexpr FieldMetadata_VendorData kVendorData{};
+  void set_vendor_data(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, data, size);
+  }
+  void set_vendor_data(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_VendorData::kFieldId, bytes.data, bytes.size);
+  }
+  void set_vendor_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_VendorData::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidCameraFrameEvent_CameraNodeProcessingDetails_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidCameraFrameEvent_CameraNodeProcessingDetails_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidCameraFrameEvent_CameraNodeProcessingDetails_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidCameraFrameEvent_CameraNodeProcessingDetails_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_node_id() const { return at<1>().valid(); }
+  int64_t node_id() const { return at<1>().as_int64(); }
+  bool has_start_processing_ns() const { return at<2>().valid(); }
+  int64_t start_processing_ns() const { return at<2>().as_int64(); }
+  bool has_end_processing_ns() const { return at<3>().valid(); }
+  int64_t end_processing_ns() const { return at<3>().as_int64(); }
+  bool has_scheduling_latency_ns() const { return at<4>().valid(); }
+  int64_t scheduling_latency_ns() const { return at<4>().as_int64(); }
+};
+
+class AndroidCameraFrameEvent_CameraNodeProcessingDetails : public ::protozero::Message {
+ public:
+  using Decoder = AndroidCameraFrameEvent_CameraNodeProcessingDetails_Decoder;
+  enum : int32_t {
+    kNodeIdFieldNumber = 1,
+    kStartProcessingNsFieldNumber = 2,
+    kEndProcessingNsFieldNumber = 3,
+    kSchedulingLatencyNsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidCameraFrameEvent.CameraNodeProcessingDetails"; }
+
+
+  using FieldMetadata_NodeId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent_CameraNodeProcessingDetails>;
+
+  static constexpr FieldMetadata_NodeId kNodeId{};
+  void set_node_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NodeId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartProcessingNs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent_CameraNodeProcessingDetails>;
+
+  static constexpr FieldMetadata_StartProcessingNs kStartProcessingNs{};
+  void set_start_processing_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartProcessingNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EndProcessingNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent_CameraNodeProcessingDetails>;
+
+  static constexpr FieldMetadata_EndProcessingNs kEndProcessingNs{};
+  void set_end_processing_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EndProcessingNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SchedulingLatencyNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidCameraFrameEvent_CameraNodeProcessingDetails>;
+
+  static constexpr FieldMetadata_SchedulingLatencyNs kSchedulingLatencyNs{};
+  void set_scheduling_latency_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SchedulingLatencyNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/frame_timeline_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_FRAME_TIMELINE_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_FRAME_TIMELINE_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FrameTimelineEvent_ActualDisplayFrameStart;
+class FrameTimelineEvent_ActualSurfaceFrameStart;
+class FrameTimelineEvent_ExpectedDisplayFrameStart;
+class FrameTimelineEvent_ExpectedSurfaceFrameStart;
+class FrameTimelineEvent_FrameEnd;
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum JankSeverityType : int32_t;
+}  // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_JankSeverityType = perfetto_pbzero_enum_FrameTimelineEvent::JankSeverityType;
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum PredictionType : int32_t;
+}  // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_PredictionType = perfetto_pbzero_enum_FrameTimelineEvent::PredictionType;
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum PresentType : int32_t;
+}  // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_PresentType = perfetto_pbzero_enum_FrameTimelineEvent::PresentType;
+
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum JankType : int32_t {
+  JANK_UNSPECIFIED = 0,
+  JANK_NONE = 1,
+  JANK_SF_SCHEDULING = 2,
+  JANK_PREDICTION_ERROR = 4,
+  JANK_DISPLAY_HAL = 8,
+  JANK_SF_CPU_DEADLINE_MISSED = 16,
+  JANK_SF_GPU_DEADLINE_MISSED = 32,
+  JANK_APP_DEADLINE_MISSED = 64,
+  JANK_BUFFER_STUFFING = 128,
+  JANK_UNKNOWN = 256,
+  JANK_SF_STUFFING = 512,
+  JANK_DROPPED = 1024,
+};
+} // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_JankType = perfetto_pbzero_enum_FrameTimelineEvent::JankType;
+
+
+constexpr FrameTimelineEvent_JankType FrameTimelineEvent_JankType_MIN = FrameTimelineEvent_JankType::JANK_UNSPECIFIED;
+constexpr FrameTimelineEvent_JankType FrameTimelineEvent_JankType_MAX = FrameTimelineEvent_JankType::JANK_DROPPED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FrameTimelineEvent_JankType_Name(::perfetto::protos::pbzero::FrameTimelineEvent_JankType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_UNSPECIFIED:
+    return "JANK_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_NONE:
+    return "JANK_NONE";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_SF_SCHEDULING:
+    return "JANK_SF_SCHEDULING";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_PREDICTION_ERROR:
+    return "JANK_PREDICTION_ERROR";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_DISPLAY_HAL:
+    return "JANK_DISPLAY_HAL";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_SF_CPU_DEADLINE_MISSED:
+    return "JANK_SF_CPU_DEADLINE_MISSED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_SF_GPU_DEADLINE_MISSED:
+    return "JANK_SF_GPU_DEADLINE_MISSED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_APP_DEADLINE_MISSED:
+    return "JANK_APP_DEADLINE_MISSED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_BUFFER_STUFFING:
+    return "JANK_BUFFER_STUFFING";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_UNKNOWN:
+    return "JANK_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_SF_STUFFING:
+    return "JANK_SF_STUFFING";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankType::JANK_DROPPED:
+    return "JANK_DROPPED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum JankSeverityType : int32_t {
+  SEVERITY_UNKNOWN = 0,
+  SEVERITY_NONE = 1,
+  SEVERITY_PARTIAL = 2,
+  SEVERITY_FULL = 3,
+};
+} // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_JankSeverityType = perfetto_pbzero_enum_FrameTimelineEvent::JankSeverityType;
+
+
+constexpr FrameTimelineEvent_JankSeverityType FrameTimelineEvent_JankSeverityType_MIN = FrameTimelineEvent_JankSeverityType::SEVERITY_UNKNOWN;
+constexpr FrameTimelineEvent_JankSeverityType FrameTimelineEvent_JankSeverityType_MAX = FrameTimelineEvent_JankSeverityType::SEVERITY_FULL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FrameTimelineEvent_JankSeverityType_Name(::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType::SEVERITY_UNKNOWN:
+    return "SEVERITY_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType::SEVERITY_NONE:
+    return "SEVERITY_NONE";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType::SEVERITY_PARTIAL:
+    return "SEVERITY_PARTIAL";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType::SEVERITY_FULL:
+    return "SEVERITY_FULL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum PresentType : int32_t {
+  PRESENT_UNSPECIFIED = 0,
+  PRESENT_ON_TIME = 1,
+  PRESENT_LATE = 2,
+  PRESENT_EARLY = 3,
+  PRESENT_DROPPED = 4,
+  PRESENT_UNKNOWN = 5,
+};
+} // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_PresentType = perfetto_pbzero_enum_FrameTimelineEvent::PresentType;
+
+
+constexpr FrameTimelineEvent_PresentType FrameTimelineEvent_PresentType_MIN = FrameTimelineEvent_PresentType::PRESENT_UNSPECIFIED;
+constexpr FrameTimelineEvent_PresentType FrameTimelineEvent_PresentType_MAX = FrameTimelineEvent_PresentType::PRESENT_UNKNOWN;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FrameTimelineEvent_PresentType_Name(::perfetto::protos::pbzero::FrameTimelineEvent_PresentType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_UNSPECIFIED:
+    return "PRESENT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_ON_TIME:
+    return "PRESENT_ON_TIME";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_LATE:
+    return "PRESENT_LATE";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_EARLY:
+    return "PRESENT_EARLY";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_DROPPED:
+    return "PRESENT_DROPPED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType::PRESENT_UNKNOWN:
+    return "PRESENT_UNKNOWN";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_FrameTimelineEvent {
+enum PredictionType : int32_t {
+  PREDICTION_UNSPECIFIED = 0,
+  PREDICTION_VALID = 1,
+  PREDICTION_EXPIRED = 2,
+  PREDICTION_UNKNOWN = 3,
+};
+} // namespace perfetto_pbzero_enum_FrameTimelineEvent
+using FrameTimelineEvent_PredictionType = perfetto_pbzero_enum_FrameTimelineEvent::PredictionType;
+
+
+constexpr FrameTimelineEvent_PredictionType FrameTimelineEvent_PredictionType_MIN = FrameTimelineEvent_PredictionType::PREDICTION_UNSPECIFIED;
+constexpr FrameTimelineEvent_PredictionType FrameTimelineEvent_PredictionType_MAX = FrameTimelineEvent_PredictionType::PREDICTION_UNKNOWN;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FrameTimelineEvent_PredictionType_Name(::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType::PREDICTION_UNSPECIFIED:
+    return "PREDICTION_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType::PREDICTION_VALID:
+    return "PREDICTION_VALID";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType::PREDICTION_EXPIRED:
+    return "PREDICTION_EXPIRED";
+
+  case ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType::PREDICTION_UNKNOWN:
+    return "PREDICTION_UNKNOWN";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class FrameTimelineEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_expected_display_frame_start() const { return at<1>().valid(); }
+  ::protozero::ConstBytes expected_display_frame_start() const { return at<1>().as_bytes(); }
+  bool has_actual_display_frame_start() const { return at<2>().valid(); }
+  ::protozero::ConstBytes actual_display_frame_start() const { return at<2>().as_bytes(); }
+  bool has_expected_surface_frame_start() const { return at<3>().valid(); }
+  ::protozero::ConstBytes expected_surface_frame_start() const { return at<3>().as_bytes(); }
+  bool has_actual_surface_frame_start() const { return at<4>().valid(); }
+  ::protozero::ConstBytes actual_surface_frame_start() const { return at<4>().as_bytes(); }
+  bool has_frame_end() const { return at<5>().valid(); }
+  ::protozero::ConstBytes frame_end() const { return at<5>().as_bytes(); }
+};
+
+class FrameTimelineEvent : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_Decoder;
+  enum : int32_t {
+    kExpectedDisplayFrameStartFieldNumber = 1,
+    kActualDisplayFrameStartFieldNumber = 2,
+    kExpectedSurfaceFrameStartFieldNumber = 3,
+    kActualSurfaceFrameStartFieldNumber = 4,
+    kFrameEndFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent"; }
+
+  using ExpectedSurfaceFrameStart = ::perfetto::protos::pbzero::FrameTimelineEvent_ExpectedSurfaceFrameStart;
+  using ActualSurfaceFrameStart = ::perfetto::protos::pbzero::FrameTimelineEvent_ActualSurfaceFrameStart;
+  using ExpectedDisplayFrameStart = ::perfetto::protos::pbzero::FrameTimelineEvent_ExpectedDisplayFrameStart;
+  using ActualDisplayFrameStart = ::perfetto::protos::pbzero::FrameTimelineEvent_ActualDisplayFrameStart;
+  using FrameEnd = ::perfetto::protos::pbzero::FrameTimelineEvent_FrameEnd;
+
+  using JankType = ::perfetto::protos::pbzero::FrameTimelineEvent_JankType;
+  static inline const char* JankType_Name(JankType value) {
+    return ::perfetto::protos::pbzero::FrameTimelineEvent_JankType_Name(value);
+  }
+
+  using JankSeverityType = ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType;
+  static inline const char* JankSeverityType_Name(JankSeverityType value) {
+    return ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType_Name(value);
+  }
+
+  using PresentType = ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType;
+  static inline const char* PresentType_Name(PresentType value) {
+    return ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType_Name(value);
+  }
+
+  using PredictionType = ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType;
+  static inline const char* PredictionType_Name(PredictionType value) {
+    return ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType_Name(value);
+  }
+  static inline const JankType JANK_UNSPECIFIED = JankType::JANK_UNSPECIFIED;
+  static inline const JankType JANK_NONE = JankType::JANK_NONE;
+  static inline const JankType JANK_SF_SCHEDULING = JankType::JANK_SF_SCHEDULING;
+  static inline const JankType JANK_PREDICTION_ERROR = JankType::JANK_PREDICTION_ERROR;
+  static inline const JankType JANK_DISPLAY_HAL = JankType::JANK_DISPLAY_HAL;
+  static inline const JankType JANK_SF_CPU_DEADLINE_MISSED = JankType::JANK_SF_CPU_DEADLINE_MISSED;
+  static inline const JankType JANK_SF_GPU_DEADLINE_MISSED = JankType::JANK_SF_GPU_DEADLINE_MISSED;
+  static inline const JankType JANK_APP_DEADLINE_MISSED = JankType::JANK_APP_DEADLINE_MISSED;
+  static inline const JankType JANK_BUFFER_STUFFING = JankType::JANK_BUFFER_STUFFING;
+  static inline const JankType JANK_UNKNOWN = JankType::JANK_UNKNOWN;
+  static inline const JankType JANK_SF_STUFFING = JankType::JANK_SF_STUFFING;
+  static inline const JankType JANK_DROPPED = JankType::JANK_DROPPED;
+  static inline const JankSeverityType SEVERITY_UNKNOWN = JankSeverityType::SEVERITY_UNKNOWN;
+  static inline const JankSeverityType SEVERITY_NONE = JankSeverityType::SEVERITY_NONE;
+  static inline const JankSeverityType SEVERITY_PARTIAL = JankSeverityType::SEVERITY_PARTIAL;
+  static inline const JankSeverityType SEVERITY_FULL = JankSeverityType::SEVERITY_FULL;
+  static inline const PresentType PRESENT_UNSPECIFIED = PresentType::PRESENT_UNSPECIFIED;
+  static inline const PresentType PRESENT_ON_TIME = PresentType::PRESENT_ON_TIME;
+  static inline const PresentType PRESENT_LATE = PresentType::PRESENT_LATE;
+  static inline const PresentType PRESENT_EARLY = PresentType::PRESENT_EARLY;
+  static inline const PresentType PRESENT_DROPPED = PresentType::PRESENT_DROPPED;
+  static inline const PresentType PRESENT_UNKNOWN = PresentType::PRESENT_UNKNOWN;
+  static inline const PredictionType PREDICTION_UNSPECIFIED = PredictionType::PREDICTION_UNSPECIFIED;
+  static inline const PredictionType PREDICTION_VALID = PredictionType::PREDICTION_VALID;
+  static inline const PredictionType PREDICTION_EXPIRED = PredictionType::PREDICTION_EXPIRED;
+  static inline const PredictionType PREDICTION_UNKNOWN = PredictionType::PREDICTION_UNKNOWN;
+
+  using FieldMetadata_ExpectedDisplayFrameStart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_ExpectedDisplayFrameStart,
+      FrameTimelineEvent>;
+
+  static constexpr FieldMetadata_ExpectedDisplayFrameStart kExpectedDisplayFrameStart{};
+  template <typename T = FrameTimelineEvent_ExpectedDisplayFrameStart> T* set_expected_display_frame_start() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ActualDisplayFrameStart =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_ActualDisplayFrameStart,
+      FrameTimelineEvent>;
+
+  static constexpr FieldMetadata_ActualDisplayFrameStart kActualDisplayFrameStart{};
+  template <typename T = FrameTimelineEvent_ActualDisplayFrameStart> T* set_actual_display_frame_start() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ExpectedSurfaceFrameStart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart,
+      FrameTimelineEvent>;
+
+  static constexpr FieldMetadata_ExpectedSurfaceFrameStart kExpectedSurfaceFrameStart{};
+  template <typename T = FrameTimelineEvent_ExpectedSurfaceFrameStart> T* set_expected_surface_frame_start() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ActualSurfaceFrameStart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_ActualSurfaceFrameStart,
+      FrameTimelineEvent>;
+
+  static constexpr FieldMetadata_ActualSurfaceFrameStart kActualSurfaceFrameStart{};
+  template <typename T = FrameTimelineEvent_ActualSurfaceFrameStart> T* set_actual_surface_frame_start() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_FrameEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FrameTimelineEvent_FrameEnd,
+      FrameTimelineEvent>;
+
+  static constexpr FieldMetadata_FrameEnd kFrameEnd{};
+  template <typename T = FrameTimelineEvent_FrameEnd> T* set_frame_end() {
+    return BeginNestedMessage<T>(5);
+  }
+
+};
+
+class FrameTimelineEvent_FrameEnd_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_FrameEnd_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_FrameEnd_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_FrameEnd_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cookie() const { return at<1>().valid(); }
+  int64_t cookie() const { return at<1>().as_int64(); }
+};
+
+class FrameTimelineEvent_FrameEnd : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_FrameEnd_Decoder;
+  enum : int32_t {
+    kCookieFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent.FrameEnd"; }
+
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_FrameEnd>;
+
+  static constexpr FieldMetadata_Cookie kCookie{};
+  void set_cookie(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cookie::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FrameTimelineEvent_ActualDisplayFrameStart_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_ActualDisplayFrameStart_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_ActualDisplayFrameStart_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_ActualDisplayFrameStart_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cookie() const { return at<1>().valid(); }
+  int64_t cookie() const { return at<1>().as_int64(); }
+  bool has_token() const { return at<2>().valid(); }
+  int64_t token() const { return at<2>().as_int64(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+  bool has_present_type() const { return at<4>().valid(); }
+  int32_t present_type() const { return at<4>().as_int32(); }
+  bool has_on_time_finish() const { return at<5>().valid(); }
+  bool on_time_finish() const { return at<5>().as_bool(); }
+  bool has_gpu_composition() const { return at<6>().valid(); }
+  bool gpu_composition() const { return at<6>().as_bool(); }
+  bool has_jank_type() const { return at<7>().valid(); }
+  int32_t jank_type() const { return at<7>().as_int32(); }
+  bool has_prediction_type() const { return at<8>().valid(); }
+  int32_t prediction_type() const { return at<8>().as_int32(); }
+  bool has_jank_severity_type() const { return at<9>().valid(); }
+  int32_t jank_severity_type() const { return at<9>().as_int32(); }
+};
+
+class FrameTimelineEvent_ActualDisplayFrameStart : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_ActualDisplayFrameStart_Decoder;
+  enum : int32_t {
+    kCookieFieldNumber = 1,
+    kTokenFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kPresentTypeFieldNumber = 4,
+    kOnTimeFinishFieldNumber = 5,
+    kGpuCompositionFieldNumber = 6,
+    kJankTypeFieldNumber = 7,
+    kPredictionTypeFieldNumber = 8,
+    kJankSeverityTypeFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent.ActualDisplayFrameStart"; }
+
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Cookie kCookie{};
+  void set_cookie(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cookie::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Token =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Token kToken{};
+  void set_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Token::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PresentType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_PresentType kPresentType{};
+  void set_present_type(::perfetto::protos::pbzero::FrameTimelineEvent_PresentType value) {
+    static constexpr uint32_t field_id = FieldMetadata_PresentType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OnTimeFinish =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_OnTimeFinish kOnTimeFinish{};
+  void set_on_time_finish(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_OnTimeFinish::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GpuComposition =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_GpuComposition kGpuComposition{};
+  void set_gpu_composition(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuComposition::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_JankType =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_JankType kJankType{};
+  void set_jank_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_JankType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PredictionType =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_PredictionType kPredictionType{};
+  void set_prediction_type(::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType value) {
+    static constexpr uint32_t field_id = FieldMetadata_PredictionType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_JankSeverityType =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType,
+      FrameTimelineEvent_ActualDisplayFrameStart>;
+
+  static constexpr FieldMetadata_JankSeverityType kJankSeverityType{};
+  void set_jank_severity_type(::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType value) {
+    static constexpr uint32_t field_id = FieldMetadata_JankSeverityType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FrameTimelineEvent_ExpectedDisplayFrameStart_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_ExpectedDisplayFrameStart_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_ExpectedDisplayFrameStart_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_ExpectedDisplayFrameStart_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cookie() const { return at<1>().valid(); }
+  int64_t cookie() const { return at<1>().as_int64(); }
+  bool has_token() const { return at<2>().valid(); }
+  int64_t token() const { return at<2>().as_int64(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+};
+
+class FrameTimelineEvent_ExpectedDisplayFrameStart : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_ExpectedDisplayFrameStart_Decoder;
+  enum : int32_t {
+    kCookieFieldNumber = 1,
+    kTokenFieldNumber = 2,
+    kPidFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent.ExpectedDisplayFrameStart"; }
+
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Cookie kCookie{};
+  void set_cookie(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cookie::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Token =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Token kToken{};
+  void set_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Token::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ExpectedDisplayFrameStart>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FrameTimelineEvent_ActualSurfaceFrameStart_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_ActualSurfaceFrameStart_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_ActualSurfaceFrameStart_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_ActualSurfaceFrameStart_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cookie() const { return at<1>().valid(); }
+  int64_t cookie() const { return at<1>().as_int64(); }
+  bool has_token() const { return at<2>().valid(); }
+  int64_t token() const { return at<2>().as_int64(); }
+  bool has_display_frame_token() const { return at<3>().valid(); }
+  int64_t display_frame_token() const { return at<3>().as_int64(); }
+  bool has_pid() const { return at<4>().valid(); }
+  int32_t pid() const { return at<4>().as_int32(); }
+  bool has_layer_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars layer_name() const { return at<5>().as_string(); }
+  bool has_present_type() const { return at<6>().valid(); }
+  int32_t present_type() const { return at<6>().as_int32(); }
+  bool has_on_time_finish() const { return at<7>().valid(); }
+  bool on_time_finish() const { return at<7>().as_bool(); }
+  bool has_gpu_composition() const { return at<8>().valid(); }
+  bool gpu_composition() const { return at<8>().as_bool(); }
+  bool has_jank_type() const { return at<9>().valid(); }
+  int32_t jank_type() const { return at<9>().as_int32(); }
+  bool has_prediction_type() const { return at<10>().valid(); }
+  int32_t prediction_type() const { return at<10>().as_int32(); }
+  bool has_is_buffer() const { return at<11>().valid(); }
+  bool is_buffer() const { return at<11>().as_bool(); }
+  bool has_jank_severity_type() const { return at<12>().valid(); }
+  int32_t jank_severity_type() const { return at<12>().as_int32(); }
+};
+
+class FrameTimelineEvent_ActualSurfaceFrameStart : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_ActualSurfaceFrameStart_Decoder;
+  enum : int32_t {
+    kCookieFieldNumber = 1,
+    kTokenFieldNumber = 2,
+    kDisplayFrameTokenFieldNumber = 3,
+    kPidFieldNumber = 4,
+    kLayerNameFieldNumber = 5,
+    kPresentTypeFieldNumber = 6,
+    kOnTimeFinishFieldNumber = 7,
+    kGpuCompositionFieldNumber = 8,
+    kJankTypeFieldNumber = 9,
+    kPredictionTypeFieldNumber = 10,
+    kIsBufferFieldNumber = 11,
+    kJankSeverityTypeFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent.ActualSurfaceFrameStart"; }
+
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Cookie kCookie{};
+  void set_cookie(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cookie::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Token =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Token kToken{};
+  void set_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Token::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisplayFrameToken =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_DisplayFrameToken kDisplayFrameToken{};
+  void set_display_frame_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplayFrameToken::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_LayerName kLayerName{};
+  void set_layer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, data, size);
+  }
+  void set_layer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, chars.data, chars.size);
+  }
+  void set_layer_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PresentType =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FrameTimelineEvent_PresentType,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_PresentType kPresentType{};
+  void set_present_type(::perfetto::protos::pbzero::FrameTimelineEvent_PresentType value) {
+    static constexpr uint32_t field_id = FieldMetadata_PresentType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OnTimeFinish =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_OnTimeFinish kOnTimeFinish{};
+  void set_on_time_finish(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_OnTimeFinish::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GpuComposition =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_GpuComposition kGpuComposition{};
+  void set_gpu_composition(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuComposition::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_JankType =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_JankType kJankType{};
+  void set_jank_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_JankType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PredictionType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_PredictionType kPredictionType{};
+  void set_prediction_type(::perfetto::protos::pbzero::FrameTimelineEvent_PredictionType value) {
+    static constexpr uint32_t field_id = FieldMetadata_PredictionType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_IsBuffer kIsBuffer{};
+  void set_is_buffer(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsBuffer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_JankSeverityType =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType,
+      FrameTimelineEvent_ActualSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_JankSeverityType kJankSeverityType{};
+  void set_jank_severity_type(::perfetto::protos::pbzero::FrameTimelineEvent_JankSeverityType value) {
+    static constexpr uint32_t field_id = FieldMetadata_JankSeverityType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FrameTimelineEvent_ExpectedSurfaceFrameStart_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FrameTimelineEvent_ExpectedSurfaceFrameStart_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FrameTimelineEvent_ExpectedSurfaceFrameStart_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FrameTimelineEvent_ExpectedSurfaceFrameStart_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cookie() const { return at<1>().valid(); }
+  int64_t cookie() const { return at<1>().as_int64(); }
+  bool has_token() const { return at<2>().valid(); }
+  int64_t token() const { return at<2>().as_int64(); }
+  bool has_display_frame_token() const { return at<3>().valid(); }
+  int64_t display_frame_token() const { return at<3>().as_int64(); }
+  bool has_pid() const { return at<4>().valid(); }
+  int32_t pid() const { return at<4>().as_int32(); }
+  bool has_layer_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars layer_name() const { return at<5>().as_string(); }
+};
+
+class FrameTimelineEvent_ExpectedSurfaceFrameStart : public ::protozero::Message {
+ public:
+  using Decoder = FrameTimelineEvent_ExpectedSurfaceFrameStart_Decoder;
+  enum : int32_t {
+    kCookieFieldNumber = 1,
+    kTokenFieldNumber = 2,
+    kDisplayFrameTokenFieldNumber = 3,
+    kPidFieldNumber = 4,
+    kLayerNameFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FrameTimelineEvent.ExpectedSurfaceFrameStart"; }
+
+
+  using FieldMetadata_Cookie =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Cookie kCookie{};
+  void set_cookie(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cookie::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Token =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Token kToken{};
+  void set_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Token::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisplayFrameToken =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_DisplayFrameToken kDisplayFrameToken{};
+  void set_display_frame_token(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplayFrameToken::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FrameTimelineEvent_ExpectedSurfaceFrameStart>;
+
+  static constexpr FieldMetadata_LayerName kLayerName{};
+  void set_layer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, data, size);
+  }
+  void set_layer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, chars.data, chars.size);
+  }
+  void set_layer_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/gpu_mem_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GPU_MEM_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GPU_MEM_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class GpuMemTotalEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuMemTotalEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuMemTotalEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuMemTotalEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gpu_id() const { return at<1>().valid(); }
+  uint32_t gpu_id() const { return at<1>().as_uint32(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+};
+
+class GpuMemTotalEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuMemTotalEvent_Decoder;
+  enum : int32_t {
+    kGpuIdFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuMemTotalEvent"; }
+
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuMemTotalEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuMemTotalEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuMemTotalEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/graphics_frame_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GRAPHICS_FRAME_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_GRAPHICS_FRAME_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GraphicsFrameEvent_BufferEvent;
+namespace perfetto_pbzero_enum_GraphicsFrameEvent {
+enum BufferEventType : int32_t;
+}  // namespace perfetto_pbzero_enum_GraphicsFrameEvent
+using GraphicsFrameEvent_BufferEventType = perfetto_pbzero_enum_GraphicsFrameEvent::BufferEventType;
+
+namespace perfetto_pbzero_enum_GraphicsFrameEvent {
+enum BufferEventType : int32_t {
+  UNSPECIFIED = 0,
+  DEQUEUE = 1,
+  QUEUE = 2,
+  POST = 3,
+  ACQUIRE_FENCE = 4,
+  LATCH = 5,
+  HWC_COMPOSITION_QUEUED = 6,
+  FALLBACK_COMPOSITION = 7,
+  PRESENT_FENCE = 8,
+  RELEASE_FENCE = 9,
+  MODIFY = 10,
+  DETACH = 11,
+  ATTACH = 12,
+  CANCEL = 13,
+};
+} // namespace perfetto_pbzero_enum_GraphicsFrameEvent
+using GraphicsFrameEvent_BufferEventType = perfetto_pbzero_enum_GraphicsFrameEvent::BufferEventType;
+
+
+constexpr GraphicsFrameEvent_BufferEventType GraphicsFrameEvent_BufferEventType_MIN = GraphicsFrameEvent_BufferEventType::UNSPECIFIED;
+constexpr GraphicsFrameEvent_BufferEventType GraphicsFrameEvent_BufferEventType_MAX = GraphicsFrameEvent_BufferEventType::CANCEL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* GraphicsFrameEvent_BufferEventType_Name(::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::DEQUEUE:
+    return "DEQUEUE";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::QUEUE:
+    return "QUEUE";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::POST:
+    return "POST";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::ACQUIRE_FENCE:
+    return "ACQUIRE_FENCE";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::LATCH:
+    return "LATCH";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::HWC_COMPOSITION_QUEUED:
+    return "HWC_COMPOSITION_QUEUED";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::FALLBACK_COMPOSITION:
+    return "FALLBACK_COMPOSITION";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::PRESENT_FENCE:
+    return "PRESENT_FENCE";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::RELEASE_FENCE:
+    return "RELEASE_FENCE";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::MODIFY:
+    return "MODIFY";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::DETACH:
+    return "DETACH";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::ATTACH:
+    return "ATTACH";
+
+  case ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType::CANCEL:
+    return "CANCEL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class GraphicsFrameEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GraphicsFrameEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GraphicsFrameEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GraphicsFrameEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffer_event() const { return at<1>().valid(); }
+  ::protozero::ConstBytes buffer_event() const { return at<1>().as_bytes(); }
+};
+
+class GraphicsFrameEvent : public ::protozero::Message {
+ public:
+  using Decoder = GraphicsFrameEvent_Decoder;
+  enum : int32_t {
+    kBufferEventFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GraphicsFrameEvent"; }
+
+  using BufferEvent = ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEvent;
+
+  using BufferEventType = ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType;
+  static inline const char* BufferEventType_Name(BufferEventType value) {
+    return ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType_Name(value);
+  }
+  static inline const BufferEventType UNSPECIFIED = BufferEventType::UNSPECIFIED;
+  static inline const BufferEventType DEQUEUE = BufferEventType::DEQUEUE;
+  static inline const BufferEventType QUEUE = BufferEventType::QUEUE;
+  static inline const BufferEventType POST = BufferEventType::POST;
+  static inline const BufferEventType ACQUIRE_FENCE = BufferEventType::ACQUIRE_FENCE;
+  static inline const BufferEventType LATCH = BufferEventType::LATCH;
+  static inline const BufferEventType HWC_COMPOSITION_QUEUED = BufferEventType::HWC_COMPOSITION_QUEUED;
+  static inline const BufferEventType FALLBACK_COMPOSITION = BufferEventType::FALLBACK_COMPOSITION;
+  static inline const BufferEventType PRESENT_FENCE = BufferEventType::PRESENT_FENCE;
+  static inline const BufferEventType RELEASE_FENCE = BufferEventType::RELEASE_FENCE;
+  static inline const BufferEventType MODIFY = BufferEventType::MODIFY;
+  static inline const BufferEventType DETACH = BufferEventType::DETACH;
+  static inline const BufferEventType ATTACH = BufferEventType::ATTACH;
+  static inline const BufferEventType CANCEL = BufferEventType::CANCEL;
+
+  using FieldMetadata_BufferEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GraphicsFrameEvent_BufferEvent,
+      GraphicsFrameEvent>;
+
+  static constexpr FieldMetadata_BufferEvent kBufferEvent{};
+  template <typename T = GraphicsFrameEvent_BufferEvent> T* set_buffer_event() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class GraphicsFrameEvent_BufferEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GraphicsFrameEvent_BufferEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GraphicsFrameEvent_BufferEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GraphicsFrameEvent_BufferEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_frame_number() const { return at<1>().valid(); }
+  uint32_t frame_number() const { return at<1>().as_uint32(); }
+  bool has_type() const { return at<2>().valid(); }
+  int32_t type() const { return at<2>().as_int32(); }
+  bool has_layer_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars layer_name() const { return at<3>().as_string(); }
+  bool has_duration_ns() const { return at<4>().valid(); }
+  uint64_t duration_ns() const { return at<4>().as_uint64(); }
+  bool has_buffer_id() const { return at<5>().valid(); }
+  uint32_t buffer_id() const { return at<5>().as_uint32(); }
+};
+
+class GraphicsFrameEvent_BufferEvent : public ::protozero::Message {
+ public:
+  using Decoder = GraphicsFrameEvent_BufferEvent_Decoder;
+  enum : int32_t {
+    kFrameNumberFieldNumber = 1,
+    kTypeFieldNumber = 2,
+    kLayerNameFieldNumber = 3,
+    kDurationNsFieldNumber = 4,
+    kBufferIdFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GraphicsFrameEvent.BufferEvent"; }
+
+
+  using FieldMetadata_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GraphicsFrameEvent_BufferEvent>;
+
+  static constexpr FieldMetadata_FrameNumber kFrameNumber{};
+  void set_frame_number(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType,
+      GraphicsFrameEvent_BufferEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(::perfetto::protos::pbzero::GraphicsFrameEvent_BufferEventType value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GraphicsFrameEvent_BufferEvent>;
+
+  static constexpr FieldMetadata_LayerName kLayerName{};
+  void set_layer_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, data, size);
+  }
+  void set_layer_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LayerName::kFieldId, chars.data, chars.size);
+  }
+  void set_layer_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DurationNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GraphicsFrameEvent_BufferEvent>;
+
+  static constexpr FieldMetadata_DurationNs kDurationNs{};
+  void set_duration_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DurationNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BufferId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GraphicsFrameEvent_BufferEvent>;
+
+  static constexpr FieldMetadata_BufferId kBufferId{};
+  void set_buffer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/initial_display_state.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_INITIAL_DISPLAY_STATE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_INITIAL_DISPLAY_STATE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class InitialDisplayState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InitialDisplayState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InitialDisplayState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InitialDisplayState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_display_state() const { return at<1>().valid(); }
+  int32_t display_state() const { return at<1>().as_int32(); }
+  bool has_brightness() const { return at<2>().valid(); }
+  double brightness() const { return at<2>().as_double(); }
+};
+
+class InitialDisplayState : public ::protozero::Message {
+ public:
+  using Decoder = InitialDisplayState_Decoder;
+  enum : int32_t {
+    kDisplayStateFieldNumber = 1,
+    kBrightnessFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InitialDisplayState"; }
+
+
+  using FieldMetadata_DisplayState =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InitialDisplayState>;
+
+  static constexpr FieldMetadata_DisplayState kDisplayState{};
+  void set_display_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplayState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Brightness =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      InitialDisplayState>;
+
+  static constexpr FieldMetadata_Brightness kBrightness{};
+  void set_brightness(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_Brightness::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/network_trace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_NETWORK_TRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_NETWORK_TRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class NetworkPacketEvent;
+enum TrafficDirection : int32_t;
+
+enum TrafficDirection : int32_t {
+  DIR_UNSPECIFIED = 0,
+  DIR_INGRESS = 1,
+  DIR_EGRESS = 2,
+};
+
+constexpr TrafficDirection TrafficDirection_MIN = TrafficDirection::DIR_UNSPECIFIED;
+constexpr TrafficDirection TrafficDirection_MAX = TrafficDirection::DIR_EGRESS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TrafficDirection_Name(::perfetto::protos::pbzero::TrafficDirection value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TrafficDirection::DIR_UNSPECIFIED:
+    return "DIR_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::TrafficDirection::DIR_INGRESS:
+    return "DIR_INGRESS";
+
+  case ::perfetto::protos::pbzero::TrafficDirection::DIR_EGRESS:
+    return "DIR_EGRESS";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class NetworkPacketContext_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetworkPacketContext_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetworkPacketContext_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetworkPacketContext_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_ctx() const { return at<2>().valid(); }
+  ::protozero::ConstBytes ctx() const { return at<2>().as_bytes(); }
+};
+
+class NetworkPacketContext : public ::protozero::Message {
+ public:
+  using Decoder = NetworkPacketContext_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kCtxFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetworkPacketContext"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetworkPacketContext>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ctx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketEvent,
+      NetworkPacketContext>;
+
+  static constexpr FieldMetadata_Ctx kCtx{};
+  template <typename T = NetworkPacketEvent> T* set_ctx() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class NetworkPacketBundle_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetworkPacketBundle_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetworkPacketBundle_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetworkPacketBundle_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_ctx() const { return at<2>().valid(); }
+  ::protozero::ConstBytes ctx() const { return at<2>().as_bytes(); }
+  bool has_packet_timestamps() const { return at<3>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> packet_timestamps(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(3, parse_error_ptr); }
+  bool has_packet_lengths() const { return at<4>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t> packet_lengths(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t>(4, parse_error_ptr); }
+  bool has_total_packets() const { return at<5>().valid(); }
+  uint32_t total_packets() const { return at<5>().as_uint32(); }
+  bool has_total_duration() const { return at<6>().valid(); }
+  uint64_t total_duration() const { return at<6>().as_uint64(); }
+  bool has_total_length() const { return at<7>().valid(); }
+  uint64_t total_length() const { return at<7>().as_uint64(); }
+};
+
+class NetworkPacketBundle : public ::protozero::Message {
+ public:
+  using Decoder = NetworkPacketBundle_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kCtxFieldNumber = 2,
+    kPacketTimestampsFieldNumber = 3,
+    kPacketLengthsFieldNumber = 4,
+    kTotalPacketsFieldNumber = 5,
+    kTotalDurationFieldNumber = 6,
+    kTotalLengthFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetworkPacketBundle"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ctx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetworkPacketEvent,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_Ctx kCtx{};
+  template <typename T = NetworkPacketEvent> T* set_ctx() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_PacketTimestamps =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_PacketTimestamps kPacketTimestamps{};
+  void set_packet_timestamps(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_PacketTimestamps::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_PacketLengths =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_PacketLengths kPacketLengths{};
+  void set_packet_lengths(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_PacketLengths::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_TotalPackets =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_TotalPackets kTotalPackets{};
+  void set_total_packets(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalPackets::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalDuration =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_TotalDuration kTotalDuration{};
+  void set_total_duration(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalDuration::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalLength =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetworkPacketBundle>;
+
+  static constexpr FieldMetadata_TotalLength kTotalLength{};
+  void set_total_length(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalLength::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class NetworkPacketEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetworkPacketEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetworkPacketEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetworkPacketEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_direction() const { return at<1>().valid(); }
+  int32_t direction() const { return at<1>().as_int32(); }
+  bool has_interface() const { return at<2>().valid(); }
+  ::protozero::ConstChars interface() const { return at<2>().as_string(); }
+  bool has_length() const { return at<3>().valid(); }
+  uint32_t length() const { return at<3>().as_uint32(); }
+  bool has_uid() const { return at<4>().valid(); }
+  uint32_t uid() const { return at<4>().as_uint32(); }
+  bool has_tag() const { return at<5>().valid(); }
+  uint32_t tag() const { return at<5>().as_uint32(); }
+  bool has_ip_proto() const { return at<6>().valid(); }
+  uint32_t ip_proto() const { return at<6>().as_uint32(); }
+  bool has_tcp_flags() const { return at<7>().valid(); }
+  uint32_t tcp_flags() const { return at<7>().as_uint32(); }
+  bool has_local_port() const { return at<8>().valid(); }
+  uint32_t local_port() const { return at<8>().as_uint32(); }
+  bool has_remote_port() const { return at<9>().valid(); }
+  uint32_t remote_port() const { return at<9>().as_uint32(); }
+  bool has_icmp_type() const { return at<10>().valid(); }
+  uint32_t icmp_type() const { return at<10>().as_uint32(); }
+  bool has_icmp_code() const { return at<11>().valid(); }
+  uint32_t icmp_code() const { return at<11>().as_uint32(); }
+};
+
+class NetworkPacketEvent : public ::protozero::Message {
+ public:
+  using Decoder = NetworkPacketEvent_Decoder;
+  enum : int32_t {
+    kDirectionFieldNumber = 1,
+    kInterfaceFieldNumber = 2,
+    kLengthFieldNumber = 3,
+    kUidFieldNumber = 4,
+    kTagFieldNumber = 5,
+    kIpProtoFieldNumber = 6,
+    kTcpFlagsFieldNumber = 7,
+    kLocalPortFieldNumber = 8,
+    kRemotePortFieldNumber = 9,
+    kIcmpTypeFieldNumber = 10,
+    kIcmpCodeFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetworkPacketEvent"; }
+
+
+  using FieldMetadata_Direction =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::TrafficDirection,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_Direction kDirection{};
+  void set_direction(::perfetto::protos::pbzero::TrafficDirection value) {
+    static constexpr uint32_t field_id = FieldMetadata_Direction::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Interface =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_Interface kInterface{};
+  void set_interface(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Interface::kFieldId, data, size);
+  }
+  void set_interface(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Interface::kFieldId, chars.data, chars.size);
+  }
+  void set_interface(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Interface::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Length =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_Length kLength{};
+  void set_length(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Length::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IpProto =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_IpProto kIpProto{};
+  void set_ip_proto(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IpProto::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TcpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_TcpFlags kTcpFlags{};
+  void set_tcp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TcpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LocalPort =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_LocalPort kLocalPort{};
+  void set_local_port(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LocalPort::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RemotePort =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_RemotePort kRemotePort{};
+  void set_remote_port(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RemotePort::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IcmpType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_IcmpType kIcmpType{};
+  void set_icmp_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IcmpType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IcmpCode =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetworkPacketEvent>;
+
+  static constexpr FieldMetadata_IcmpCode kIcmpCode{};
+  void set_icmp_code(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IcmpCode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/packages_list.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_PACKAGES_LIST_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_PACKAGES_LIST_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PackagesList_PackageInfo;
+
+class PackagesList_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PackagesList_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PackagesList_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PackagesList_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_packages() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> packages() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_parse_error() const { return at<2>().valid(); }
+  bool parse_error() const { return at<2>().as_bool(); }
+  bool has_read_error() const { return at<3>().valid(); }
+  bool read_error() const { return at<3>().as_bool(); }
+};
+
+class PackagesList : public ::protozero::Message {
+ public:
+  using Decoder = PackagesList_Decoder;
+  enum : int32_t {
+    kPackagesFieldNumber = 1,
+    kParseErrorFieldNumber = 2,
+    kReadErrorFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PackagesList"; }
+
+  using PackageInfo = ::perfetto::protos::pbzero::PackagesList_PackageInfo;
+
+  using FieldMetadata_Packages =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PackagesList_PackageInfo,
+      PackagesList>;
+
+  static constexpr FieldMetadata_Packages kPackages{};
+  template <typename T = PackagesList_PackageInfo> T* add_packages() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ParseError =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PackagesList>;
+
+  static constexpr FieldMetadata_ParseError kParseError{};
+  void set_parse_error(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParseError::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReadError =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PackagesList>;
+
+  static constexpr FieldMetadata_ReadError kReadError{};
+  void set_read_error(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadError::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PackagesList_PackageInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PackagesList_PackageInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PackagesList_PackageInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PackagesList_PackageInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_uid() const { return at<2>().valid(); }
+  uint64_t uid() const { return at<2>().as_uint64(); }
+  bool has_debuggable() const { return at<3>().valid(); }
+  bool debuggable() const { return at<3>().as_bool(); }
+  bool has_profileable_from_shell() const { return at<4>().valid(); }
+  bool profileable_from_shell() const { return at<4>().as_bool(); }
+  bool has_version_code() const { return at<5>().valid(); }
+  int64_t version_code() const { return at<5>().as_int64(); }
+};
+
+class PackagesList_PackageInfo : public ::protozero::Message {
+ public:
+  using Decoder = PackagesList_PackageInfo_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kUidFieldNumber = 2,
+    kDebuggableFieldNumber = 3,
+    kProfileableFromShellFieldNumber = 4,
+    kVersionCodeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PackagesList.PackageInfo"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PackagesList_PackageInfo>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PackagesList_PackageInfo>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Debuggable =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PackagesList_PackageInfo>;
+
+  static constexpr FieldMetadata_Debuggable kDebuggable{};
+  void set_debuggable(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Debuggable::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProfileableFromShell =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PackagesList_PackageInfo>;
+
+  static constexpr FieldMetadata_ProfileableFromShell kProfileableFromShell{};
+  void set_profileable_from_shell(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProfileableFromShell::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VersionCode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      PackagesList_PackageInfo>;
+
+  static constexpr FieldMetadata_VersionCode kVersionCode{};
+  void set_version_code(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VersionCode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/shell_transition.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SHELL_TRANSITION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SHELL_TRANSITION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ShellHandlerMapping;
+class ShellTransition_Target;
+
+class ShellHandlerMapping_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ShellHandlerMapping_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ShellHandlerMapping_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ShellHandlerMapping_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class ShellHandlerMapping : public ::protozero::Message {
+ public:
+  using Decoder = ShellHandlerMapping_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ShellHandlerMapping"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellHandlerMapping>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ShellHandlerMapping>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ShellHandlerMappings_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ShellHandlerMappings_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ShellHandlerMappings_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ShellHandlerMappings_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mapping() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mapping() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class ShellHandlerMappings : public ::protozero::Message {
+ public:
+  using Decoder = ShellHandlerMappings_Decoder;
+  enum : int32_t {
+    kMappingFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ShellHandlerMappings"; }
+
+
+  using FieldMetadata_Mapping =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ShellHandlerMapping,
+      ShellHandlerMappings>;
+
+  static constexpr FieldMetadata_Mapping kMapping{};
+  template <typename T = ShellHandlerMapping> T* add_mapping() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ShellTransition_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/17, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ShellTransition_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ShellTransition_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ShellTransition_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_create_time_ns() const { return at<2>().valid(); }
+  int64_t create_time_ns() const { return at<2>().as_int64(); }
+  bool has_send_time_ns() const { return at<3>().valid(); }
+  int64_t send_time_ns() const { return at<3>().as_int64(); }
+  bool has_dispatch_time_ns() const { return at<4>().valid(); }
+  int64_t dispatch_time_ns() const { return at<4>().as_int64(); }
+  bool has_merge_time_ns() const { return at<5>().valid(); }
+  int64_t merge_time_ns() const { return at<5>().as_int64(); }
+  bool has_merge_request_time_ns() const { return at<6>().valid(); }
+  int64_t merge_request_time_ns() const { return at<6>().as_int64(); }
+  bool has_shell_abort_time_ns() const { return at<7>().valid(); }
+  int64_t shell_abort_time_ns() const { return at<7>().as_int64(); }
+  bool has_wm_abort_time_ns() const { return at<8>().valid(); }
+  int64_t wm_abort_time_ns() const { return at<8>().as_int64(); }
+  bool has_finish_time_ns() const { return at<9>().valid(); }
+  int64_t finish_time_ns() const { return at<9>().as_int64(); }
+  bool has_start_transaction_id() const { return at<10>().valid(); }
+  uint64_t start_transaction_id() const { return at<10>().as_uint64(); }
+  bool has_finish_transaction_id() const { return at<11>().valid(); }
+  uint64_t finish_transaction_id() const { return at<11>().as_uint64(); }
+  bool has_handler() const { return at<12>().valid(); }
+  int32_t handler() const { return at<12>().as_int32(); }
+  bool has_type() const { return at<13>().valid(); }
+  int32_t type() const { return at<13>().as_int32(); }
+  bool has_targets() const { return at<14>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> targets() const { return GetRepeated<::protozero::ConstBytes>(14); }
+  bool has_merge_target() const { return at<15>().valid(); }
+  int32_t merge_target() const { return at<15>().as_int32(); }
+  bool has_flags() const { return at<16>().valid(); }
+  int32_t flags() const { return at<16>().as_int32(); }
+  bool has_starting_window_remove_time_ns() const { return at<17>().valid(); }
+  int64_t starting_window_remove_time_ns() const { return at<17>().as_int64(); }
+};
+
+class ShellTransition : public ::protozero::Message {
+ public:
+  using Decoder = ShellTransition_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kCreateTimeNsFieldNumber = 2,
+    kSendTimeNsFieldNumber = 3,
+    kDispatchTimeNsFieldNumber = 4,
+    kMergeTimeNsFieldNumber = 5,
+    kMergeRequestTimeNsFieldNumber = 6,
+    kShellAbortTimeNsFieldNumber = 7,
+    kWmAbortTimeNsFieldNumber = 8,
+    kFinishTimeNsFieldNumber = 9,
+    kStartTransactionIdFieldNumber = 10,
+    kFinishTransactionIdFieldNumber = 11,
+    kHandlerFieldNumber = 12,
+    kTypeFieldNumber = 13,
+    kTargetsFieldNumber = 14,
+    kMergeTargetFieldNumber = 15,
+    kFlagsFieldNumber = 16,
+    kStartingWindowRemoveTimeNsFieldNumber = 17,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ShellTransition"; }
+
+  using Target = ::perfetto::protos::pbzero::ShellTransition_Target;
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CreateTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_CreateTimeNs kCreateTimeNs{};
+  void set_create_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CreateTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SendTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_SendTimeNs kSendTimeNs{};
+  void set_send_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SendTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DispatchTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_DispatchTimeNs kDispatchTimeNs{};
+  void set_dispatch_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DispatchTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MergeTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_MergeTimeNs kMergeTimeNs{};
+  void set_merge_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MergeTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MergeRequestTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_MergeRequestTimeNs kMergeRequestTimeNs{};
+  void set_merge_request_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MergeRequestTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ShellAbortTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_ShellAbortTimeNs kShellAbortTimeNs{};
+  void set_shell_abort_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShellAbortTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WmAbortTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_WmAbortTimeNs kWmAbortTimeNs{};
+  void set_wm_abort_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WmAbortTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FinishTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_FinishTimeNs kFinishTimeNs{};
+  void set_finish_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FinishTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartTransactionId =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_StartTransactionId kStartTransactionId{};
+  void set_start_transaction_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartTransactionId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FinishTransactionId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_FinishTransactionId kFinishTransactionId{};
+  void set_finish_transaction_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FinishTransactionId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Handler =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_Handler kHandler{};
+  void set_handler(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Handler::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Targets =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ShellTransition_Target,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_Targets kTargets{};
+  template <typename T = ShellTransition_Target> T* add_targets() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_MergeTarget =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_MergeTarget kMergeTarget{};
+  void set_merge_target(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MergeTarget::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartingWindowRemoveTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ShellTransition>;
+
+  static constexpr FieldMetadata_StartingWindowRemoveTimeNs kStartingWindowRemoveTimeNs{};
+  void set_starting_window_remove_time_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartingWindowRemoveTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ShellTransition_Target_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ShellTransition_Target_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ShellTransition_Target_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ShellTransition_Target_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+  bool has_layer_id() const { return at<2>().valid(); }
+  int32_t layer_id() const { return at<2>().as_int32(); }
+  bool has_window_id() const { return at<3>().valid(); }
+  int32_t window_id() const { return at<3>().as_int32(); }
+  bool has_flags() const { return at<4>().valid(); }
+  int32_t flags() const { return at<4>().as_int32(); }
+};
+
+class ShellTransition_Target : public ::protozero::Message {
+ public:
+  using Decoder = ShellTransition_Target_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+    kLayerIdFieldNumber = 2,
+    kWindowIdFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ShellTransition.Target"; }
+
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition_Target>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition_Target>;
+
+  static constexpr FieldMetadata_LayerId kLayerId{};
+  void set_layer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WindowId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition_Target>;
+
+  static constexpr FieldMetadata_WindowId kWindowId{};
+  void set_window_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WindowId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ShellTransition_Target>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/surfaceflinger_common.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_COMMON_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_COMMON_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class RectProto;
+class RegionProto;
+class TransformProto;
+
+class ColorTransformProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ColorTransformProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ColorTransformProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ColorTransformProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_val() const { return at<1>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kFixed32, float> val(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kFixed32, float>(1, parse_error_ptr); }
+};
+
+class ColorTransformProto : public ::protozero::Message {
+ public:
+  using Decoder = ColorTransformProto_Decoder;
+  enum : int32_t {
+    kValFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ColorTransformProto"; }
+
+
+  using FieldMetadata_Val =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      ColorTransformProto>;
+
+  static constexpr FieldMetadata_Val kVal{};
+  void set_val(const ::protozero::PackedFixedSizeInt<float>& packed_buffer) {
+    AppendBytes(FieldMetadata_Val::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+};
+
+class BlurRegion_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlurRegion_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlurRegion_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlurRegion_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_blur_radius() const { return at<1>().valid(); }
+  uint32_t blur_radius() const { return at<1>().as_uint32(); }
+  bool has_corner_radius_tl() const { return at<2>().valid(); }
+  uint32_t corner_radius_tl() const { return at<2>().as_uint32(); }
+  bool has_corner_radius_tr() const { return at<3>().valid(); }
+  uint32_t corner_radius_tr() const { return at<3>().as_uint32(); }
+  bool has_corner_radius_bl() const { return at<4>().valid(); }
+  uint32_t corner_radius_bl() const { return at<4>().as_uint32(); }
+  bool has_corner_radius_br() const { return at<5>().valid(); }
+  float corner_radius_br() const { return at<5>().as_float(); }
+  bool has_alpha() const { return at<6>().valid(); }
+  float alpha() const { return at<6>().as_float(); }
+  bool has_left() const { return at<7>().valid(); }
+  int32_t left() const { return at<7>().as_int32(); }
+  bool has_top() const { return at<8>().valid(); }
+  int32_t top() const { return at<8>().as_int32(); }
+  bool has_right() const { return at<9>().valid(); }
+  int32_t right() const { return at<9>().as_int32(); }
+  bool has_bottom() const { return at<10>().valid(); }
+  int32_t bottom() const { return at<10>().as_int32(); }
+};
+
+class BlurRegion : public ::protozero::Message {
+ public:
+  using Decoder = BlurRegion_Decoder;
+  enum : int32_t {
+    kBlurRadiusFieldNumber = 1,
+    kCornerRadiusTlFieldNumber = 2,
+    kCornerRadiusTrFieldNumber = 3,
+    kCornerRadiusBlFieldNumber = 4,
+    kCornerRadiusBrFieldNumber = 5,
+    kAlphaFieldNumber = 6,
+    kLeftFieldNumber = 7,
+    kTopFieldNumber = 8,
+    kRightFieldNumber = 9,
+    kBottomFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlurRegion"; }
+
+
+  using FieldMetadata_BlurRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_BlurRadius kBlurRadius{};
+  void set_blur_radius(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlurRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CornerRadiusTl =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_CornerRadiusTl kCornerRadiusTl{};
+  void set_corner_radius_tl(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadiusTl::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CornerRadiusTr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_CornerRadiusTr kCornerRadiusTr{};
+  void set_corner_radius_tr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadiusTr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CornerRadiusBl =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_CornerRadiusBl kCornerRadiusBl{};
+  void set_corner_radius_bl(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadiusBl::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CornerRadiusBr =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_CornerRadiusBr kCornerRadiusBr{};
+  void set_corner_radius_br(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadiusBr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Alpha =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_Alpha kAlpha{};
+  void set_alpha(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Alpha::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Left =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_Left kLeft{};
+  void set_left(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Left::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Top =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_Top kTop{};
+  void set_top(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Top::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Right =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_Right kRight{};
+  void set_right(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Right::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Bottom =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlurRegion>;
+
+  static constexpr FieldMetadata_Bottom kBottom{};
+  void set_bottom(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bottom::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class InputWindowInfoProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/17, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InputWindowInfoProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InputWindowInfoProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InputWindowInfoProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layout_params_flags() const { return at<1>().valid(); }
+  uint32_t layout_params_flags() const { return at<1>().as_uint32(); }
+  bool has_layout_params_type() const { return at<2>().valid(); }
+  int32_t layout_params_type() const { return at<2>().as_int32(); }
+  bool has_frame() const { return at<3>().valid(); }
+  ::protozero::ConstBytes frame() const { return at<3>().as_bytes(); }
+  bool has_touchable_region() const { return at<4>().valid(); }
+  ::protozero::ConstBytes touchable_region() const { return at<4>().as_bytes(); }
+  bool has_surface_inset() const { return at<5>().valid(); }
+  int32_t surface_inset() const { return at<5>().as_int32(); }
+  bool has_visible() const { return at<6>().valid(); }
+  bool visible() const { return at<6>().as_bool(); }
+  bool has_can_receive_keys() const { return at<7>().valid(); }
+  bool can_receive_keys() const { return at<7>().as_bool(); }
+  bool has_focusable() const { return at<8>().valid(); }
+  bool focusable() const { return at<8>().as_bool(); }
+  bool has_has_wallpaper() const { return at<9>().valid(); }
+  bool has_wallpaper() const { return at<9>().as_bool(); }
+  bool has_global_scale_factor() const { return at<10>().valid(); }
+  float global_scale_factor() const { return at<10>().as_float(); }
+  bool has_window_x_scale() const { return at<11>().valid(); }
+  float window_x_scale() const { return at<11>().as_float(); }
+  bool has_window_y_scale() const { return at<12>().valid(); }
+  float window_y_scale() const { return at<12>().as_float(); }
+  bool has_crop_layer_id() const { return at<13>().valid(); }
+  int32_t crop_layer_id() const { return at<13>().as_int32(); }
+  bool has_replace_touchable_region_with_crop() const { return at<14>().valid(); }
+  bool replace_touchable_region_with_crop() const { return at<14>().as_bool(); }
+  bool has_touchable_region_crop() const { return at<15>().valid(); }
+  ::protozero::ConstBytes touchable_region_crop() const { return at<15>().as_bytes(); }
+  bool has_transform() const { return at<16>().valid(); }
+  ::protozero::ConstBytes transform() const { return at<16>().as_bytes(); }
+  bool has_input_config() const { return at<17>().valid(); }
+  uint32_t input_config() const { return at<17>().as_uint32(); }
+};
+
+class InputWindowInfoProto : public ::protozero::Message {
+ public:
+  using Decoder = InputWindowInfoProto_Decoder;
+  enum : int32_t {
+    kLayoutParamsFlagsFieldNumber = 1,
+    kLayoutParamsTypeFieldNumber = 2,
+    kFrameFieldNumber = 3,
+    kTouchableRegionFieldNumber = 4,
+    kSurfaceInsetFieldNumber = 5,
+    kVisibleFieldNumber = 6,
+    kCanReceiveKeysFieldNumber = 7,
+    kFocusableFieldNumber = 8,
+    kHasWallpaperFieldNumber = 9,
+    kGlobalScaleFactorFieldNumber = 10,
+    kWindowXScaleFieldNumber = 11,
+    kWindowYScaleFieldNumber = 12,
+    kCropLayerIdFieldNumber = 13,
+    kReplaceTouchableRegionWithCropFieldNumber = 14,
+    kTouchableRegionCropFieldNumber = 15,
+    kTransformFieldNumber = 16,
+    kInputConfigFieldNumber = 17,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InputWindowInfoProto"; }
+
+
+  using FieldMetadata_LayoutParamsFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_LayoutParamsFlags kLayoutParamsFlags{};
+  void set_layout_params_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayoutParamsFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayoutParamsType =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_LayoutParamsType kLayoutParamsType{};
+  void set_layout_params_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayoutParamsType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Frame =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_Frame kFrame{};
+  template <typename T = RectProto> T* set_frame() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_TouchableRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_TouchableRegion kTouchableRegion{};
+  template <typename T = RegionProto> T* set_touchable_region() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_SurfaceInset =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_SurfaceInset kSurfaceInset{};
+  void set_surface_inset(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SurfaceInset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Visible =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_Visible kVisible{};
+  void set_visible(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Visible::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CanReceiveKeys =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_CanReceiveKeys kCanReceiveKeys{};
+  void set_can_receive_keys(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CanReceiveKeys::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Focusable =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_Focusable kFocusable{};
+  void set_focusable(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Focusable::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasWallpaper =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_HasWallpaper kHasWallpaper{};
+  void set_has_wallpaper(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasWallpaper::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GlobalScaleFactor =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_GlobalScaleFactor kGlobalScaleFactor{};
+  void set_global_scale_factor(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_GlobalScaleFactor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WindowXScale =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_WindowXScale kWindowXScale{};
+  void set_window_x_scale(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_WindowXScale::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WindowYScale =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_WindowYScale kWindowYScale{};
+  void set_window_y_scale(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_WindowYScale::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CropLayerId =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_CropLayerId kCropLayerId{};
+  void set_crop_layer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CropLayerId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReplaceTouchableRegionWithCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_ReplaceTouchableRegionWithCrop kReplaceTouchableRegionWithCrop{};
+  void set_replace_touchable_region_with_crop(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReplaceTouchableRegionWithCrop::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TouchableRegionCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_TouchableRegionCrop kTouchableRegionCrop{};
+  template <typename T = RectProto> T* set_touchable_region_crop() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  template <typename T = TransformProto> T* set_transform() {
+    return BeginNestedMessage<T>(16);
+  }
+
+
+  using FieldMetadata_InputConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InputWindowInfoProto>;
+
+  static constexpr FieldMetadata_InputConfig kInputConfig{};
+  void set_input_config(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputConfig::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ColorProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ColorProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ColorProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ColorProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_r() const { return at<1>().valid(); }
+  float r() const { return at<1>().as_float(); }
+  bool has_g() const { return at<2>().valid(); }
+  float g() const { return at<2>().as_float(); }
+  bool has_b() const { return at<3>().valid(); }
+  float b() const { return at<3>().as_float(); }
+  bool has_a() const { return at<4>().valid(); }
+  float a() const { return at<4>().as_float(); }
+};
+
+class ColorProto : public ::protozero::Message {
+ public:
+  using Decoder = ColorProto_Decoder;
+  enum : int32_t {
+    kRFieldNumber = 1,
+    kGFieldNumber = 2,
+    kBFieldNumber = 3,
+    kAFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ColorProto"; }
+
+
+  using FieldMetadata_R =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      ColorProto>;
+
+  static constexpr FieldMetadata_R kR{};
+  void set_r(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_R::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_G =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      ColorProto>;
+
+  static constexpr FieldMetadata_G kG{};
+  void set_g(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_G::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_B =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      ColorProto>;
+
+  static constexpr FieldMetadata_B kB{};
+  void set_b(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_B::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_A =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      ColorProto>;
+
+  static constexpr FieldMetadata_A kA{};
+  void set_a(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_A::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TransformProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TransformProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TransformProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TransformProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dsdx() const { return at<1>().valid(); }
+  float dsdx() const { return at<1>().as_float(); }
+  bool has_dtdx() const { return at<2>().valid(); }
+  float dtdx() const { return at<2>().as_float(); }
+  bool has_dsdy() const { return at<3>().valid(); }
+  float dsdy() const { return at<3>().as_float(); }
+  bool has_dtdy() const { return at<4>().valid(); }
+  float dtdy() const { return at<4>().as_float(); }
+  bool has_type() const { return at<5>().valid(); }
+  int32_t type() const { return at<5>().as_int32(); }
+};
+
+class TransformProto : public ::protozero::Message {
+ public:
+  using Decoder = TransformProto_Decoder;
+  enum : int32_t {
+    kDsdxFieldNumber = 1,
+    kDtdxFieldNumber = 2,
+    kDsdyFieldNumber = 3,
+    kDtdyFieldNumber = 4,
+    kTypeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TransformProto"; }
+
+
+  using FieldMetadata_Dsdx =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TransformProto>;
+
+  static constexpr FieldMetadata_Dsdx kDsdx{};
+  void set_dsdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TransformProto>;
+
+  static constexpr FieldMetadata_Dtdx kDtdx{};
+  void set_dtdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dsdy =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TransformProto>;
+
+  static constexpr FieldMetadata_Dsdy kDsdy{};
+  void set_dsdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdy =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      TransformProto>;
+
+  static constexpr FieldMetadata_Dtdy kDtdy{};
+  void set_dtdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TransformProto>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SizeProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SizeProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SizeProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SizeProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_w() const { return at<1>().valid(); }
+  int32_t w() const { return at<1>().as_int32(); }
+  bool has_h() const { return at<2>().valid(); }
+  int32_t h() const { return at<2>().as_int32(); }
+};
+
+class SizeProto : public ::protozero::Message {
+ public:
+  using Decoder = SizeProto_Decoder;
+  enum : int32_t {
+    kWFieldNumber = 1,
+    kHFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SizeProto"; }
+
+
+  using FieldMetadata_W =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SizeProto>;
+
+  static constexpr FieldMetadata_W kW{};
+  void set_w(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_W::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_H =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SizeProto>;
+
+  static constexpr FieldMetadata_H kH{};
+  void set_h(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_H::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class RectProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RectProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RectProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RectProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_left() const { return at<1>().valid(); }
+  int32_t left() const { return at<1>().as_int32(); }
+  bool has_top() const { return at<2>().valid(); }
+  int32_t top() const { return at<2>().as_int32(); }
+  bool has_right() const { return at<3>().valid(); }
+  int32_t right() const { return at<3>().as_int32(); }
+  bool has_bottom() const { return at<4>().valid(); }
+  int32_t bottom() const { return at<4>().as_int32(); }
+};
+
+class RectProto : public ::protozero::Message {
+ public:
+  using Decoder = RectProto_Decoder;
+  enum : int32_t {
+    kLeftFieldNumber = 1,
+    kTopFieldNumber = 2,
+    kRightFieldNumber = 3,
+    kBottomFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RectProto"; }
+
+
+  using FieldMetadata_Left =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RectProto>;
+
+  static constexpr FieldMetadata_Left kLeft{};
+  void set_left(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Left::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Top =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RectProto>;
+
+  static constexpr FieldMetadata_Top kTop{};
+  void set_top(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Top::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Right =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RectProto>;
+
+  static constexpr FieldMetadata_Right kRight{};
+  void set_right(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Right::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Bottom =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RectProto>;
+
+  static constexpr FieldMetadata_Bottom kBottom{};
+  void set_bottom(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bottom::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class RegionProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  RegionProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegionProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegionProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rect() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> rect() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class RegionProto : public ::protozero::Message {
+ public:
+  using Decoder = RegionProto_Decoder;
+  enum : int32_t {
+    kRectFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegionProto"; }
+
+
+  using FieldMetadata_Rect =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      RegionProto>;
+
+  static constexpr FieldMetadata_Rect kRect{};
+  template <typename T = RectProto> T* add_rect() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/surfaceflinger_layers.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_LAYERS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_LAYERS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ActiveBufferProto;
+class BarrierLayerProto;
+class BlurRegion;
+class ColorProto;
+class ColorTransformProto;
+class DisplayProto;
+class FloatRectProto;
+class InputWindowInfoProto;
+class LayerProto;
+class LayerProto_MetadataEntry;
+class LayersProto;
+class LayersSnapshotProto;
+class PositionProto;
+class RectProto;
+class RegionProto;
+class SizeProto;
+class TransformProto;
+enum HwcCompositionType : int32_t;
+
+enum HwcCompositionType : int32_t {
+  HWC_TYPE_UNSPECIFIED = 0,
+  HWC_TYPE_CLIENT = 1,
+  HWC_TYPE_DEVICE = 2,
+  HWC_TYPE_SOLID_COLOR = 3,
+  HWC_TYPE_CURSOR = 4,
+  HWC_TYPE_SIDEBAND = 5,
+};
+
+constexpr HwcCompositionType HwcCompositionType_MIN = HwcCompositionType::HWC_TYPE_UNSPECIFIED;
+constexpr HwcCompositionType HwcCompositionType_MAX = HwcCompositionType::HWC_TYPE_SIDEBAND;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* HwcCompositionType_Name(::perfetto::protos::pbzero::HwcCompositionType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_UNSPECIFIED:
+    return "HWC_TYPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_CLIENT:
+    return "HWC_TYPE_CLIENT";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_DEVICE:
+    return "HWC_TYPE_DEVICE";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_SOLID_COLOR:
+    return "HWC_TYPE_SOLID_COLOR";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_CURSOR:
+    return "HWC_TYPE_CURSOR";
+
+  case ::perfetto::protos::pbzero::HwcCompositionType::HWC_TYPE_SIDEBAND:
+    return "HWC_TYPE_SIDEBAND";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayersTraceFileProto {
+enum MagicNumber : int32_t {
+  INVALID = 0,
+  MAGIC_NUMBER_L = 1414682956,
+  MAGIC_NUMBER_H = 1162035538,
+};
+} // namespace perfetto_pbzero_enum_LayersTraceFileProto
+using LayersTraceFileProto_MagicNumber = perfetto_pbzero_enum_LayersTraceFileProto::MagicNumber;
+
+
+constexpr LayersTraceFileProto_MagicNumber LayersTraceFileProto_MagicNumber_MIN = LayersTraceFileProto_MagicNumber::INVALID;
+constexpr LayersTraceFileProto_MagicNumber LayersTraceFileProto_MagicNumber_MAX = LayersTraceFileProto_MagicNumber::MAGIC_NUMBER_L;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayersTraceFileProto_MagicNumber_Name(::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber::INVALID:
+    return "INVALID";
+
+  case ::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber::MAGIC_NUMBER_L:
+    return "MAGIC_NUMBER_L";
+
+  case ::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber::MAGIC_NUMBER_H:
+    return "MAGIC_NUMBER_H";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class BarrierLayerProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BarrierLayerProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BarrierLayerProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BarrierLayerProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_frame_number() const { return at<2>().valid(); }
+  uint64_t frame_number() const { return at<2>().as_uint64(); }
+};
+
+class BarrierLayerProto : public ::protozero::Message {
+ public:
+  using Decoder = BarrierLayerProto_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kFrameNumberFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BarrierLayerProto"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BarrierLayerProto>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BarrierLayerProto>;
+
+  static constexpr FieldMetadata_FrameNumber kFrameNumber{};
+  void set_frame_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ActiveBufferProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ActiveBufferProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ActiveBufferProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ActiveBufferProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_width() const { return at<1>().valid(); }
+  uint32_t width() const { return at<1>().as_uint32(); }
+  bool has_height() const { return at<2>().valid(); }
+  uint32_t height() const { return at<2>().as_uint32(); }
+  bool has_stride() const { return at<3>().valid(); }
+  uint32_t stride() const { return at<3>().as_uint32(); }
+  bool has_format() const { return at<4>().valid(); }
+  int32_t format() const { return at<4>().as_int32(); }
+  bool has_usage() const { return at<5>().valid(); }
+  uint64_t usage() const { return at<5>().as_uint64(); }
+};
+
+class ActiveBufferProto : public ::protozero::Message {
+ public:
+  using Decoder = ActiveBufferProto_Decoder;
+  enum : int32_t {
+    kWidthFieldNumber = 1,
+    kHeightFieldNumber = 2,
+    kStrideFieldNumber = 3,
+    kFormatFieldNumber = 4,
+    kUsageFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ActiveBufferProto"; }
+
+
+  using FieldMetadata_Width =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ActiveBufferProto>;
+
+  static constexpr FieldMetadata_Width kWidth{};
+  void set_width(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Width::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Height =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ActiveBufferProto>;
+
+  static constexpr FieldMetadata_Height kHeight{};
+  void set_height(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Height::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Stride =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ActiveBufferProto>;
+
+  static constexpr FieldMetadata_Stride kStride{};
+  void set_stride(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Stride::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Format =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ActiveBufferProto>;
+
+  static constexpr FieldMetadata_Format kFormat{};
+  void set_format(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Format::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Usage =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ActiveBufferProto>;
+
+  static constexpr FieldMetadata_Usage kUsage{};
+  void set_usage(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Usage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FloatRectProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FloatRectProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FloatRectProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FloatRectProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_left() const { return at<1>().valid(); }
+  float left() const { return at<1>().as_float(); }
+  bool has_top() const { return at<2>().valid(); }
+  float top() const { return at<2>().as_float(); }
+  bool has_right() const { return at<3>().valid(); }
+  float right() const { return at<3>().as_float(); }
+  bool has_bottom() const { return at<4>().valid(); }
+  float bottom() const { return at<4>().as_float(); }
+};
+
+class FloatRectProto : public ::protozero::Message {
+ public:
+  using Decoder = FloatRectProto_Decoder;
+  enum : int32_t {
+    kLeftFieldNumber = 1,
+    kTopFieldNumber = 2,
+    kRightFieldNumber = 3,
+    kBottomFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FloatRectProto"; }
+
+
+  using FieldMetadata_Left =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      FloatRectProto>;
+
+  static constexpr FieldMetadata_Left kLeft{};
+  void set_left(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Left::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Top =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      FloatRectProto>;
+
+  static constexpr FieldMetadata_Top kTop{};
+  void set_top(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Top::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Right =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      FloatRectProto>;
+
+  static constexpr FieldMetadata_Right kRight{};
+  void set_right(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Right::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Bottom =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      FloatRectProto>;
+
+  static constexpr FieldMetadata_Bottom kBottom{};
+  void set_bottom(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bottom::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PositionProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PositionProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PositionProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PositionProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_x() const { return at<1>().valid(); }
+  float x() const { return at<1>().as_float(); }
+  bool has_y() const { return at<2>().valid(); }
+  float y() const { return at<2>().as_float(); }
+};
+
+class PositionProto : public ::protozero::Message {
+ public:
+  using Decoder = PositionProto_Decoder;
+  enum : int32_t {
+    kXFieldNumber = 1,
+    kYFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PositionProto"; }
+
+
+  using FieldMetadata_X =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      PositionProto>;
+
+  static constexpr FieldMetadata_X kX{};
+  void set_x(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_X::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Y =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      PositionProto>;
+
+  static constexpr FieldMetadata_Y kY{};
+  void set_y(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Y::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/58, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  LayerProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_children() const { return at<3>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> children(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(3, parse_error_ptr); }
+  bool has_relatives() const { return at<4>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> relatives(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(4, parse_error_ptr); }
+  bool has_type() const { return at<5>().valid(); }
+  ::protozero::ConstChars type() const { return at<5>().as_string(); }
+  bool has_transparent_region() const { return at<6>().valid(); }
+  ::protozero::ConstBytes transparent_region() const { return at<6>().as_bytes(); }
+  bool has_visible_region() const { return at<7>().valid(); }
+  ::protozero::ConstBytes visible_region() const { return at<7>().as_bytes(); }
+  bool has_damage_region() const { return at<8>().valid(); }
+  ::protozero::ConstBytes damage_region() const { return at<8>().as_bytes(); }
+  bool has_layer_stack() const { return at<9>().valid(); }
+  uint32_t layer_stack() const { return at<9>().as_uint32(); }
+  bool has_z() const { return at<10>().valid(); }
+  int32_t z() const { return at<10>().as_int32(); }
+  bool has_position() const { return at<11>().valid(); }
+  ::protozero::ConstBytes position() const { return at<11>().as_bytes(); }
+  bool has_requested_position() const { return at<12>().valid(); }
+  ::protozero::ConstBytes requested_position() const { return at<12>().as_bytes(); }
+  bool has_size() const { return at<13>().valid(); }
+  ::protozero::ConstBytes size() const { return at<13>().as_bytes(); }
+  bool has_crop() const { return at<14>().valid(); }
+  ::protozero::ConstBytes crop() const { return at<14>().as_bytes(); }
+  bool has_final_crop() const { return at<15>().valid(); }
+  ::protozero::ConstBytes final_crop() const { return at<15>().as_bytes(); }
+  bool has_is_opaque() const { return at<16>().valid(); }
+  bool is_opaque() const { return at<16>().as_bool(); }
+  bool has_invalidate() const { return at<17>().valid(); }
+  bool invalidate() const { return at<17>().as_bool(); }
+  bool has_dataspace() const { return at<18>().valid(); }
+  ::protozero::ConstChars dataspace() const { return at<18>().as_string(); }
+  bool has_pixel_format() const { return at<19>().valid(); }
+  ::protozero::ConstChars pixel_format() const { return at<19>().as_string(); }
+  bool has_color() const { return at<20>().valid(); }
+  ::protozero::ConstBytes color() const { return at<20>().as_bytes(); }
+  bool has_requested_color() const { return at<21>().valid(); }
+  ::protozero::ConstBytes requested_color() const { return at<21>().as_bytes(); }
+  bool has_flags() const { return at<22>().valid(); }
+  uint32_t flags() const { return at<22>().as_uint32(); }
+  bool has_transform() const { return at<23>().valid(); }
+  ::protozero::ConstBytes transform() const { return at<23>().as_bytes(); }
+  bool has_requested_transform() const { return at<24>().valid(); }
+  ::protozero::ConstBytes requested_transform() const { return at<24>().as_bytes(); }
+  bool has_parent() const { return at<25>().valid(); }
+  int32_t parent() const { return at<25>().as_int32(); }
+  bool has_z_order_relative_of() const { return at<26>().valid(); }
+  int32_t z_order_relative_of() const { return at<26>().as_int32(); }
+  bool has_active_buffer() const { return at<27>().valid(); }
+  ::protozero::ConstBytes active_buffer() const { return at<27>().as_bytes(); }
+  bool has_queued_frames() const { return at<28>().valid(); }
+  int32_t queued_frames() const { return at<28>().as_int32(); }
+  bool has_refresh_pending() const { return at<29>().valid(); }
+  bool refresh_pending() const { return at<29>().as_bool(); }
+  bool has_hwc_frame() const { return at<30>().valid(); }
+  ::protozero::ConstBytes hwc_frame() const { return at<30>().as_bytes(); }
+  bool has_hwc_crop() const { return at<31>().valid(); }
+  ::protozero::ConstBytes hwc_crop() const { return at<31>().as_bytes(); }
+  bool has_hwc_transform() const { return at<32>().valid(); }
+  int32_t hwc_transform() const { return at<32>().as_int32(); }
+  bool has_window_type() const { return at<33>().valid(); }
+  int32_t window_type() const { return at<33>().as_int32(); }
+  bool has_app_id() const { return at<34>().valid(); }
+  int32_t app_id() const { return at<34>().as_int32(); }
+  bool has_hwc_composition_type() const { return at<35>().valid(); }
+  int32_t hwc_composition_type() const { return at<35>().as_int32(); }
+  bool has_is_protected() const { return at<36>().valid(); }
+  bool is_protected() const { return at<36>().as_bool(); }
+  bool has_curr_frame() const { return at<37>().valid(); }
+  uint64_t curr_frame() const { return at<37>().as_uint64(); }
+  bool has_barrier_layer() const { return at<38>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> barrier_layer() const { return GetRepeated<::protozero::ConstBytes>(38); }
+  bool has_buffer_transform() const { return at<39>().valid(); }
+  ::protozero::ConstBytes buffer_transform() const { return at<39>().as_bytes(); }
+  bool has_effective_scaling_mode() const { return at<40>().valid(); }
+  int32_t effective_scaling_mode() const { return at<40>().as_int32(); }
+  bool has_corner_radius() const { return at<41>().valid(); }
+  float corner_radius() const { return at<41>().as_float(); }
+  bool has_metadata() const { return at<42>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> metadata() const { return GetRepeated<::protozero::ConstBytes>(42); }
+  bool has_effective_transform() const { return at<43>().valid(); }
+  ::protozero::ConstBytes effective_transform() const { return at<43>().as_bytes(); }
+  bool has_source_bounds() const { return at<44>().valid(); }
+  ::protozero::ConstBytes source_bounds() const { return at<44>().as_bytes(); }
+  bool has_bounds() const { return at<45>().valid(); }
+  ::protozero::ConstBytes bounds() const { return at<45>().as_bytes(); }
+  bool has_screen_bounds() const { return at<46>().valid(); }
+  ::protozero::ConstBytes screen_bounds() const { return at<46>().as_bytes(); }
+  bool has_input_window_info() const { return at<47>().valid(); }
+  ::protozero::ConstBytes input_window_info() const { return at<47>().as_bytes(); }
+  bool has_corner_radius_crop() const { return at<48>().valid(); }
+  ::protozero::ConstBytes corner_radius_crop() const { return at<48>().as_bytes(); }
+  bool has_shadow_radius() const { return at<49>().valid(); }
+  float shadow_radius() const { return at<49>().as_float(); }
+  bool has_color_transform() const { return at<50>().valid(); }
+  ::protozero::ConstBytes color_transform() const { return at<50>().as_bytes(); }
+  bool has_is_relative_of() const { return at<51>().valid(); }
+  bool is_relative_of() const { return at<51>().as_bool(); }
+  bool has_background_blur_radius() const { return at<52>().valid(); }
+  int32_t background_blur_radius() const { return at<52>().as_int32(); }
+  bool has_owner_uid() const { return at<53>().valid(); }
+  uint32_t owner_uid() const { return at<53>().as_uint32(); }
+  bool has_blur_regions() const { return at<54>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> blur_regions() const { return GetRepeated<::protozero::ConstBytes>(54); }
+  bool has_is_trusted_overlay() const { return at<55>().valid(); }
+  bool is_trusted_overlay() const { return at<55>().as_bool(); }
+  bool has_requested_corner_radius() const { return at<56>().valid(); }
+  float requested_corner_radius() const { return at<56>().as_float(); }
+  bool has_destination_frame() const { return at<57>().valid(); }
+  ::protozero::ConstBytes destination_frame() const { return at<57>().as_bytes(); }
+  bool has_original_id() const { return at<58>().valid(); }
+  uint32_t original_id() const { return at<58>().as_uint32(); }
+};
+
+class LayerProto : public ::protozero::Message {
+ public:
+  using Decoder = LayerProto_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kChildrenFieldNumber = 3,
+    kRelativesFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kTransparentRegionFieldNumber = 6,
+    kVisibleRegionFieldNumber = 7,
+    kDamageRegionFieldNumber = 8,
+    kLayerStackFieldNumber = 9,
+    kZFieldNumber = 10,
+    kPositionFieldNumber = 11,
+    kRequestedPositionFieldNumber = 12,
+    kSizeFieldNumber = 13,
+    kCropFieldNumber = 14,
+    kFinalCropFieldNumber = 15,
+    kIsOpaqueFieldNumber = 16,
+    kInvalidateFieldNumber = 17,
+    kDataspaceFieldNumber = 18,
+    kPixelFormatFieldNumber = 19,
+    kColorFieldNumber = 20,
+    kRequestedColorFieldNumber = 21,
+    kFlagsFieldNumber = 22,
+    kTransformFieldNumber = 23,
+    kRequestedTransformFieldNumber = 24,
+    kParentFieldNumber = 25,
+    kZOrderRelativeOfFieldNumber = 26,
+    kActiveBufferFieldNumber = 27,
+    kQueuedFramesFieldNumber = 28,
+    kRefreshPendingFieldNumber = 29,
+    kHwcFrameFieldNumber = 30,
+    kHwcCropFieldNumber = 31,
+    kHwcTransformFieldNumber = 32,
+    kWindowTypeFieldNumber = 33,
+    kAppIdFieldNumber = 34,
+    kHwcCompositionTypeFieldNumber = 35,
+    kIsProtectedFieldNumber = 36,
+    kCurrFrameFieldNumber = 37,
+    kBarrierLayerFieldNumber = 38,
+    kBufferTransformFieldNumber = 39,
+    kEffectiveScalingModeFieldNumber = 40,
+    kCornerRadiusFieldNumber = 41,
+    kMetadataFieldNumber = 42,
+    kEffectiveTransformFieldNumber = 43,
+    kSourceBoundsFieldNumber = 44,
+    kBoundsFieldNumber = 45,
+    kScreenBoundsFieldNumber = 46,
+    kInputWindowInfoFieldNumber = 47,
+    kCornerRadiusCropFieldNumber = 48,
+    kShadowRadiusFieldNumber = 49,
+    kColorTransformFieldNumber = 50,
+    kIsRelativeOfFieldNumber = 51,
+    kBackgroundBlurRadiusFieldNumber = 52,
+    kOwnerUidFieldNumber = 53,
+    kBlurRegionsFieldNumber = 54,
+    kIsTrustedOverlayFieldNumber = 55,
+    kRequestedCornerRadiusFieldNumber = 56,
+    kDestinationFrameFieldNumber = 57,
+    kOriginalIdFieldNumber = 58,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerProto"; }
+
+  using MetadataEntry = ::perfetto::protos::pbzero::LayerProto_MetadataEntry;
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Children =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Children kChildren{};
+  void set_children(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_Children::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_Relatives =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Relatives kRelatives{};
+  void set_relatives(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_Relatives::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Type::kFieldId, data, size);
+  }
+  void set_type(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Type::kFieldId, chars.data, chars.size);
+  }
+  void set_type(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TransparentRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_TransparentRegion kTransparentRegion{};
+  template <typename T = RegionProto> T* set_transparent_region() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_VisibleRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_VisibleRegion kVisibleRegion{};
+  template <typename T = RegionProto> T* set_visible_region() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_DamageRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_DamageRegion kDamageRegion{};
+  template <typename T = RegionProto> T* set_damage_region() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_LayerStack =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_LayerStack kLayerStack{};
+  void set_layer_stack(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStack::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Z =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Z kZ{};
+  void set_z(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Z::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Position =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PositionProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Position kPosition{};
+  template <typename T = PositionProto> T* set_position() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_RequestedPosition =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PositionProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_RequestedPosition kRequestedPosition{};
+  template <typename T = PositionProto> T* set_requested_position() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SizeProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  template <typename T = SizeProto> T* set_size() {
+    return BeginNestedMessage<T>(13);
+  }
+
+
+  using FieldMetadata_Crop =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Crop kCrop{};
+  template <typename T = RectProto> T* set_crop() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_FinalCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_FinalCrop kFinalCrop{};
+  template <typename T = RectProto> T* set_final_crop() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_IsOpaque =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_IsOpaque kIsOpaque{};
+  void set_is_opaque(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsOpaque::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Invalidate =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Invalidate kInvalidate{};
+  void set_invalidate(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Invalidate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dataspace =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Dataspace kDataspace{};
+  void set_dataspace(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Dataspace::kFieldId, data, size);
+  }
+  void set_dataspace(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Dataspace::kFieldId, chars.data, chars.size);
+  }
+  void set_dataspace(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dataspace::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PixelFormat =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerProto>;
+
+  static constexpr FieldMetadata_PixelFormat kPixelFormat{};
+  void set_pixel_format(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PixelFormat::kFieldId, data, size);
+  }
+  void set_pixel_format(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PixelFormat::kFieldId, chars.data, chars.size);
+  }
+  void set_pixel_format(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PixelFormat::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Color =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ColorProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Color kColor{};
+  template <typename T = ColorProto> T* set_color() {
+    return BeginNestedMessage<T>(20);
+  }
+
+
+  using FieldMetadata_RequestedColor =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ColorProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_RequestedColor kRequestedColor{};
+  template <typename T = ColorProto> T* set_requested_color() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  template <typename T = TransformProto> T* set_transform() {
+    return BeginNestedMessage<T>(23);
+  }
+
+
+  using FieldMetadata_RequestedTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_RequestedTransform kRequestedTransform{};
+  template <typename T = TransformProto> T* set_requested_transform() {
+    return BeginNestedMessage<T>(24);
+  }
+
+
+  using FieldMetadata_Parent =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Parent kParent{};
+  void set_parent(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Parent::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ZOrderRelativeOf =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_ZOrderRelativeOf kZOrderRelativeOf{};
+  void set_z_order_relative_of(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ZOrderRelativeOf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ActiveBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ActiveBufferProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_ActiveBuffer kActiveBuffer{};
+  template <typename T = ActiveBufferProto> T* set_active_buffer() {
+    return BeginNestedMessage<T>(27);
+  }
+
+
+  using FieldMetadata_QueuedFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_QueuedFrames kQueuedFrames{};
+  void set_queued_frames(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_QueuedFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RefreshPending =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_RefreshPending kRefreshPending{};
+  void set_refresh_pending(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_RefreshPending::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HwcFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_HwcFrame kHwcFrame{};
+  template <typename T = RectProto> T* set_hwc_frame() {
+    return BeginNestedMessage<T>(30);
+  }
+
+
+  using FieldMetadata_HwcCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FloatRectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_HwcCrop kHwcCrop{};
+  template <typename T = FloatRectProto> T* set_hwc_crop() {
+    return BeginNestedMessage<T>(31);
+  }
+
+
+  using FieldMetadata_HwcTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_HwcTransform kHwcTransform{};
+  void set_hwc_transform(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwcTransform::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WindowType =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_WindowType kWindowType{};
+  void set_window_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WindowType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AppId =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_AppId kAppId{};
+  void set_app_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HwcCompositionType =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::HwcCompositionType,
+      LayerProto>;
+
+  static constexpr FieldMetadata_HwcCompositionType kHwcCompositionType{};
+  void set_hwc_composition_type(::perfetto::protos::pbzero::HwcCompositionType value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwcCompositionType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsProtected =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_IsProtected kIsProtected{};
+  void set_is_protected(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsProtected::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CurrFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_CurrFrame kCurrFrame{};
+  void set_curr_frame(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrFrame::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BarrierLayer =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BarrierLayerProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_BarrierLayer kBarrierLayer{};
+  template <typename T = BarrierLayerProto> T* add_barrier_layer() {
+    return BeginNestedMessage<T>(38);
+  }
+
+
+  using FieldMetadata_BufferTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_BufferTransform kBufferTransform{};
+  template <typename T = TransformProto> T* set_buffer_transform() {
+    return BeginNestedMessage<T>(39);
+  }
+
+
+  using FieldMetadata_EffectiveScalingMode =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_EffectiveScalingMode kEffectiveScalingMode{};
+  void set_effective_scaling_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EffectiveScalingMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CornerRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerProto>;
+
+  static constexpr FieldMetadata_CornerRadius kCornerRadius{};
+  void set_corner_radius(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Metadata =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerProto_MetadataEntry,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Metadata kMetadata{};
+  template <typename T = LayerProto_MetadataEntry> T* add_metadata() {
+    return BeginNestedMessage<T>(42);
+  }
+
+
+  using FieldMetadata_EffectiveTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      43,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_EffectiveTransform kEffectiveTransform{};
+  template <typename T = TransformProto> T* set_effective_transform() {
+    return BeginNestedMessage<T>(43);
+  }
+
+
+  using FieldMetadata_SourceBounds =
+    ::protozero::proto_utils::FieldMetadata<
+      44,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FloatRectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_SourceBounds kSourceBounds{};
+  template <typename T = FloatRectProto> T* set_source_bounds() {
+    return BeginNestedMessage<T>(44);
+  }
+
+
+  using FieldMetadata_Bounds =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FloatRectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_Bounds kBounds{};
+  template <typename T = FloatRectProto> T* set_bounds() {
+    return BeginNestedMessage<T>(45);
+  }
+
+
+  using FieldMetadata_ScreenBounds =
+    ::protozero::proto_utils::FieldMetadata<
+      46,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FloatRectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_ScreenBounds kScreenBounds{};
+  template <typename T = FloatRectProto> T* set_screen_bounds() {
+    return BeginNestedMessage<T>(46);
+  }
+
+
+  using FieldMetadata_InputWindowInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      47,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InputWindowInfoProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_InputWindowInfo kInputWindowInfo{};
+  template <typename T = InputWindowInfoProto> T* set_input_window_info() {
+    return BeginNestedMessage<T>(47);
+  }
+
+
+  using FieldMetadata_CornerRadiusCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      48,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FloatRectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_CornerRadiusCrop kCornerRadiusCrop{};
+  template <typename T = FloatRectProto> T* set_corner_radius_crop() {
+    return BeginNestedMessage<T>(48);
+  }
+
+
+  using FieldMetadata_ShadowRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      49,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerProto>;
+
+  static constexpr FieldMetadata_ShadowRadius kShadowRadius{};
+  void set_shadow_radius(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShadowRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ColorTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      50,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ColorTransformProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_ColorTransform kColorTransform{};
+  template <typename T = ColorTransformProto> T* set_color_transform() {
+    return BeginNestedMessage<T>(50);
+  }
+
+
+  using FieldMetadata_IsRelativeOf =
+    ::protozero::proto_utils::FieldMetadata<
+      51,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_IsRelativeOf kIsRelativeOf{};
+  void set_is_relative_of(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsRelativeOf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BackgroundBlurRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      52,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_BackgroundBlurRadius kBackgroundBlurRadius{};
+  void set_background_blur_radius(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BackgroundBlurRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OwnerUid =
+    ::protozero::proto_utils::FieldMetadata<
+      53,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_OwnerUid kOwnerUid{};
+  void set_owner_uid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OwnerUid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BlurRegions =
+    ::protozero::proto_utils::FieldMetadata<
+      54,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlurRegion,
+      LayerProto>;
+
+  static constexpr FieldMetadata_BlurRegions kBlurRegions{};
+  template <typename T = BlurRegion> T* add_blur_regions() {
+    return BeginNestedMessage<T>(54);
+  }
+
+
+  using FieldMetadata_IsTrustedOverlay =
+    ::protozero::proto_utils::FieldMetadata<
+      55,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerProto>;
+
+  static constexpr FieldMetadata_IsTrustedOverlay kIsTrustedOverlay{};
+  void set_is_trusted_overlay(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsTrustedOverlay::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RequestedCornerRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      56,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerProto>;
+
+  static constexpr FieldMetadata_RequestedCornerRadius kRequestedCornerRadius{};
+  void set_requested_corner_radius(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_RequestedCornerRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DestinationFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      57,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerProto>;
+
+  static constexpr FieldMetadata_DestinationFrame kDestinationFrame{};
+  template <typename T = RectProto> T* set_destination_frame() {
+    return BeginNestedMessage<T>(57);
+  }
+
+
+  using FieldMetadata_OriginalId =
+    ::protozero::proto_utils::FieldMetadata<
+      58,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerProto>;
+
+  static constexpr FieldMetadata_OriginalId kOriginalId{};
+  void set_original_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OriginalId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerProto_MetadataEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerProto_MetadataEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerProto_MetadataEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerProto_MetadataEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  int32_t key() const { return at<1>().as_int32(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class LayerProto_MetadataEntry : public ::protozero::Message {
+ public:
+  using Decoder = LayerProto_MetadataEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerProto.MetadataEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerProto_MetadataEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerProto_MetadataEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DisplayProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DisplayProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DisplayProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DisplayProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_layer_stack() const { return at<3>().valid(); }
+  uint32_t layer_stack() const { return at<3>().as_uint32(); }
+  bool has_size() const { return at<4>().valid(); }
+  ::protozero::ConstBytes size() const { return at<4>().as_bytes(); }
+  bool has_layer_stack_space_rect() const { return at<5>().valid(); }
+  ::protozero::ConstBytes layer_stack_space_rect() const { return at<5>().as_bytes(); }
+  bool has_transform() const { return at<6>().valid(); }
+  ::protozero::ConstBytes transform() const { return at<6>().as_bytes(); }
+  bool has_is_virtual() const { return at<7>().valid(); }
+  bool is_virtual() const { return at<7>().as_bool(); }
+  bool has_dpi_x() const { return at<8>().valid(); }
+  double dpi_x() const { return at<8>().as_double(); }
+  bool has_dpi_y() const { return at<9>().valid(); }
+  double dpi_y() const { return at<9>().as_double(); }
+};
+
+class DisplayProto : public ::protozero::Message {
+ public:
+  using Decoder = DisplayProto_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kLayerStackFieldNumber = 3,
+    kSizeFieldNumber = 4,
+    kLayerStackSpaceRectFieldNumber = 5,
+    kTransformFieldNumber = 6,
+    kIsVirtualFieldNumber = 7,
+    kDpiXFieldNumber = 8,
+    kDpiYFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DisplayProto"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerStack =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_LayerStack kLayerStack{};
+  void set_layer_stack(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStack::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SizeProto,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  template <typename T = SizeProto> T* set_size() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_LayerStackSpaceRect =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_LayerStackSpaceRect kLayerStackSpaceRect{};
+  template <typename T = RectProto> T* set_layer_stack_space_rect() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransformProto,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  template <typename T = TransformProto> T* set_transform() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_IsVirtual =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_IsVirtual kIsVirtual{};
+  void set_is_virtual(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsVirtual::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DpiX =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_DpiX kDpiX{};
+  void set_dpi_x(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DpiX::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DpiY =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      DisplayProto>;
+
+  static constexpr FieldMetadata_DpiY kDpiY{};
+  void set_dpi_y(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DpiY::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayersProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  LayersProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayersProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayersProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layers() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> layers() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class LayersProto : public ::protozero::Message {
+ public:
+  using Decoder = LayersProto_Decoder;
+  enum : int32_t {
+    kLayersFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayersProto"; }
+
+
+  using FieldMetadata_Layers =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerProto,
+      LayersProto>;
+
+  static constexpr FieldMetadata_Layers kLayers{};
+  template <typename T = LayerProto> T* add_layers() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class LayersSnapshotProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  LayersSnapshotProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayersSnapshotProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayersSnapshotProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_elapsed_realtime_nanos() const { return at<1>().valid(); }
+  int64_t elapsed_realtime_nanos() const { return at<1>().as_int64(); }
+  bool has_where() const { return at<2>().valid(); }
+  ::protozero::ConstChars where() const { return at<2>().as_string(); }
+  bool has_layers() const { return at<3>().valid(); }
+  ::protozero::ConstBytes layers() const { return at<3>().as_bytes(); }
+  bool has_hwc_blob() const { return at<4>().valid(); }
+  ::protozero::ConstChars hwc_blob() const { return at<4>().as_string(); }
+  bool has_excludes_composition_state() const { return at<5>().valid(); }
+  bool excludes_composition_state() const { return at<5>().as_bool(); }
+  bool has_missed_entries() const { return at<6>().valid(); }
+  uint32_t missed_entries() const { return at<6>().as_uint32(); }
+  bool has_displays() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> displays() const { return GetRepeated<::protozero::ConstBytes>(7); }
+  bool has_vsync_id() const { return at<8>().valid(); }
+  int64_t vsync_id() const { return at<8>().as_int64(); }
+};
+
+class LayersSnapshotProto : public ::protozero::Message {
+ public:
+  using Decoder = LayersSnapshotProto_Decoder;
+  enum : int32_t {
+    kElapsedRealtimeNanosFieldNumber = 1,
+    kWhereFieldNumber = 2,
+    kLayersFieldNumber = 3,
+    kHwcBlobFieldNumber = 4,
+    kExcludesCompositionStateFieldNumber = 5,
+    kMissedEntriesFieldNumber = 6,
+    kDisplaysFieldNumber = 7,
+    kVsyncIdFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayersSnapshotProto"; }
+
+
+  using FieldMetadata_ElapsedRealtimeNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed64,
+      int64_t,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_ElapsedRealtimeNanos kElapsedRealtimeNanos{};
+  void set_elapsed_realtime_nanos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ElapsedRealtimeNanos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSfixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Where =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_Where kWhere{};
+  void set_where(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Where::kFieldId, data, size);
+  }
+  void set_where(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Where::kFieldId, chars.data, chars.size);
+  }
+  void set_where(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Where::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Layers =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayersProto,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_Layers kLayers{};
+  template <typename T = LayersProto> T* set_layers() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_HwcBlob =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_HwcBlob kHwcBlob{};
+  void set_hwc_blob(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HwcBlob::kFieldId, data, size);
+  }
+  void set_hwc_blob(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HwcBlob::kFieldId, chars.data, chars.size);
+  }
+  void set_hwc_blob(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwcBlob::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExcludesCompositionState =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_ExcludesCompositionState kExcludesCompositionState{};
+  void set_excludes_composition_state(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExcludesCompositionState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MissedEntries =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_MissedEntries kMissedEntries{};
+  void set_missed_entries(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MissedEntries::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Displays =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DisplayProto,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_Displays kDisplays{};
+  template <typename T = DisplayProto> T* add_displays() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_VsyncId =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      LayersSnapshotProto>;
+
+  static constexpr FieldMetadata_VsyncId kVsyncId{};
+  void set_vsync_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VsyncId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayersTraceFileProto_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  LayersTraceFileProto_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayersTraceFileProto_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayersTraceFileProto_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_magic_number() const { return at<1>().valid(); }
+  uint64_t magic_number() const { return at<1>().as_uint64(); }
+  bool has_entry() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> entry() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_real_to_elapsed_time_offset_nanos() const { return at<3>().valid(); }
+  uint64_t real_to_elapsed_time_offset_nanos() const { return at<3>().as_uint64(); }
+};
+
+class LayersTraceFileProto : public ::protozero::Message {
+ public:
+  using Decoder = LayersTraceFileProto_Decoder;
+  enum : int32_t {
+    kMagicNumberFieldNumber = 1,
+    kEntryFieldNumber = 2,
+    kRealToElapsedTimeOffsetNanosFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayersTraceFileProto"; }
+
+
+  using MagicNumber = ::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber;
+  static inline const char* MagicNumber_Name(MagicNumber value) {
+    return ::perfetto::protos::pbzero::LayersTraceFileProto_MagicNumber_Name(value);
+  }
+  static inline const MagicNumber INVALID = MagicNumber::INVALID;
+  static inline const MagicNumber MAGIC_NUMBER_L = MagicNumber::MAGIC_NUMBER_L;
+  static inline const MagicNumber MAGIC_NUMBER_H = MagicNumber::MAGIC_NUMBER_H;
+
+  using FieldMetadata_MagicNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      LayersTraceFileProto>;
+
+  static constexpr FieldMetadata_MagicNumber kMagicNumber{};
+  void set_magic_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MagicNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Entry =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayersSnapshotProto,
+      LayersTraceFileProto>;
+
+  static constexpr FieldMetadata_Entry kEntry{};
+  template <typename T = LayersSnapshotProto> T* add_entry() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_RealToElapsedTimeOffsetNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      LayersTraceFileProto>;
+
+  static constexpr FieldMetadata_RealToElapsedTimeOffsetNanos kRealToElapsedTimeOffsetNanos{};
+  void set_real_to_elapsed_time_offset_nanos(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RealToElapsedTimeOffsetNanos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/android/surfaceflinger_transactions.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_TRANSACTIONS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ANDROID_SURFACEFLINGER_TRANSACTIONS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class BlurRegion;
+class ColorTransformProto;
+class DisplayInfo;
+class DisplayState;
+class LayerCreationArgs;
+class LayerState;
+class LayerState_BufferData;
+class LayerState_Color3;
+class LayerState_Matrix22;
+class LayerState_WindowInfo;
+class RectProto;
+class RegionProto;
+class TransactionState;
+class TransactionTraceEntry;
+class Transform;
+namespace perfetto_pbzero_enum_LayerState_BufferData {
+enum PixelFormat : int32_t;
+}  // namespace perfetto_pbzero_enum_LayerState_BufferData
+using LayerState_BufferData_PixelFormat = perfetto_pbzero_enum_LayerState_BufferData::PixelFormat;
+namespace perfetto_pbzero_enum_LayerState {
+enum DropInputMode : int32_t;
+}  // namespace perfetto_pbzero_enum_LayerState
+using LayerState_DropInputMode = perfetto_pbzero_enum_LayerState::DropInputMode;
+
+namespace perfetto_pbzero_enum_DisplayState {
+enum Changes : int32_t {
+  eChangesNone = 0,
+  eSurfaceChanged = 1,
+  eLayerStackChanged = 2,
+  eDisplayProjectionChanged = 4,
+  eDisplaySizeChanged = 8,
+  eFlagsChanged = 16,
+};
+} // namespace perfetto_pbzero_enum_DisplayState
+using DisplayState_Changes = perfetto_pbzero_enum_DisplayState::Changes;
+
+
+constexpr DisplayState_Changes DisplayState_Changes_MIN = DisplayState_Changes::eChangesNone;
+constexpr DisplayState_Changes DisplayState_Changes_MAX = DisplayState_Changes::eFlagsChanged;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* DisplayState_Changes_Name(::perfetto::protos::pbzero::DisplayState_Changes value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eChangesNone:
+    return "eChangesNone";
+
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eSurfaceChanged:
+    return "eSurfaceChanged";
+
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eLayerStackChanged:
+    return "eLayerStackChanged";
+
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eDisplayProjectionChanged:
+    return "eDisplayProjectionChanged";
+
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eDisplaySizeChanged:
+    return "eDisplaySizeChanged";
+
+  case ::perfetto::protos::pbzero::DisplayState_Changes::eFlagsChanged:
+    return "eFlagsChanged";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState {
+enum ChangesLsb : int32_t {
+  eChangesLsbNone = 0,
+  ePositionChanged = 1,
+  eLayerChanged = 2,
+  eAlphaChanged = 8,
+  eMatrixChanged = 16,
+  eTransparentRegionChanged = 32,
+  eFlagsChanged = 64,
+  eLayerStackChanged = 128,
+  eReleaseBufferListenerChanged = 1024,
+  eShadowRadiusChanged = 2048,
+  eBufferCropChanged = 8192,
+  eRelativeLayerChanged = 16384,
+  eReparent = 32768,
+  eColorChanged = 65536,
+  eBufferTransformChanged = 262144,
+  eTransformToDisplayInverseChanged = 524288,
+  eCropChanged = 1048576,
+  eBufferChanged = 2097152,
+  eAcquireFenceChanged = 4194304,
+  eDataspaceChanged = 8388608,
+  eHdrMetadataChanged = 16777216,
+  eSurfaceDamageRegionChanged = 33554432,
+  eApiChanged = 67108864,
+  eSidebandStreamChanged = 134217728,
+  eColorTransformChanged = 268435456,
+  eHasListenerCallbacksChanged = 536870912,
+  eInputInfoChanged = 1073741824,
+  eCornerRadiusChanged = -2147483648,
+};
+} // namespace perfetto_pbzero_enum_LayerState
+using LayerState_ChangesLsb = perfetto_pbzero_enum_LayerState::ChangesLsb;
+
+
+constexpr LayerState_ChangesLsb LayerState_ChangesLsb_MIN = LayerState_ChangesLsb::eCornerRadiusChanged;
+constexpr LayerState_ChangesLsb LayerState_ChangesLsb_MAX = LayerState_ChangesLsb::eInputInfoChanged;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_ChangesLsb_Name(::perfetto::protos::pbzero::LayerState_ChangesLsb value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eChangesLsbNone:
+    return "eChangesLsbNone";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::ePositionChanged:
+    return "ePositionChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eLayerChanged:
+    return "eLayerChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eAlphaChanged:
+    return "eAlphaChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eMatrixChanged:
+    return "eMatrixChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eTransparentRegionChanged:
+    return "eTransparentRegionChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eFlagsChanged:
+    return "eFlagsChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eLayerStackChanged:
+    return "eLayerStackChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eReleaseBufferListenerChanged:
+    return "eReleaseBufferListenerChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eShadowRadiusChanged:
+    return "eShadowRadiusChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eBufferCropChanged:
+    return "eBufferCropChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eRelativeLayerChanged:
+    return "eRelativeLayerChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eReparent:
+    return "eReparent";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eColorChanged:
+    return "eColorChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eBufferTransformChanged:
+    return "eBufferTransformChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eTransformToDisplayInverseChanged:
+    return "eTransformToDisplayInverseChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eCropChanged:
+    return "eCropChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eBufferChanged:
+    return "eBufferChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eAcquireFenceChanged:
+    return "eAcquireFenceChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eDataspaceChanged:
+    return "eDataspaceChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eHdrMetadataChanged:
+    return "eHdrMetadataChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eSurfaceDamageRegionChanged:
+    return "eSurfaceDamageRegionChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eApiChanged:
+    return "eApiChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eSidebandStreamChanged:
+    return "eSidebandStreamChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eColorTransformChanged:
+    return "eColorTransformChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eHasListenerCallbacksChanged:
+    return "eHasListenerCallbacksChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eInputInfoChanged:
+    return "eInputInfoChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesLsb::eCornerRadiusChanged:
+    return "eCornerRadiusChanged";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState {
+enum ChangesMsb : int32_t {
+  eChangesMsbNone = 0,
+  eDestinationFrameChanged = 1,
+  eCachedBufferChanged = 2,
+  eBackgroundColorChanged = 4,
+  eMetadataChanged = 8,
+  eColorSpaceAgnosticChanged = 16,
+  eFrameRateSelectionPriority = 32,
+  eFrameRateChanged = 64,
+  eBackgroundBlurRadiusChanged = 128,
+  eProducerDisconnect = 256,
+  eFixedTransformHintChanged = 512,
+  eFrameNumberChanged = 1024,
+  eBlurRegionsChanged = 2048,
+  eAutoRefreshChanged = 4096,
+  eStretchChanged = 8192,
+  eTrustedOverlayChanged = 16384,
+  eDropInputModeChanged = 32768,
+};
+} // namespace perfetto_pbzero_enum_LayerState
+using LayerState_ChangesMsb = perfetto_pbzero_enum_LayerState::ChangesMsb;
+
+
+constexpr LayerState_ChangesMsb LayerState_ChangesMsb_MIN = LayerState_ChangesMsb::eChangesMsbNone;
+constexpr LayerState_ChangesMsb LayerState_ChangesMsb_MAX = LayerState_ChangesMsb::eDropInputModeChanged;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_ChangesMsb_Name(::perfetto::protos::pbzero::LayerState_ChangesMsb value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eChangesMsbNone:
+    return "eChangesMsbNone";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eDestinationFrameChanged:
+    return "eDestinationFrameChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eCachedBufferChanged:
+    return "eCachedBufferChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eBackgroundColorChanged:
+    return "eBackgroundColorChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eMetadataChanged:
+    return "eMetadataChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eColorSpaceAgnosticChanged:
+    return "eColorSpaceAgnosticChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eFrameRateSelectionPriority:
+    return "eFrameRateSelectionPriority";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eFrameRateChanged:
+    return "eFrameRateChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eBackgroundBlurRadiusChanged:
+    return "eBackgroundBlurRadiusChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eProducerDisconnect:
+    return "eProducerDisconnect";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eFixedTransformHintChanged:
+    return "eFixedTransformHintChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eFrameNumberChanged:
+    return "eFrameNumberChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eBlurRegionsChanged:
+    return "eBlurRegionsChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eAutoRefreshChanged:
+    return "eAutoRefreshChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eStretchChanged:
+    return "eStretchChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eTrustedOverlayChanged:
+    return "eTrustedOverlayChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_ChangesMsb::eDropInputModeChanged:
+    return "eDropInputModeChanged";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState {
+enum Flags : int32_t {
+  eFlagsNone = 0,
+  eLayerHidden = 1,
+  eLayerOpaque = 2,
+  eLayerSkipScreenshot = 64,
+  eLayerSecure = 128,
+  eEnableBackpressure = 256,
+  eLayerIsDisplayDecoration = 512,
+};
+} // namespace perfetto_pbzero_enum_LayerState
+using LayerState_Flags = perfetto_pbzero_enum_LayerState::Flags;
+
+
+constexpr LayerState_Flags LayerState_Flags_MIN = LayerState_Flags::eFlagsNone;
+constexpr LayerState_Flags LayerState_Flags_MAX = LayerState_Flags::eLayerIsDisplayDecoration;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_Flags_Name(::perfetto::protos::pbzero::LayerState_Flags value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_Flags::eFlagsNone:
+    return "eFlagsNone";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eLayerHidden:
+    return "eLayerHidden";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eLayerOpaque:
+    return "eLayerOpaque";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eLayerSkipScreenshot:
+    return "eLayerSkipScreenshot";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eLayerSecure:
+    return "eLayerSecure";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eEnableBackpressure:
+    return "eEnableBackpressure";
+
+  case ::perfetto::protos::pbzero::LayerState_Flags::eLayerIsDisplayDecoration:
+    return "eLayerIsDisplayDecoration";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState {
+enum DropInputMode : int32_t {
+  NONE = 0,
+  ALL = 1,
+  OBSCURED = 2,
+};
+} // namespace perfetto_pbzero_enum_LayerState
+using LayerState_DropInputMode = perfetto_pbzero_enum_LayerState::DropInputMode;
+
+
+constexpr LayerState_DropInputMode LayerState_DropInputMode_MIN = LayerState_DropInputMode::NONE;
+constexpr LayerState_DropInputMode LayerState_DropInputMode_MAX = LayerState_DropInputMode::OBSCURED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_DropInputMode_Name(::perfetto::protos::pbzero::LayerState_DropInputMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_DropInputMode::NONE:
+    return "NONE";
+
+  case ::perfetto::protos::pbzero::LayerState_DropInputMode::ALL:
+    return "ALL";
+
+  case ::perfetto::protos::pbzero::LayerState_DropInputMode::OBSCURED:
+    return "OBSCURED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState_BufferData {
+enum BufferDataChange : int32_t {
+  BufferDataChangeNone = 0,
+  fenceChanged = 1,
+  frameNumberChanged = 2,
+  cachedBufferChanged = 4,
+};
+} // namespace perfetto_pbzero_enum_LayerState_BufferData
+using LayerState_BufferData_BufferDataChange = perfetto_pbzero_enum_LayerState_BufferData::BufferDataChange;
+
+
+constexpr LayerState_BufferData_BufferDataChange LayerState_BufferData_BufferDataChange_MIN = LayerState_BufferData_BufferDataChange::BufferDataChangeNone;
+constexpr LayerState_BufferData_BufferDataChange LayerState_BufferData_BufferDataChange_MAX = LayerState_BufferData_BufferDataChange::cachedBufferChanged;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_BufferData_BufferDataChange_Name(::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange::BufferDataChangeNone:
+    return "BufferDataChangeNone";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange::fenceChanged:
+    return "fenceChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange::frameNumberChanged:
+    return "frameNumberChanged";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange::cachedBufferChanged:
+    return "cachedBufferChanged";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_LayerState_BufferData {
+enum PixelFormat : int32_t {
+  PIXEL_FORMAT_UNKNOWN = 0,
+  PIXEL_FORMAT_CUSTOM = -4,
+  PIXEL_FORMAT_TRANSLUCENT = -3,
+  PIXEL_FORMAT_TRANSPARENT = -2,
+  PIXEL_FORMAT_OPAQUE = -1,
+  PIXEL_FORMAT_RGBA_8888 = 1,
+  PIXEL_FORMAT_RGBX_8888 = 2,
+  PIXEL_FORMAT_RGB_888 = 3,
+  PIXEL_FORMAT_RGB_565 = 4,
+  PIXEL_FORMAT_BGRA_8888 = 5,
+  PIXEL_FORMAT_RGBA_5551 = 6,
+  PIXEL_FORMAT_RGBA_4444 = 7,
+  PIXEL_FORMAT_RGBA_FP16 = 22,
+  PIXEL_FORMAT_RGBA_1010102 = 43,
+  PIXEL_FORMAT_R_8 = 56,
+};
+} // namespace perfetto_pbzero_enum_LayerState_BufferData
+using LayerState_BufferData_PixelFormat = perfetto_pbzero_enum_LayerState_BufferData::PixelFormat;
+
+
+constexpr LayerState_BufferData_PixelFormat LayerState_BufferData_PixelFormat_MIN = LayerState_BufferData_PixelFormat::PIXEL_FORMAT_CUSTOM;
+constexpr LayerState_BufferData_PixelFormat LayerState_BufferData_PixelFormat_MAX = LayerState_BufferData_PixelFormat::PIXEL_FORMAT_R_8;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LayerState_BufferData_PixelFormat_Name(::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_UNKNOWN:
+    return "PIXEL_FORMAT_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_CUSTOM:
+    return "PIXEL_FORMAT_CUSTOM";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_TRANSLUCENT:
+    return "PIXEL_FORMAT_TRANSLUCENT";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_TRANSPARENT:
+    return "PIXEL_FORMAT_TRANSPARENT";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_OPAQUE:
+    return "PIXEL_FORMAT_OPAQUE";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBA_8888:
+    return "PIXEL_FORMAT_RGBA_8888";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBX_8888:
+    return "PIXEL_FORMAT_RGBX_8888";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGB_888:
+    return "PIXEL_FORMAT_RGB_888";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGB_565:
+    return "PIXEL_FORMAT_RGB_565";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_BGRA_8888:
+    return "PIXEL_FORMAT_BGRA_8888";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBA_5551:
+    return "PIXEL_FORMAT_RGBA_5551";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBA_4444:
+    return "PIXEL_FORMAT_RGBA_4444";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBA_FP16:
+    return "PIXEL_FORMAT_RGBA_FP16";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_RGBA_1010102:
+    return "PIXEL_FORMAT_RGBA_1010102";
+
+  case ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat::PIXEL_FORMAT_R_8:
+    return "PIXEL_FORMAT_R_8";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_TransactionTraceFile {
+enum MagicNumber : int32_t {
+  INVALID = 0,
+  MAGIC_NUMBER_L = 1415073364,
+  MAGIC_NUMBER_H = 1162035538,
+};
+} // namespace perfetto_pbzero_enum_TransactionTraceFile
+using TransactionTraceFile_MagicNumber = perfetto_pbzero_enum_TransactionTraceFile::MagicNumber;
+
+
+constexpr TransactionTraceFile_MagicNumber TransactionTraceFile_MagicNumber_MIN = TransactionTraceFile_MagicNumber::INVALID;
+constexpr TransactionTraceFile_MagicNumber TransactionTraceFile_MagicNumber_MAX = TransactionTraceFile_MagicNumber::MAGIC_NUMBER_L;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* TransactionTraceFile_MagicNumber_Name(::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber::INVALID:
+    return "INVALID";
+
+  case ::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber::MAGIC_NUMBER_L:
+    return "MAGIC_NUMBER_L";
+
+  case ::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber::MAGIC_NUMBER_H:
+    return "MAGIC_NUMBER_H";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class DisplayState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DisplayState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DisplayState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DisplayState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_what() const { return at<2>().valid(); }
+  uint32_t what() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_layer_stack() const { return at<4>().valid(); }
+  uint32_t layer_stack() const { return at<4>().as_uint32(); }
+  bool has_orientation() const { return at<5>().valid(); }
+  uint32_t orientation() const { return at<5>().as_uint32(); }
+  bool has_layer_stack_space_rect() const { return at<6>().valid(); }
+  ::protozero::ConstBytes layer_stack_space_rect() const { return at<6>().as_bytes(); }
+  bool has_oriented_display_space_rect() const { return at<7>().valid(); }
+  ::protozero::ConstBytes oriented_display_space_rect() const { return at<7>().as_bytes(); }
+  bool has_width() const { return at<8>().valid(); }
+  uint32_t width() const { return at<8>().as_uint32(); }
+  bool has_height() const { return at<9>().valid(); }
+  uint32_t height() const { return at<9>().as_uint32(); }
+};
+
+class DisplayState : public ::protozero::Message {
+ public:
+  using Decoder = DisplayState_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kWhatFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kLayerStackFieldNumber = 4,
+    kOrientationFieldNumber = 5,
+    kLayerStackSpaceRectFieldNumber = 6,
+    kOrientedDisplaySpaceRectFieldNumber = 7,
+    kWidthFieldNumber = 8,
+    kHeightFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DisplayState"; }
+
+
+  using Changes = ::perfetto::protos::pbzero::DisplayState_Changes;
+  static inline const char* Changes_Name(Changes value) {
+    return ::perfetto::protos::pbzero::DisplayState_Changes_Name(value);
+  }
+  static inline const Changes eChangesNone = Changes::eChangesNone;
+  static inline const Changes eSurfaceChanged = Changes::eSurfaceChanged;
+  static inline const Changes eLayerStackChanged = Changes::eLayerStackChanged;
+  static inline const Changes eDisplayProjectionChanged = Changes::eDisplayProjectionChanged;
+  static inline const Changes eDisplaySizeChanged = Changes::eDisplaySizeChanged;
+  static inline const Changes eFlagsChanged = Changes::eFlagsChanged;
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_What =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_What kWhat{};
+  void set_what(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_What::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerStack =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_LayerStack kLayerStack{};
+  void set_layer_stack(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStack::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Orientation =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_Orientation kOrientation{};
+  void set_orientation(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Orientation::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerStackSpaceRect =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      DisplayState>;
+
+  static constexpr FieldMetadata_LayerStackSpaceRect kLayerStackSpaceRect{};
+  template <typename T = RectProto> T* set_layer_stack_space_rect() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_OrientedDisplaySpaceRect =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      DisplayState>;
+
+  static constexpr FieldMetadata_OrientedDisplaySpaceRect kOrientedDisplaySpaceRect{};
+  template <typename T = RectProto> T* set_oriented_display_space_rect() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_Width =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_Width kWidth{};
+  void set_width(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Width::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Height =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayState>;
+
+  static constexpr FieldMetadata_Height kHeight{};
+  void set_height(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Height::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/42, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  LayerState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layer_id() const { return at<1>().valid(); }
+  uint32_t layer_id() const { return at<1>().as_uint32(); }
+  bool has_what() const { return at<2>().valid(); }
+  uint64_t what() const { return at<2>().as_uint64(); }
+  bool has_x() const { return at<3>().valid(); }
+  float x() const { return at<3>().as_float(); }
+  bool has_y() const { return at<4>().valid(); }
+  float y() const { return at<4>().as_float(); }
+  bool has_z() const { return at<5>().valid(); }
+  int32_t z() const { return at<5>().as_int32(); }
+  bool has_w() const { return at<6>().valid(); }
+  uint32_t w() const { return at<6>().as_uint32(); }
+  bool has_h() const { return at<7>().valid(); }
+  uint32_t h() const { return at<7>().as_uint32(); }
+  bool has_layer_stack() const { return at<8>().valid(); }
+  uint32_t layer_stack() const { return at<8>().as_uint32(); }
+  bool has_flags() const { return at<9>().valid(); }
+  uint32_t flags() const { return at<9>().as_uint32(); }
+  bool has_mask() const { return at<10>().valid(); }
+  uint32_t mask() const { return at<10>().as_uint32(); }
+  bool has_matrix() const { return at<11>().valid(); }
+  ::protozero::ConstBytes matrix() const { return at<11>().as_bytes(); }
+  bool has_corner_radius() const { return at<12>().valid(); }
+  float corner_radius() const { return at<12>().as_float(); }
+  bool has_background_blur_radius() const { return at<13>().valid(); }
+  uint32_t background_blur_radius() const { return at<13>().as_uint32(); }
+  bool has_parent_id() const { return at<14>().valid(); }
+  uint32_t parent_id() const { return at<14>().as_uint32(); }
+  bool has_relative_parent_id() const { return at<15>().valid(); }
+  uint32_t relative_parent_id() const { return at<15>().as_uint32(); }
+  bool has_alpha() const { return at<16>().valid(); }
+  float alpha() const { return at<16>().as_float(); }
+  bool has_color() const { return at<17>().valid(); }
+  ::protozero::ConstBytes color() const { return at<17>().as_bytes(); }
+  bool has_transparent_region() const { return at<18>().valid(); }
+  ::protozero::ConstBytes transparent_region() const { return at<18>().as_bytes(); }
+  bool has_transform() const { return at<19>().valid(); }
+  uint32_t transform() const { return at<19>().as_uint32(); }
+  bool has_transform_to_display_inverse() const { return at<20>().valid(); }
+  bool transform_to_display_inverse() const { return at<20>().as_bool(); }
+  bool has_crop() const { return at<21>().valid(); }
+  ::protozero::ConstBytes crop() const { return at<21>().as_bytes(); }
+  bool has_buffer_data() const { return at<22>().valid(); }
+  ::protozero::ConstBytes buffer_data() const { return at<22>().as_bytes(); }
+  bool has_api() const { return at<23>().valid(); }
+  int32_t api() const { return at<23>().as_int32(); }
+  bool has_has_sideband_stream() const { return at<24>().valid(); }
+  bool has_sideband_stream() const { return at<24>().as_bool(); }
+  bool has_color_transform() const { return at<25>().valid(); }
+  ::protozero::ConstBytes color_transform() const { return at<25>().as_bytes(); }
+  bool has_blur_regions() const { return at<26>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> blur_regions() const { return GetRepeated<::protozero::ConstBytes>(26); }
+  bool has_window_info_handle() const { return at<27>().valid(); }
+  ::protozero::ConstBytes window_info_handle() const { return at<27>().as_bytes(); }
+  bool has_bg_color_alpha() const { return at<28>().valid(); }
+  float bg_color_alpha() const { return at<28>().as_float(); }
+  bool has_bg_color_dataspace() const { return at<29>().valid(); }
+  int32_t bg_color_dataspace() const { return at<29>().as_int32(); }
+  bool has_color_space_agnostic() const { return at<30>().valid(); }
+  bool color_space_agnostic() const { return at<30>().as_bool(); }
+  bool has_shadow_radius() const { return at<31>().valid(); }
+  float shadow_radius() const { return at<31>().as_float(); }
+  bool has_frame_rate_selection_priority() const { return at<32>().valid(); }
+  int32_t frame_rate_selection_priority() const { return at<32>().as_int32(); }
+  bool has_frame_rate() const { return at<33>().valid(); }
+  float frame_rate() const { return at<33>().as_float(); }
+  bool has_frame_rate_compatibility() const { return at<34>().valid(); }
+  int32_t frame_rate_compatibility() const { return at<34>().as_int32(); }
+  bool has_change_frame_rate_strategy() const { return at<35>().valid(); }
+  int32_t change_frame_rate_strategy() const { return at<35>().as_int32(); }
+  bool has_fixed_transform_hint() const { return at<36>().valid(); }
+  uint32_t fixed_transform_hint() const { return at<36>().as_uint32(); }
+  bool has_frame_number() const { return at<37>().valid(); }
+  uint64_t frame_number() const { return at<37>().as_uint64(); }
+  bool has_auto_refresh() const { return at<38>().valid(); }
+  bool auto_refresh() const { return at<38>().as_bool(); }
+  bool has_is_trusted_overlay() const { return at<39>().valid(); }
+  bool is_trusted_overlay() const { return at<39>().as_bool(); }
+  bool has_buffer_crop() const { return at<40>().valid(); }
+  ::protozero::ConstBytes buffer_crop() const { return at<40>().as_bytes(); }
+  bool has_destination_frame() const { return at<41>().valid(); }
+  ::protozero::ConstBytes destination_frame() const { return at<41>().as_bytes(); }
+  bool has_drop_input_mode() const { return at<42>().valid(); }
+  int32_t drop_input_mode() const { return at<42>().as_int32(); }
+};
+
+class LayerState : public ::protozero::Message {
+ public:
+  using Decoder = LayerState_Decoder;
+  enum : int32_t {
+    kLayerIdFieldNumber = 1,
+    kWhatFieldNumber = 2,
+    kXFieldNumber = 3,
+    kYFieldNumber = 4,
+    kZFieldNumber = 5,
+    kWFieldNumber = 6,
+    kHFieldNumber = 7,
+    kLayerStackFieldNumber = 8,
+    kFlagsFieldNumber = 9,
+    kMaskFieldNumber = 10,
+    kMatrixFieldNumber = 11,
+    kCornerRadiusFieldNumber = 12,
+    kBackgroundBlurRadiusFieldNumber = 13,
+    kParentIdFieldNumber = 14,
+    kRelativeParentIdFieldNumber = 15,
+    kAlphaFieldNumber = 16,
+    kColorFieldNumber = 17,
+    kTransparentRegionFieldNumber = 18,
+    kTransformFieldNumber = 19,
+    kTransformToDisplayInverseFieldNumber = 20,
+    kCropFieldNumber = 21,
+    kBufferDataFieldNumber = 22,
+    kApiFieldNumber = 23,
+    kHasSidebandStreamFieldNumber = 24,
+    kColorTransformFieldNumber = 25,
+    kBlurRegionsFieldNumber = 26,
+    kWindowInfoHandleFieldNumber = 27,
+    kBgColorAlphaFieldNumber = 28,
+    kBgColorDataspaceFieldNumber = 29,
+    kColorSpaceAgnosticFieldNumber = 30,
+    kShadowRadiusFieldNumber = 31,
+    kFrameRateSelectionPriorityFieldNumber = 32,
+    kFrameRateFieldNumber = 33,
+    kFrameRateCompatibilityFieldNumber = 34,
+    kChangeFrameRateStrategyFieldNumber = 35,
+    kFixedTransformHintFieldNumber = 36,
+    kFrameNumberFieldNumber = 37,
+    kAutoRefreshFieldNumber = 38,
+    kIsTrustedOverlayFieldNumber = 39,
+    kBufferCropFieldNumber = 40,
+    kDestinationFrameFieldNumber = 41,
+    kDropInputModeFieldNumber = 42,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerState"; }
+
+  using Matrix22 = ::perfetto::protos::pbzero::LayerState_Matrix22;
+  using Color3 = ::perfetto::protos::pbzero::LayerState_Color3;
+  using BufferData = ::perfetto::protos::pbzero::LayerState_BufferData;
+  using WindowInfo = ::perfetto::protos::pbzero::LayerState_WindowInfo;
+
+  using ChangesLsb = ::perfetto::protos::pbzero::LayerState_ChangesLsb;
+  static inline const char* ChangesLsb_Name(ChangesLsb value) {
+    return ::perfetto::protos::pbzero::LayerState_ChangesLsb_Name(value);
+  }
+
+  using ChangesMsb = ::perfetto::protos::pbzero::LayerState_ChangesMsb;
+  static inline const char* ChangesMsb_Name(ChangesMsb value) {
+    return ::perfetto::protos::pbzero::LayerState_ChangesMsb_Name(value);
+  }
+
+  using Flags = ::perfetto::protos::pbzero::LayerState_Flags;
+  static inline const char* Flags_Name(Flags value) {
+    return ::perfetto::protos::pbzero::LayerState_Flags_Name(value);
+  }
+
+  using DropInputMode = ::perfetto::protos::pbzero::LayerState_DropInputMode;
+  static inline const char* DropInputMode_Name(DropInputMode value) {
+    return ::perfetto::protos::pbzero::LayerState_DropInputMode_Name(value);
+  }
+  static inline const ChangesLsb eChangesLsbNone = ChangesLsb::eChangesLsbNone;
+  static inline const ChangesLsb ePositionChanged = ChangesLsb::ePositionChanged;
+  static inline const ChangesLsb eLayerChanged = ChangesLsb::eLayerChanged;
+  static inline const ChangesLsb eAlphaChanged = ChangesLsb::eAlphaChanged;
+  static inline const ChangesLsb eMatrixChanged = ChangesLsb::eMatrixChanged;
+  static inline const ChangesLsb eTransparentRegionChanged = ChangesLsb::eTransparentRegionChanged;
+  static inline const ChangesLsb eFlagsChanged = ChangesLsb::eFlagsChanged;
+  static inline const ChangesLsb eLayerStackChanged = ChangesLsb::eLayerStackChanged;
+  static inline const ChangesLsb eReleaseBufferListenerChanged = ChangesLsb::eReleaseBufferListenerChanged;
+  static inline const ChangesLsb eShadowRadiusChanged = ChangesLsb::eShadowRadiusChanged;
+  static inline const ChangesLsb eBufferCropChanged = ChangesLsb::eBufferCropChanged;
+  static inline const ChangesLsb eRelativeLayerChanged = ChangesLsb::eRelativeLayerChanged;
+  static inline const ChangesLsb eReparent = ChangesLsb::eReparent;
+  static inline const ChangesLsb eColorChanged = ChangesLsb::eColorChanged;
+  static inline const ChangesLsb eBufferTransformChanged = ChangesLsb::eBufferTransformChanged;
+  static inline const ChangesLsb eTransformToDisplayInverseChanged = ChangesLsb::eTransformToDisplayInverseChanged;
+  static inline const ChangesLsb eCropChanged = ChangesLsb::eCropChanged;
+  static inline const ChangesLsb eBufferChanged = ChangesLsb::eBufferChanged;
+  static inline const ChangesLsb eAcquireFenceChanged = ChangesLsb::eAcquireFenceChanged;
+  static inline const ChangesLsb eDataspaceChanged = ChangesLsb::eDataspaceChanged;
+  static inline const ChangesLsb eHdrMetadataChanged = ChangesLsb::eHdrMetadataChanged;
+  static inline const ChangesLsb eSurfaceDamageRegionChanged = ChangesLsb::eSurfaceDamageRegionChanged;
+  static inline const ChangesLsb eApiChanged = ChangesLsb::eApiChanged;
+  static inline const ChangesLsb eSidebandStreamChanged = ChangesLsb::eSidebandStreamChanged;
+  static inline const ChangesLsb eColorTransformChanged = ChangesLsb::eColorTransformChanged;
+  static inline const ChangesLsb eHasListenerCallbacksChanged = ChangesLsb::eHasListenerCallbacksChanged;
+  static inline const ChangesLsb eInputInfoChanged = ChangesLsb::eInputInfoChanged;
+  static inline const ChangesLsb eCornerRadiusChanged = ChangesLsb::eCornerRadiusChanged;
+  static inline const ChangesMsb eChangesMsbNone = ChangesMsb::eChangesMsbNone;
+  static inline const ChangesMsb eDestinationFrameChanged = ChangesMsb::eDestinationFrameChanged;
+  static inline const ChangesMsb eCachedBufferChanged = ChangesMsb::eCachedBufferChanged;
+  static inline const ChangesMsb eBackgroundColorChanged = ChangesMsb::eBackgroundColorChanged;
+  static inline const ChangesMsb eMetadataChanged = ChangesMsb::eMetadataChanged;
+  static inline const ChangesMsb eColorSpaceAgnosticChanged = ChangesMsb::eColorSpaceAgnosticChanged;
+  static inline const ChangesMsb eFrameRateSelectionPriority = ChangesMsb::eFrameRateSelectionPriority;
+  static inline const ChangesMsb eFrameRateChanged = ChangesMsb::eFrameRateChanged;
+  static inline const ChangesMsb eBackgroundBlurRadiusChanged = ChangesMsb::eBackgroundBlurRadiusChanged;
+  static inline const ChangesMsb eProducerDisconnect = ChangesMsb::eProducerDisconnect;
+  static inline const ChangesMsb eFixedTransformHintChanged = ChangesMsb::eFixedTransformHintChanged;
+  static inline const ChangesMsb eFrameNumberChanged = ChangesMsb::eFrameNumberChanged;
+  static inline const ChangesMsb eBlurRegionsChanged = ChangesMsb::eBlurRegionsChanged;
+  static inline const ChangesMsb eAutoRefreshChanged = ChangesMsb::eAutoRefreshChanged;
+  static inline const ChangesMsb eStretchChanged = ChangesMsb::eStretchChanged;
+  static inline const ChangesMsb eTrustedOverlayChanged = ChangesMsb::eTrustedOverlayChanged;
+  static inline const ChangesMsb eDropInputModeChanged = ChangesMsb::eDropInputModeChanged;
+  static inline const Flags eFlagsNone = Flags::eFlagsNone;
+  static inline const Flags eLayerHidden = Flags::eLayerHidden;
+  static inline const Flags eLayerOpaque = Flags::eLayerOpaque;
+  static inline const Flags eLayerSkipScreenshot = Flags::eLayerSkipScreenshot;
+  static inline const Flags eLayerSecure = Flags::eLayerSecure;
+  static inline const Flags eEnableBackpressure = Flags::eEnableBackpressure;
+  static inline const Flags eLayerIsDisplayDecoration = Flags::eLayerIsDisplayDecoration;
+  static inline const DropInputMode NONE = DropInputMode::NONE;
+  static inline const DropInputMode ALL = DropInputMode::ALL;
+  static inline const DropInputMode OBSCURED = DropInputMode::OBSCURED;
+
+  using FieldMetadata_LayerId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_LayerId kLayerId{};
+  void set_layer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_What =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_What kWhat{};
+  void set_what(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_What::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_X =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_X kX{};
+  void set_x(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_X::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Y =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_Y kY{};
+  void set_y(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Y::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Z =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_Z kZ{};
+  void set_z(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Z::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_W =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_W kW{};
+  void set_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_W::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_H =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_H kH{};
+  void set_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_H::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerStack =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_LayerStack kLayerStack{};
+  void set_layer_stack(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStack::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mask =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_Mask kMask{};
+  void set_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Matrix =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerState_Matrix22,
+      LayerState>;
+
+  static constexpr FieldMetadata_Matrix kMatrix{};
+  template <typename T = LayerState_Matrix22> T* set_matrix() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_CornerRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_CornerRadius kCornerRadius{};
+  void set_corner_radius(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_CornerRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BackgroundBlurRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_BackgroundBlurRadius kBackgroundBlurRadius{};
+  void set_background_blur_radius(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BackgroundBlurRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ParentId =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_ParentId kParentId{};
+  void set_parent_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParentId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RelativeParentId =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_RelativeParentId kRelativeParentId{};
+  void set_relative_parent_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RelativeParentId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Alpha =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_Alpha kAlpha{};
+  void set_alpha(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Alpha::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Color =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerState_Color3,
+      LayerState>;
+
+  static constexpr FieldMetadata_Color kColor{};
+  template <typename T = LayerState_Color3> T* set_color() {
+    return BeginNestedMessage<T>(17);
+  }
+
+
+  using FieldMetadata_TransparentRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      LayerState>;
+
+  static constexpr FieldMetadata_TransparentRegion kTransparentRegion{};
+  template <typename T = RegionProto> T* set_transparent_region() {
+    return BeginNestedMessage<T>(18);
+  }
+
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  void set_transform(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Transform::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TransformToDisplayInverse =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState>;
+
+  static constexpr FieldMetadata_TransformToDisplayInverse kTransformToDisplayInverse{};
+  void set_transform_to_display_inverse(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TransformToDisplayInverse::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Crop =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerState>;
+
+  static constexpr FieldMetadata_Crop kCrop{};
+  template <typename T = RectProto> T* set_crop() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_BufferData =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerState_BufferData,
+      LayerState>;
+
+  static constexpr FieldMetadata_BufferData kBufferData{};
+  template <typename T = LayerState_BufferData> T* set_buffer_data() {
+    return BeginNestedMessage<T>(22);
+  }
+
+
+  using FieldMetadata_Api =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_Api kApi{};
+  void set_api(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Api::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasSidebandStream =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState>;
+
+  static constexpr FieldMetadata_HasSidebandStream kHasSidebandStream{};
+  void set_has_sideband_stream(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasSidebandStream::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ColorTransform =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ColorTransformProto,
+      LayerState>;
+
+  static constexpr FieldMetadata_ColorTransform kColorTransform{};
+  template <typename T = ColorTransformProto> T* set_color_transform() {
+    return BeginNestedMessage<T>(25);
+  }
+
+
+  using FieldMetadata_BlurRegions =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlurRegion,
+      LayerState>;
+
+  static constexpr FieldMetadata_BlurRegions kBlurRegions{};
+  template <typename T = BlurRegion> T* add_blur_regions() {
+    return BeginNestedMessage<T>(26);
+  }
+
+
+  using FieldMetadata_WindowInfoHandle =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerState_WindowInfo,
+      LayerState>;
+
+  static constexpr FieldMetadata_WindowInfoHandle kWindowInfoHandle{};
+  template <typename T = LayerState_WindowInfo> T* set_window_info_handle() {
+    return BeginNestedMessage<T>(27);
+  }
+
+
+  using FieldMetadata_BgColorAlpha =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_BgColorAlpha kBgColorAlpha{};
+  void set_bg_color_alpha(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_BgColorAlpha::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BgColorDataspace =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_BgColorDataspace kBgColorDataspace{};
+  void set_bg_color_dataspace(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BgColorDataspace::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ColorSpaceAgnostic =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState>;
+
+  static constexpr FieldMetadata_ColorSpaceAgnostic kColorSpaceAgnostic{};
+  void set_color_space_agnostic(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ColorSpaceAgnostic::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ShadowRadius =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_ShadowRadius kShadowRadius{};
+  void set_shadow_radius(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShadowRadius::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameRateSelectionPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_FrameRateSelectionPriority kFrameRateSelectionPriority{};
+  void set_frame_rate_selection_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameRateSelectionPriority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameRate =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState>;
+
+  static constexpr FieldMetadata_FrameRate kFrameRate{};
+  void set_frame_rate(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameRate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameRateCompatibility =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_FrameRateCompatibility kFrameRateCompatibility{};
+  void set_frame_rate_compatibility(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameRateCompatibility::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChangeFrameRateStrategy =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_ChangeFrameRateStrategy kChangeFrameRateStrategy{};
+  void set_change_frame_rate_strategy(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChangeFrameRateStrategy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FixedTransformHint =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_FixedTransformHint kFixedTransformHint{};
+  void set_fixed_transform_hint(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FixedTransformHint::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState>;
+
+  static constexpr FieldMetadata_FrameNumber kFrameNumber{};
+  void set_frame_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AutoRefresh =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState>;
+
+  static constexpr FieldMetadata_AutoRefresh kAutoRefresh{};
+  void set_auto_refresh(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AutoRefresh::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsTrustedOverlay =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState>;
+
+  static constexpr FieldMetadata_IsTrustedOverlay kIsTrustedOverlay{};
+  void set_is_trusted_overlay(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsTrustedOverlay::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BufferCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerState>;
+
+  static constexpr FieldMetadata_BufferCrop kBufferCrop{};
+  template <typename T = RectProto> T* set_buffer_crop() {
+    return BeginNestedMessage<T>(40);
+  }
+
+
+  using FieldMetadata_DestinationFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerState>;
+
+  static constexpr FieldMetadata_DestinationFrame kDestinationFrame{};
+  template <typename T = RectProto> T* set_destination_frame() {
+    return BeginNestedMessage<T>(41);
+  }
+
+
+  using FieldMetadata_DropInputMode =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::LayerState_DropInputMode,
+      LayerState>;
+
+  static constexpr FieldMetadata_DropInputMode kDropInputMode{};
+  void set_drop_input_mode(::perfetto::protos::pbzero::LayerState_DropInputMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_DropInputMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerState_WindowInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerState_WindowInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerState_WindowInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerState_WindowInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layout_params_flags() const { return at<1>().valid(); }
+  uint32_t layout_params_flags() const { return at<1>().as_uint32(); }
+  bool has_layout_params_type() const { return at<2>().valid(); }
+  int32_t layout_params_type() const { return at<2>().as_int32(); }
+  bool has_touchable_region() const { return at<3>().valid(); }
+  ::protozero::ConstBytes touchable_region() const { return at<3>().as_bytes(); }
+  bool has_surface_inset() const { return at<4>().valid(); }
+  int32_t surface_inset() const { return at<4>().as_int32(); }
+  bool has_focusable() const { return at<5>().valid(); }
+  bool focusable() const { return at<5>().as_bool(); }
+  bool has_has_wallpaper() const { return at<6>().valid(); }
+  bool has_wallpaper() const { return at<6>().as_bool(); }
+  bool has_global_scale_factor() const { return at<7>().valid(); }
+  float global_scale_factor() const { return at<7>().as_float(); }
+  bool has_crop_layer_id() const { return at<8>().valid(); }
+  uint32_t crop_layer_id() const { return at<8>().as_uint32(); }
+  bool has_replace_touchable_region_with_crop() const { return at<9>().valid(); }
+  bool replace_touchable_region_with_crop() const { return at<9>().as_bool(); }
+  bool has_touchable_region_crop() const { return at<10>().valid(); }
+  ::protozero::ConstBytes touchable_region_crop() const { return at<10>().as_bytes(); }
+  bool has_transform() const { return at<11>().valid(); }
+  ::protozero::ConstBytes transform() const { return at<11>().as_bytes(); }
+  bool has_input_config() const { return at<12>().valid(); }
+  uint32_t input_config() const { return at<12>().as_uint32(); }
+};
+
+class LayerState_WindowInfo : public ::protozero::Message {
+ public:
+  using Decoder = LayerState_WindowInfo_Decoder;
+  enum : int32_t {
+    kLayoutParamsFlagsFieldNumber = 1,
+    kLayoutParamsTypeFieldNumber = 2,
+    kTouchableRegionFieldNumber = 3,
+    kSurfaceInsetFieldNumber = 4,
+    kFocusableFieldNumber = 5,
+    kHasWallpaperFieldNumber = 6,
+    kGlobalScaleFactorFieldNumber = 7,
+    kCropLayerIdFieldNumber = 8,
+    kReplaceTouchableRegionWithCropFieldNumber = 9,
+    kTouchableRegionCropFieldNumber = 10,
+    kTransformFieldNumber = 11,
+    kInputConfigFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerState.WindowInfo"; }
+
+
+  using FieldMetadata_LayoutParamsFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_LayoutParamsFlags kLayoutParamsFlags{};
+  void set_layout_params_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayoutParamsFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayoutParamsType =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_LayoutParamsType kLayoutParamsType{};
+  void set_layout_params_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayoutParamsType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TouchableRegion =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegionProto,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_TouchableRegion kTouchableRegion{};
+  template <typename T = RegionProto> T* set_touchable_region() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_SurfaceInset =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_SurfaceInset kSurfaceInset{};
+  void set_surface_inset(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SurfaceInset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Focusable =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_Focusable kFocusable{};
+  void set_focusable(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Focusable::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasWallpaper =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_HasWallpaper kHasWallpaper{};
+  void set_has_wallpaper(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasWallpaper::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GlobalScaleFactor =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_GlobalScaleFactor kGlobalScaleFactor{};
+  void set_global_scale_factor(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_GlobalScaleFactor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CropLayerId =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_CropLayerId kCropLayerId{};
+  void set_crop_layer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CropLayerId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReplaceTouchableRegionWithCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_ReplaceTouchableRegionWithCrop kReplaceTouchableRegionWithCrop{};
+  void set_replace_touchable_region_with_crop(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReplaceTouchableRegionWithCrop::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TouchableRegionCrop =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RectProto,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_TouchableRegionCrop kTouchableRegionCrop{};
+  template <typename T = RectProto> T* set_touchable_region_crop() {
+    return BeginNestedMessage<T>(10);
+  }
+
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Transform,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  template <typename T = Transform> T* set_transform() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_InputConfig =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_WindowInfo>;
+
+  static constexpr FieldMetadata_InputConfig kInputConfig{};
+  void set_input_config(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputConfig::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerState_BufferData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerState_BufferData_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerState_BufferData_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerState_BufferData_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffer_id() const { return at<1>().valid(); }
+  uint64_t buffer_id() const { return at<1>().as_uint64(); }
+  bool has_width() const { return at<2>().valid(); }
+  uint32_t width() const { return at<2>().as_uint32(); }
+  bool has_height() const { return at<3>().valid(); }
+  uint32_t height() const { return at<3>().as_uint32(); }
+  bool has_frame_number() const { return at<4>().valid(); }
+  uint64_t frame_number() const { return at<4>().as_uint64(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+  bool has_cached_buffer_id() const { return at<6>().valid(); }
+  uint64_t cached_buffer_id() const { return at<6>().as_uint64(); }
+  bool has_pixel_format() const { return at<7>().valid(); }
+  int32_t pixel_format() const { return at<7>().as_int32(); }
+  bool has_usage() const { return at<8>().valid(); }
+  uint64_t usage() const { return at<8>().as_uint64(); }
+};
+
+class LayerState_BufferData : public ::protozero::Message {
+ public:
+  using Decoder = LayerState_BufferData_Decoder;
+  enum : int32_t {
+    kBufferIdFieldNumber = 1,
+    kWidthFieldNumber = 2,
+    kHeightFieldNumber = 3,
+    kFrameNumberFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+    kCachedBufferIdFieldNumber = 6,
+    kPixelFormatFieldNumber = 7,
+    kUsageFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerState.BufferData"; }
+
+
+  using BufferDataChange = ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange;
+  static inline const char* BufferDataChange_Name(BufferDataChange value) {
+    return ::perfetto::protos::pbzero::LayerState_BufferData_BufferDataChange_Name(value);
+  }
+
+  using PixelFormat = ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat;
+  static inline const char* PixelFormat_Name(PixelFormat value) {
+    return ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat_Name(value);
+  }
+  static inline const BufferDataChange BufferDataChangeNone = BufferDataChange::BufferDataChangeNone;
+  static inline const BufferDataChange fenceChanged = BufferDataChange::fenceChanged;
+  static inline const BufferDataChange frameNumberChanged = BufferDataChange::frameNumberChanged;
+  static inline const BufferDataChange cachedBufferChanged = BufferDataChange::cachedBufferChanged;
+  static inline const PixelFormat PIXEL_FORMAT_UNKNOWN = PixelFormat::PIXEL_FORMAT_UNKNOWN;
+  static inline const PixelFormat PIXEL_FORMAT_CUSTOM = PixelFormat::PIXEL_FORMAT_CUSTOM;
+  static inline const PixelFormat PIXEL_FORMAT_TRANSLUCENT = PixelFormat::PIXEL_FORMAT_TRANSLUCENT;
+  static inline const PixelFormat PIXEL_FORMAT_TRANSPARENT = PixelFormat::PIXEL_FORMAT_TRANSPARENT;
+  static inline const PixelFormat PIXEL_FORMAT_OPAQUE = PixelFormat::PIXEL_FORMAT_OPAQUE;
+  static inline const PixelFormat PIXEL_FORMAT_RGBA_8888 = PixelFormat::PIXEL_FORMAT_RGBA_8888;
+  static inline const PixelFormat PIXEL_FORMAT_RGBX_8888 = PixelFormat::PIXEL_FORMAT_RGBX_8888;
+  static inline const PixelFormat PIXEL_FORMAT_RGB_888 = PixelFormat::PIXEL_FORMAT_RGB_888;
+  static inline const PixelFormat PIXEL_FORMAT_RGB_565 = PixelFormat::PIXEL_FORMAT_RGB_565;
+  static inline const PixelFormat PIXEL_FORMAT_BGRA_8888 = PixelFormat::PIXEL_FORMAT_BGRA_8888;
+  static inline const PixelFormat PIXEL_FORMAT_RGBA_5551 = PixelFormat::PIXEL_FORMAT_RGBA_5551;
+  static inline const PixelFormat PIXEL_FORMAT_RGBA_4444 = PixelFormat::PIXEL_FORMAT_RGBA_4444;
+  static inline const PixelFormat PIXEL_FORMAT_RGBA_FP16 = PixelFormat::PIXEL_FORMAT_RGBA_FP16;
+  static inline const PixelFormat PIXEL_FORMAT_RGBA_1010102 = PixelFormat::PIXEL_FORMAT_RGBA_1010102;
+  static inline const PixelFormat PIXEL_FORMAT_R_8 = PixelFormat::PIXEL_FORMAT_R_8;
+
+  using FieldMetadata_BufferId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_BufferId kBufferId{};
+  void set_buffer_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Width =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_Width kWidth{};
+  void set_width(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Width::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Height =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_Height kHeight{};
+  void set_height(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Height::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_FrameNumber kFrameNumber{};
+  void set_frame_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CachedBufferId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_CachedBufferId kCachedBufferId{};
+  void set_cached_buffer_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CachedBufferId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PixelFormat =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_PixelFormat kPixelFormat{};
+  void set_pixel_format(::perfetto::protos::pbzero::LayerState_BufferData_PixelFormat value) {
+    static constexpr uint32_t field_id = FieldMetadata_PixelFormat::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Usage =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LayerState_BufferData>;
+
+  static constexpr FieldMetadata_Usage kUsage{};
+  void set_usage(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Usage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerState_Color3_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerState_Color3_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerState_Color3_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerState_Color3_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_r() const { return at<1>().valid(); }
+  float r() const { return at<1>().as_float(); }
+  bool has_g() const { return at<2>().valid(); }
+  float g() const { return at<2>().as_float(); }
+  bool has_b() const { return at<3>().valid(); }
+  float b() const { return at<3>().as_float(); }
+};
+
+class LayerState_Color3 : public ::protozero::Message {
+ public:
+  using Decoder = LayerState_Color3_Decoder;
+  enum : int32_t {
+    kRFieldNumber = 1,
+    kGFieldNumber = 2,
+    kBFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerState.Color3"; }
+
+
+  using FieldMetadata_R =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Color3>;
+
+  static constexpr FieldMetadata_R kR{};
+  void set_r(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_R::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_G =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Color3>;
+
+  static constexpr FieldMetadata_G kG{};
+  void set_g(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_G::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_B =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Color3>;
+
+  static constexpr FieldMetadata_B kB{};
+  void set_b(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_B::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerState_Matrix22_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerState_Matrix22_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerState_Matrix22_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerState_Matrix22_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dsdx() const { return at<1>().valid(); }
+  float dsdx() const { return at<1>().as_float(); }
+  bool has_dtdx() const { return at<2>().valid(); }
+  float dtdx() const { return at<2>().as_float(); }
+  bool has_dtdy() const { return at<3>().valid(); }
+  float dtdy() const { return at<3>().as_float(); }
+  bool has_dsdy() const { return at<4>().valid(); }
+  float dsdy() const { return at<4>().as_float(); }
+};
+
+class LayerState_Matrix22 : public ::protozero::Message {
+ public:
+  using Decoder = LayerState_Matrix22_Decoder;
+  enum : int32_t {
+    kDsdxFieldNumber = 1,
+    kDtdxFieldNumber = 2,
+    kDtdyFieldNumber = 3,
+    kDsdyFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerState.Matrix22"; }
+
+
+  using FieldMetadata_Dsdx =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Matrix22>;
+
+  static constexpr FieldMetadata_Dsdx kDsdx{};
+  void set_dsdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Matrix22>;
+
+  static constexpr FieldMetadata_Dtdx kDtdx{};
+  void set_dtdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdy =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Matrix22>;
+
+  static constexpr FieldMetadata_Dtdy kDtdy{};
+  void set_dtdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dsdy =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      LayerState_Matrix22>;
+
+  static constexpr FieldMetadata_Dsdy kDsdy{};
+  void set_dsdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TransactionState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TransactionState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TransactionState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TransactionState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_uid() const { return at<2>().valid(); }
+  int32_t uid() const { return at<2>().as_int32(); }
+  bool has_vsync_id() const { return at<3>().valid(); }
+  int64_t vsync_id() const { return at<3>().as_int64(); }
+  bool has_input_event_id() const { return at<4>().valid(); }
+  int32_t input_event_id() const { return at<4>().as_int32(); }
+  bool has_post_time() const { return at<5>().valid(); }
+  int64_t post_time() const { return at<5>().as_int64(); }
+  bool has_transaction_id() const { return at<6>().valid(); }
+  uint64_t transaction_id() const { return at<6>().as_uint64(); }
+  bool has_layer_changes() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> layer_changes() const { return GetRepeated<::protozero::ConstBytes>(7); }
+  bool has_display_changes() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> display_changes() const { return GetRepeated<::protozero::ConstBytes>(8); }
+  bool has_merged_transaction_ids() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> merged_transaction_ids() const { return GetRepeated<uint64_t>(9); }
+};
+
+class TransactionState : public ::protozero::Message {
+ public:
+  using Decoder = TransactionState_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kUidFieldNumber = 2,
+    kVsyncIdFieldNumber = 3,
+    kInputEventIdFieldNumber = 4,
+    kPostTimeFieldNumber = 5,
+    kTransactionIdFieldNumber = 6,
+    kLayerChangesFieldNumber = 7,
+    kDisplayChangesFieldNumber = 8,
+    kMergedTransactionIdsFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TransactionState"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VsyncId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_VsyncId kVsyncId{};
+  void set_vsync_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VsyncId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InputEventId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_InputEventId kInputEventId{};
+  void set_input_event_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InputEventId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PostTime =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_PostTime kPostTime{};
+  void set_post_time(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PostTime::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TransactionId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_TransactionId kTransactionId{};
+  void set_transaction_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TransactionId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerChanges =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerState,
+      TransactionState>;
+
+  static constexpr FieldMetadata_LayerChanges kLayerChanges{};
+  template <typename T = LayerState> T* add_layer_changes() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_DisplayChanges =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DisplayState,
+      TransactionState>;
+
+  static constexpr FieldMetadata_DisplayChanges kDisplayChanges{};
+  template <typename T = DisplayState> T* add_display_changes() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_MergedTransactionIds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TransactionState>;
+
+  static constexpr FieldMetadata_MergedTransactionIds kMergedTransactionIds{};
+  void add_merged_transaction_ids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MergedTransactionIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Transform_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Transform_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Transform_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Transform_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dsdx() const { return at<1>().valid(); }
+  float dsdx() const { return at<1>().as_float(); }
+  bool has_dtdx() const { return at<2>().valid(); }
+  float dtdx() const { return at<2>().as_float(); }
+  bool has_dtdy() const { return at<3>().valid(); }
+  float dtdy() const { return at<3>().as_float(); }
+  bool has_dsdy() const { return at<4>().valid(); }
+  float dsdy() const { return at<4>().as_float(); }
+  bool has_tx() const { return at<5>().valid(); }
+  float tx() const { return at<5>().as_float(); }
+  bool has_ty() const { return at<6>().valid(); }
+  float ty() const { return at<6>().as_float(); }
+};
+
+class Transform : public ::protozero::Message {
+ public:
+  using Decoder = Transform_Decoder;
+  enum : int32_t {
+    kDsdxFieldNumber = 1,
+    kDtdxFieldNumber = 2,
+    kDtdyFieldNumber = 3,
+    kDsdyFieldNumber = 4,
+    kTxFieldNumber = 5,
+    kTyFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Transform"; }
+
+
+  using FieldMetadata_Dsdx =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Dsdx kDsdx{};
+  void set_dsdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Dtdx kDtdx{};
+  void set_dtdx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dtdy =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Dtdy kDtdy{};
+  void set_dtdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dtdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dsdy =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Dsdy kDsdy{};
+  void set_dsdy(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dsdy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tx =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Tx kTx{};
+  void set_tx(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ty =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      Transform>;
+
+  static constexpr FieldMetadata_Ty kTy{};
+  void set_ty(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ty::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LayerCreationArgs_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LayerCreationArgs_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LayerCreationArgs_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LayerCreationArgs_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layer_id() const { return at<1>().valid(); }
+  uint32_t layer_id() const { return at<1>().as_uint32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_parent_id() const { return at<4>().valid(); }
+  uint32_t parent_id() const { return at<4>().as_uint32(); }
+  bool has_mirror_from_id() const { return at<5>().valid(); }
+  uint32_t mirror_from_id() const { return at<5>().as_uint32(); }
+  bool has_add_to_root() const { return at<6>().valid(); }
+  bool add_to_root() const { return at<6>().as_bool(); }
+  bool has_layer_stack_to_mirror() const { return at<7>().valid(); }
+  uint32_t layer_stack_to_mirror() const { return at<7>().as_uint32(); }
+};
+
+class LayerCreationArgs : public ::protozero::Message {
+ public:
+  using Decoder = LayerCreationArgs_Decoder;
+  enum : int32_t {
+    kLayerIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kParentIdFieldNumber = 4,
+    kMirrorFromIdFieldNumber = 5,
+    kAddToRootFieldNumber = 6,
+    kLayerStackToMirrorFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LayerCreationArgs"; }
+
+
+  using FieldMetadata_LayerId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_LayerId kLayerId{};
+  void set_layer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ParentId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_ParentId kParentId{};
+  void set_parent_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParentId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MirrorFromId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_MirrorFromId kMirrorFromId{};
+  void set_mirror_from_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MirrorFromId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AddToRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_AddToRoot kAddToRoot{};
+  void set_add_to_root(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AddToRoot::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerStackToMirror =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LayerCreationArgs>;
+
+  static constexpr FieldMetadata_LayerStackToMirror kLayerStackToMirror{};
+  void set_layer_stack_to_mirror(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStackToMirror::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DisplayInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DisplayInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DisplayInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DisplayInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_layer_stack() const { return at<1>().valid(); }
+  uint32_t layer_stack() const { return at<1>().as_uint32(); }
+  bool has_display_id() const { return at<2>().valid(); }
+  int32_t display_id() const { return at<2>().as_int32(); }
+  bool has_logical_width() const { return at<3>().valid(); }
+  int32_t logical_width() const { return at<3>().as_int32(); }
+  bool has_logical_height() const { return at<4>().valid(); }
+  int32_t logical_height() const { return at<4>().as_int32(); }
+  bool has_transform_inverse() const { return at<5>().valid(); }
+  ::protozero::ConstBytes transform_inverse() const { return at<5>().as_bytes(); }
+  bool has_transform() const { return at<6>().valid(); }
+  ::protozero::ConstBytes transform() const { return at<6>().as_bytes(); }
+  bool has_receives_input() const { return at<7>().valid(); }
+  bool receives_input() const { return at<7>().as_bool(); }
+  bool has_is_secure() const { return at<8>().valid(); }
+  bool is_secure() const { return at<8>().as_bool(); }
+  bool has_is_primary() const { return at<9>().valid(); }
+  bool is_primary() const { return at<9>().as_bool(); }
+  bool has_is_virtual() const { return at<10>().valid(); }
+  bool is_virtual() const { return at<10>().as_bool(); }
+  bool has_rotation_flags() const { return at<11>().valid(); }
+  int32_t rotation_flags() const { return at<11>().as_int32(); }
+  bool has_transform_hint() const { return at<12>().valid(); }
+  int32_t transform_hint() const { return at<12>().as_int32(); }
+};
+
+class DisplayInfo : public ::protozero::Message {
+ public:
+  using Decoder = DisplayInfo_Decoder;
+  enum : int32_t {
+    kLayerStackFieldNumber = 1,
+    kDisplayIdFieldNumber = 2,
+    kLogicalWidthFieldNumber = 3,
+    kLogicalHeightFieldNumber = 4,
+    kTransformInverseFieldNumber = 5,
+    kTransformFieldNumber = 6,
+    kReceivesInputFieldNumber = 7,
+    kIsSecureFieldNumber = 8,
+    kIsPrimaryFieldNumber = 9,
+    kIsVirtualFieldNumber = 10,
+    kRotationFlagsFieldNumber = 11,
+    kTransformHintFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DisplayInfo"; }
+
+
+  using FieldMetadata_LayerStack =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_LayerStack kLayerStack{};
+  void set_layer_stack(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerStack::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisplayId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_DisplayId kDisplayId{};
+  void set_display_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplayId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LogicalWidth =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_LogicalWidth kLogicalWidth{};
+  void set_logical_width(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogicalWidth::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LogicalHeight =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_LogicalHeight kLogicalHeight{};
+  void set_logical_height(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogicalHeight::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TransformInverse =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Transform,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_TransformInverse kTransformInverse{};
+  template <typename T = Transform> T* set_transform_inverse() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Transform =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Transform,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_Transform kTransform{};
+  template <typename T = Transform> T* set_transform() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_ReceivesInput =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_ReceivesInput kReceivesInput{};
+  void set_receives_input(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReceivesInput::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsSecure =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_IsSecure kIsSecure{};
+  void set_is_secure(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsSecure::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsPrimary =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_IsPrimary kIsPrimary{};
+  void set_is_primary(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsPrimary::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsVirtual =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_IsVirtual kIsVirtual{};
+  void set_is_virtual(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsVirtual::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RotationFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_RotationFlags kRotationFlags{};
+  void set_rotation_flags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RotationFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TransformHint =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DisplayInfo>;
+
+  static constexpr FieldMetadata_TransformHint kTransformHint{};
+  void set_transform_hint(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TransformHint::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TransactionTraceEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TransactionTraceEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TransactionTraceEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TransactionTraceEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_elapsed_realtime_nanos() const { return at<1>().valid(); }
+  int64_t elapsed_realtime_nanos() const { return at<1>().as_int64(); }
+  bool has_vsync_id() const { return at<2>().valid(); }
+  int64_t vsync_id() const { return at<2>().as_int64(); }
+  bool has_transactions() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> transactions() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_added_layers() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> added_layers() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_destroyed_layers() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> destroyed_layers() const { return GetRepeated<uint32_t>(5); }
+  bool has_added_displays() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> added_displays() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_removed_displays() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> removed_displays() const { return GetRepeated<int32_t>(7); }
+  bool has_destroyed_layer_handles() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> destroyed_layer_handles() const { return GetRepeated<uint32_t>(8); }
+  bool has_displays_changed() const { return at<9>().valid(); }
+  bool displays_changed() const { return at<9>().as_bool(); }
+  bool has_displays() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> displays() const { return GetRepeated<::protozero::ConstBytes>(10); }
+};
+
+class TransactionTraceEntry : public ::protozero::Message {
+ public:
+  using Decoder = TransactionTraceEntry_Decoder;
+  enum : int32_t {
+    kElapsedRealtimeNanosFieldNumber = 1,
+    kVsyncIdFieldNumber = 2,
+    kTransactionsFieldNumber = 3,
+    kAddedLayersFieldNumber = 4,
+    kDestroyedLayersFieldNumber = 5,
+    kAddedDisplaysFieldNumber = 6,
+    kRemovedDisplaysFieldNumber = 7,
+    kDestroyedLayerHandlesFieldNumber = 8,
+    kDisplaysChangedFieldNumber = 9,
+    kDisplaysFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TransactionTraceEntry"; }
+
+
+  using FieldMetadata_ElapsedRealtimeNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_ElapsedRealtimeNanos kElapsedRealtimeNanos{};
+  void set_elapsed_realtime_nanos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ElapsedRealtimeNanos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VsyncId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_VsyncId kVsyncId{};
+  void set_vsync_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VsyncId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Transactions =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransactionState,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_Transactions kTransactions{};
+  template <typename T = TransactionState> T* add_transactions() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_AddedLayers =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LayerCreationArgs,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_AddedLayers kAddedLayers{};
+  template <typename T = LayerCreationArgs> T* add_added_layers() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_DestroyedLayers =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_DestroyedLayers kDestroyedLayers{};
+  void add_destroyed_layers(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DestroyedLayers::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AddedDisplays =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DisplayState,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_AddedDisplays kAddedDisplays{};
+  template <typename T = DisplayState> T* add_added_displays() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_RemovedDisplays =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_RemovedDisplays kRemovedDisplays{};
+  void add_removed_displays(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RemovedDisplays::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DestroyedLayerHandles =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_DestroyedLayerHandles kDestroyedLayerHandles{};
+  void add_destroyed_layer_handles(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DestroyedLayerHandles::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DisplaysChanged =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_DisplaysChanged kDisplaysChanged{};
+  void set_displays_changed(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DisplaysChanged::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Displays =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DisplayInfo,
+      TransactionTraceEntry>;
+
+  static constexpr FieldMetadata_Displays kDisplays{};
+  template <typename T = DisplayInfo> T* add_displays() {
+    return BeginNestedMessage<T>(10);
+  }
+
+};
+
+class TransactionTraceFile_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TransactionTraceFile_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TransactionTraceFile_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TransactionTraceFile_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_magic_number() const { return at<1>().valid(); }
+  uint64_t magic_number() const { return at<1>().as_uint64(); }
+  bool has_entry() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> entry() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_real_to_elapsed_time_offset_nanos() const { return at<3>().valid(); }
+  uint64_t real_to_elapsed_time_offset_nanos() const { return at<3>().as_uint64(); }
+  bool has_version() const { return at<4>().valid(); }
+  uint32_t version() const { return at<4>().as_uint32(); }
+};
+
+class TransactionTraceFile : public ::protozero::Message {
+ public:
+  using Decoder = TransactionTraceFile_Decoder;
+  enum : int32_t {
+    kMagicNumberFieldNumber = 1,
+    kEntryFieldNumber = 2,
+    kRealToElapsedTimeOffsetNanosFieldNumber = 3,
+    kVersionFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TransactionTraceFile"; }
+
+
+  using MagicNumber = ::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber;
+  static inline const char* MagicNumber_Name(MagicNumber value) {
+    return ::perfetto::protos::pbzero::TransactionTraceFile_MagicNumber_Name(value);
+  }
+  static inline const MagicNumber INVALID = MagicNumber::INVALID;
+  static inline const MagicNumber MAGIC_NUMBER_L = MagicNumber::MAGIC_NUMBER_L;
+  static inline const MagicNumber MAGIC_NUMBER_H = MagicNumber::MAGIC_NUMBER_H;
+
+  using FieldMetadata_MagicNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      TransactionTraceFile>;
+
+  static constexpr FieldMetadata_MagicNumber kMagicNumber{};
+  void set_magic_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MagicNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Entry =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TransactionTraceEntry,
+      TransactionTraceFile>;
+
+  static constexpr FieldMetadata_Entry kEntry{};
+  template <typename T = TransactionTraceEntry> T* add_entry() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_RealToElapsedTimeOffsetNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      TransactionTraceFile>;
+
+  static constexpr FieldMetadata_RealToElapsedTimeOffsetNanos kRealToElapsedTimeOffsetNanos{};
+  void set_real_to_elapsed_time_offset_nanos(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RealToElapsedTimeOffsetNanos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Version =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TransactionTraceFile>;
+
+  static constexpr FieldMetadata_Version kVersion{};
+  void set_version(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Version::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_BENCHMARK_METADATA_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_BENCHMARK_METADATA_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ChromeBenchmarkMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeBenchmarkMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeBenchmarkMetadata_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeBenchmarkMetadata_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_benchmark_start_time_us() const { return at<1>().valid(); }
+  int64_t benchmark_start_time_us() const { return at<1>().as_int64(); }
+  bool has_story_run_time_us() const { return at<2>().valid(); }
+  int64_t story_run_time_us() const { return at<2>().as_int64(); }
+  bool has_benchmark_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars benchmark_name() const { return at<3>().as_string(); }
+  bool has_benchmark_description() const { return at<4>().valid(); }
+  ::protozero::ConstChars benchmark_description() const { return at<4>().as_string(); }
+  bool has_label() const { return at<5>().valid(); }
+  ::protozero::ConstChars label() const { return at<5>().as_string(); }
+  bool has_story_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars story_name() const { return at<6>().as_string(); }
+  bool has_story_tags() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> story_tags() const { return GetRepeated<::protozero::ConstChars>(7); }
+  bool has_story_run_index() const { return at<8>().valid(); }
+  int32_t story_run_index() const { return at<8>().as_int32(); }
+  bool has_had_failures() const { return at<9>().valid(); }
+  bool had_failures() const { return at<9>().as_bool(); }
+};
+
+class ChromeBenchmarkMetadata : public ::protozero::Message {
+ public:
+  using Decoder = ChromeBenchmarkMetadata_Decoder;
+  enum : int32_t {
+    kBenchmarkStartTimeUsFieldNumber = 1,
+    kStoryRunTimeUsFieldNumber = 2,
+    kBenchmarkNameFieldNumber = 3,
+    kBenchmarkDescriptionFieldNumber = 4,
+    kLabelFieldNumber = 5,
+    kStoryNameFieldNumber = 6,
+    kStoryTagsFieldNumber = 7,
+    kStoryRunIndexFieldNumber = 8,
+    kHadFailuresFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeBenchmarkMetadata"; }
+
+
+  using FieldMetadata_BenchmarkStartTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_BenchmarkStartTimeUs kBenchmarkStartTimeUs{};
+  void set_benchmark_start_time_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BenchmarkStartTimeUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StoryRunTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_StoryRunTimeUs kStoryRunTimeUs{};
+  void set_story_run_time_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StoryRunTimeUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BenchmarkName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_BenchmarkName kBenchmarkName{};
+  void set_benchmark_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BenchmarkName::kFieldId, data, size);
+  }
+  void set_benchmark_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_BenchmarkName::kFieldId, chars.data, chars.size);
+  }
+  void set_benchmark_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_BenchmarkName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BenchmarkDescription =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_BenchmarkDescription kBenchmarkDescription{};
+  void set_benchmark_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BenchmarkDescription::kFieldId, data, size);
+  }
+  void set_benchmark_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_BenchmarkDescription::kFieldId, chars.data, chars.size);
+  }
+  void set_benchmark_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_BenchmarkDescription::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Label =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_Label kLabel{};
+  void set_label(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Label::kFieldId, data, size);
+  }
+  void set_label(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Label::kFieldId, chars.data, chars.size);
+  }
+  void set_label(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Label::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StoryName =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_StoryName kStoryName{};
+  void set_story_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StoryName::kFieldId, data, size);
+  }
+  void set_story_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StoryName::kFieldId, chars.data, chars.size);
+  }
+  void set_story_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StoryName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StoryTags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_StoryTags kStoryTags{};
+  void add_story_tags(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StoryTags::kFieldId, data, size);
+  }
+  void add_story_tags(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StoryTags::kFieldId, chars.data, chars.size);
+  }
+  void add_story_tags(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StoryTags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StoryRunIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_StoryRunIndex kStoryRunIndex{};
+  void set_story_run_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StoryRunIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HadFailures =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeBenchmarkMetadata>;
+
+  static constexpr FieldMetadata_HadFailures kHadFailures{};
+  void set_had_failures(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HadFailures::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/chrome/chrome_metadata.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_METADATA_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_METADATA_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class BackgroundTracingMetadata;
+class BackgroundTracingMetadata_TriggerRule;
+class BackgroundTracingMetadata_TriggerRule_HistogramRule;
+class BackgroundTracingMetadata_TriggerRule_NamedRule;
+class ChromeMetadataPacket_FinchHash;
+namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule {
+enum EventType : int32_t;
+}  // namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule
+using BackgroundTracingMetadata_TriggerRule_NamedRule_EventType = perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule::EventType;
+namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule {
+enum TriggerType : int32_t;
+}  // namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule
+using BackgroundTracingMetadata_TriggerRule_TriggerType = perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule::TriggerType;
+
+namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule {
+enum TriggerType : int32_t {
+  TRIGGER_UNSPECIFIED = 0,
+  MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE = 1,
+  MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED = 2,
+};
+} // namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule
+using BackgroundTracingMetadata_TriggerRule_TriggerType = perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule::TriggerType;
+
+
+constexpr BackgroundTracingMetadata_TriggerRule_TriggerType BackgroundTracingMetadata_TriggerRule_TriggerType_MIN = BackgroundTracingMetadata_TriggerRule_TriggerType::TRIGGER_UNSPECIFIED;
+constexpr BackgroundTracingMetadata_TriggerRule_TriggerType BackgroundTracingMetadata_TriggerRule_TriggerType_MAX = BackgroundTracingMetadata_TriggerRule_TriggerType::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* BackgroundTracingMetadata_TriggerRule_TriggerType_Name(::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType::TRIGGER_UNSPECIFIED:
+    return "TRIGGER_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType::MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE:
+    return "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED:
+    return "MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule {
+enum EventType : int32_t {
+  UNSPECIFIED = 0,
+  SESSION_RESTORE = 1,
+  NAVIGATION = 2,
+  STARTUP = 3,
+  REACHED_CODE = 4,
+  CONTENT_TRIGGER = 5,
+  TEST_RULE = 1000,
+};
+} // namespace perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule
+using BackgroundTracingMetadata_TriggerRule_NamedRule_EventType = perfetto_pbzero_enum_BackgroundTracingMetadata_TriggerRule_NamedRule::EventType;
+
+
+constexpr BackgroundTracingMetadata_TriggerRule_NamedRule_EventType BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_MIN = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::UNSPECIFIED;
+constexpr BackgroundTracingMetadata_TriggerRule_NamedRule_EventType BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_MAX = BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::TEST_RULE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_Name(::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::SESSION_RESTORE:
+    return "SESSION_RESTORE";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::NAVIGATION:
+    return "NAVIGATION";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::STARTUP:
+    return "STARTUP";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::REACHED_CODE:
+    return "REACHED_CODE";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::CONTENT_TRIGGER:
+    return "CONTENT_TRIGGER";
+
+  case ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType::TEST_RULE:
+    return "TEST_RULE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class BackgroundTracingMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  BackgroundTracingMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BackgroundTracingMetadata_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BackgroundTracingMetadata_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_triggered_rule() const { return at<1>().valid(); }
+  ::protozero::ConstBytes triggered_rule() const { return at<1>().as_bytes(); }
+  bool has_active_rules() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> active_rules() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_scenario_name_hash() const { return at<3>().valid(); }
+  uint32_t scenario_name_hash() const { return at<3>().as_uint32(); }
+};
+
+class BackgroundTracingMetadata : public ::protozero::Message {
+ public:
+  using Decoder = BackgroundTracingMetadata_Decoder;
+  enum : int32_t {
+    kTriggeredRuleFieldNumber = 1,
+    kActiveRulesFieldNumber = 2,
+    kScenarioNameHashFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BackgroundTracingMetadata"; }
+
+  using TriggerRule = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule;
+
+  using FieldMetadata_TriggeredRule =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata_TriggerRule,
+      BackgroundTracingMetadata>;
+
+  static constexpr FieldMetadata_TriggeredRule kTriggeredRule{};
+  template <typename T = BackgroundTracingMetadata_TriggerRule> T* set_triggered_rule() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ActiveRules =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata_TriggerRule,
+      BackgroundTracingMetadata>;
+
+  static constexpr FieldMetadata_ActiveRules kActiveRules{};
+  template <typename T = BackgroundTracingMetadata_TriggerRule> T* add_active_rules() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ScenarioNameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      BackgroundTracingMetadata>;
+
+  static constexpr FieldMetadata_ScenarioNameHash kScenarioNameHash{};
+  void set_scenario_name_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScenarioNameHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BackgroundTracingMetadata_TriggerRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BackgroundTracingMetadata_TriggerRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BackgroundTracingMetadata_TriggerRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BackgroundTracingMetadata_TriggerRule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trigger_type() const { return at<1>().valid(); }
+  int32_t trigger_type() const { return at<1>().as_int32(); }
+  bool has_histogram_rule() const { return at<2>().valid(); }
+  ::protozero::ConstBytes histogram_rule() const { return at<2>().as_bytes(); }
+  bool has_named_rule() const { return at<3>().valid(); }
+  ::protozero::ConstBytes named_rule() const { return at<3>().as_bytes(); }
+  bool has_name_hash() const { return at<4>().valid(); }
+  uint32_t name_hash() const { return at<4>().as_uint32(); }
+};
+
+class BackgroundTracingMetadata_TriggerRule : public ::protozero::Message {
+ public:
+  using Decoder = BackgroundTracingMetadata_TriggerRule_Decoder;
+  enum : int32_t {
+    kTriggerTypeFieldNumber = 1,
+    kHistogramRuleFieldNumber = 2,
+    kNamedRuleFieldNumber = 3,
+    kNameHashFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BackgroundTracingMetadata.TriggerRule"; }
+
+  using HistogramRule = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_HistogramRule;
+  using NamedRule = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule;
+
+  using TriggerType = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType;
+  static inline const char* TriggerType_Name(TriggerType value) {
+    return ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType_Name(value);
+  }
+  static inline const TriggerType TRIGGER_UNSPECIFIED = TriggerType::TRIGGER_UNSPECIFIED;
+  static inline const TriggerType MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE = TriggerType::MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE;
+  static inline const TriggerType MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED = TriggerType::MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED;
+
+  using FieldMetadata_TriggerType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType,
+      BackgroundTracingMetadata_TriggerRule>;
+
+  static constexpr FieldMetadata_TriggerType kTriggerType{};
+  void set_trigger_type(::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_TriggerType value) {
+    static constexpr uint32_t field_id = FieldMetadata_TriggerType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HistogramRule =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata_TriggerRule_HistogramRule,
+      BackgroundTracingMetadata_TriggerRule>;
+
+  static constexpr FieldMetadata_HistogramRule kHistogramRule{};
+  template <typename T = BackgroundTracingMetadata_TriggerRule_HistogramRule> T* set_histogram_rule() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_NamedRule =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata_TriggerRule_NamedRule,
+      BackgroundTracingMetadata_TriggerRule>;
+
+  static constexpr FieldMetadata_NamedRule kNamedRule{};
+  template <typename T = BackgroundTracingMetadata_TriggerRule_NamedRule> T* set_named_rule() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_NameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32,
+      uint32_t,
+      BackgroundTracingMetadata_TriggerRule>;
+
+  static constexpr FieldMetadata_NameHash kNameHash{};
+  void set_name_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BackgroundTracingMetadata_TriggerRule_NamedRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BackgroundTracingMetadata_TriggerRule_NamedRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BackgroundTracingMetadata_TriggerRule_NamedRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BackgroundTracingMetadata_TriggerRule_NamedRule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_type() const { return at<1>().valid(); }
+  int32_t event_type() const { return at<1>().as_int32(); }
+  bool has_content_trigger_name_hash() const { return at<2>().valid(); }
+  uint64_t content_trigger_name_hash() const { return at<2>().as_uint64(); }
+};
+
+class BackgroundTracingMetadata_TriggerRule_NamedRule : public ::protozero::Message {
+ public:
+  using Decoder = BackgroundTracingMetadata_TriggerRule_NamedRule_Decoder;
+  enum : int32_t {
+    kEventTypeFieldNumber = 1,
+    kContentTriggerNameHashFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BackgroundTracingMetadata.TriggerRule.NamedRule"; }
+
+
+  using EventType = ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType;
+  static inline const char* EventType_Name(EventType value) {
+    return ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType_Name(value);
+  }
+  static inline const EventType UNSPECIFIED = EventType::UNSPECIFIED;
+  static inline const EventType SESSION_RESTORE = EventType::SESSION_RESTORE;
+  static inline const EventType NAVIGATION = EventType::NAVIGATION;
+  static inline const EventType STARTUP = EventType::STARTUP;
+  static inline const EventType REACHED_CODE = EventType::REACHED_CODE;
+  static inline const EventType CONTENT_TRIGGER = EventType::CONTENT_TRIGGER;
+  static inline const EventType TEST_RULE = EventType::TEST_RULE;
+
+  using FieldMetadata_EventType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType,
+      BackgroundTracingMetadata_TriggerRule_NamedRule>;
+
+  static constexpr FieldMetadata_EventType kEventType{};
+  void set_event_type(::perfetto::protos::pbzero::BackgroundTracingMetadata_TriggerRule_NamedRule_EventType value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ContentTriggerNameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      BackgroundTracingMetadata_TriggerRule_NamedRule>;
+
+  static constexpr FieldMetadata_ContentTriggerNameHash kContentTriggerNameHash{};
+  void set_content_trigger_name_hash(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ContentTriggerNameHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BackgroundTracingMetadata_TriggerRule_HistogramRule_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BackgroundTracingMetadata_TriggerRule_HistogramRule_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BackgroundTracingMetadata_TriggerRule_HistogramRule_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BackgroundTracingMetadata_TriggerRule_HistogramRule_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_histogram_name_hash() const { return at<1>().valid(); }
+  uint64_t histogram_name_hash() const { return at<1>().as_uint64(); }
+  bool has_histogram_min_trigger() const { return at<2>().valid(); }
+  int64_t histogram_min_trigger() const { return at<2>().as_int64(); }
+  bool has_histogram_max_trigger() const { return at<3>().valid(); }
+  int64_t histogram_max_trigger() const { return at<3>().as_int64(); }
+};
+
+class BackgroundTracingMetadata_TriggerRule_HistogramRule : public ::protozero::Message {
+ public:
+  using Decoder = BackgroundTracingMetadata_TriggerRule_HistogramRule_Decoder;
+  enum : int32_t {
+    kHistogramNameHashFieldNumber = 1,
+    kHistogramMinTriggerFieldNumber = 2,
+    kHistogramMaxTriggerFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BackgroundTracingMetadata.TriggerRule.HistogramRule"; }
+
+
+  using FieldMetadata_HistogramNameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      BackgroundTracingMetadata_TriggerRule_HistogramRule>;
+
+  static constexpr FieldMetadata_HistogramNameHash kHistogramNameHash{};
+  void set_histogram_name_hash(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HistogramNameHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HistogramMinTrigger =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BackgroundTracingMetadata_TriggerRule_HistogramRule>;
+
+  static constexpr FieldMetadata_HistogramMinTrigger kHistogramMinTrigger{};
+  void set_histogram_min_trigger(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HistogramMinTrigger::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HistogramMaxTrigger =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BackgroundTracingMetadata_TriggerRule_HistogramRule>;
+
+  static constexpr FieldMetadata_HistogramMaxTrigger kHistogramMaxTrigger{};
+  void set_histogram_max_trigger(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HistogramMaxTrigger::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeMetadataPacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeMetadataPacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeMetadataPacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeMetadataPacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_background_tracing_metadata() const { return at<1>().valid(); }
+  ::protozero::ConstBytes background_tracing_metadata() const { return at<1>().as_bytes(); }
+  bool has_chrome_version_code() const { return at<2>().valid(); }
+  int32_t chrome_version_code() const { return at<2>().as_int32(); }
+  bool has_enabled_categories() const { return at<3>().valid(); }
+  ::protozero::ConstChars enabled_categories() const { return at<3>().as_string(); }
+  bool has_field_trial_hashes() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> field_trial_hashes() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class ChromeMetadataPacket : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMetadataPacket_Decoder;
+  enum : int32_t {
+    kBackgroundTracingMetadataFieldNumber = 1,
+    kChromeVersionCodeFieldNumber = 2,
+    kEnabledCategoriesFieldNumber = 3,
+    kFieldTrialHashesFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeMetadataPacket"; }
+
+  using FinchHash = ::perfetto::protos::pbzero::ChromeMetadataPacket_FinchHash;
+
+  using FieldMetadata_BackgroundTracingMetadata =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BackgroundTracingMetadata,
+      ChromeMetadataPacket>;
+
+  static constexpr FieldMetadata_BackgroundTracingMetadata kBackgroundTracingMetadata{};
+  template <typename T = BackgroundTracingMetadata> T* set_background_tracing_metadata() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ChromeVersionCode =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeMetadataPacket>;
+
+  static constexpr FieldMetadata_ChromeVersionCode kChromeVersionCode{};
+  void set_chrome_version_code(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChromeVersionCode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnabledCategories =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMetadataPacket>;
+
+  static constexpr FieldMetadata_EnabledCategories kEnabledCategories{};
+  void set_enabled_categories(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EnabledCategories::kFieldId, data, size);
+  }
+  void set_enabled_categories(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EnabledCategories::kFieldId, chars.data, chars.size);
+  }
+  void set_enabled_categories(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnabledCategories::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FieldTrialHashes =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeMetadataPacket_FinchHash,
+      ChromeMetadataPacket>;
+
+  static constexpr FieldMetadata_FieldTrialHashes kFieldTrialHashes{};
+  template <typename T = ChromeMetadataPacket_FinchHash> T* add_field_trial_hashes() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class ChromeMetadataPacket_FinchHash_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeMetadataPacket_FinchHash_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeMetadataPacket_FinchHash_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeMetadataPacket_FinchHash_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  uint32_t name() const { return at<1>().as_uint32(); }
+  bool has_group() const { return at<2>().valid(); }
+  uint32_t group() const { return at<2>().as_uint32(); }
+};
+
+class ChromeMetadataPacket_FinchHash : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMetadataPacket_FinchHash_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kGroupFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeMetadataPacket.FinchHash"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeMetadataPacket_FinchHash>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeMetadataPacket_FinchHash>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_TRACE_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CHROME_CHROME_TRACE_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeLegacyJsonTrace;
+class ChromeMetadata;
+class ChromeStringTableEntry;
+class ChromeTraceEvent;
+class ChromeTraceEvent_Arg;
+class ChromeTracedValue;
+namespace perfetto_pbzero_enum_ChromeLegacyJsonTrace {
+enum TraceType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeLegacyJsonTrace
+using ChromeLegacyJsonTrace_TraceType = perfetto_pbzero_enum_ChromeLegacyJsonTrace::TraceType;
+namespace perfetto_pbzero_enum_ChromeTracedValue {
+enum NestedType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeTracedValue
+using ChromeTracedValue_NestedType = perfetto_pbzero_enum_ChromeTracedValue::NestedType;
+
+namespace perfetto_pbzero_enum_ChromeLegacyJsonTrace {
+enum TraceType : int32_t {
+  USER_TRACE = 0,
+  SYSTEM_TRACE = 1,
+};
+} // namespace perfetto_pbzero_enum_ChromeLegacyJsonTrace
+using ChromeLegacyJsonTrace_TraceType = perfetto_pbzero_enum_ChromeLegacyJsonTrace::TraceType;
+
+
+constexpr ChromeLegacyJsonTrace_TraceType ChromeLegacyJsonTrace_TraceType_MIN = ChromeLegacyJsonTrace_TraceType::USER_TRACE;
+constexpr ChromeLegacyJsonTrace_TraceType ChromeLegacyJsonTrace_TraceType_MAX = ChromeLegacyJsonTrace_TraceType::SYSTEM_TRACE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeLegacyJsonTrace_TraceType_Name(::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType::USER_TRACE:
+    return "USER_TRACE";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType::SYSTEM_TRACE:
+    return "SYSTEM_TRACE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeTracedValue {
+enum NestedType : int32_t {
+  DICT = 0,
+  ARRAY = 1,
+};
+} // namespace perfetto_pbzero_enum_ChromeTracedValue
+using ChromeTracedValue_NestedType = perfetto_pbzero_enum_ChromeTracedValue::NestedType;
+
+
+constexpr ChromeTracedValue_NestedType ChromeTracedValue_NestedType_MIN = ChromeTracedValue_NestedType::DICT;
+constexpr ChromeTracedValue_NestedType ChromeTracedValue_NestedType_MAX = ChromeTracedValue_NestedType::ARRAY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeTracedValue_NestedType_Name(::perfetto::protos::pbzero::ChromeTracedValue_NestedType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeTracedValue_NestedType::DICT:
+    return "DICT";
+
+  case ::perfetto::protos::pbzero::ChromeTracedValue_NestedType::ARRAY:
+    return "ARRAY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeEventBundle_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeEventBundle_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeEventBundle_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeEventBundle_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trace_events() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> trace_events() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_metadata() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> metadata() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_legacy_ftrace_output() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> legacy_ftrace_output() const { return GetRepeated<::protozero::ConstChars>(4); }
+  bool has_legacy_json_trace() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> legacy_json_trace() const { return GetRepeated<::protozero::ConstBytes>(5); }
+  bool has_string_table() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> string_table() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class ChromeEventBundle : public ::protozero::Message {
+ public:
+  using Decoder = ChromeEventBundle_Decoder;
+  enum : int32_t {
+    kTraceEventsFieldNumber = 1,
+    kMetadataFieldNumber = 2,
+    kLegacyFtraceOutputFieldNumber = 4,
+    kLegacyJsonTraceFieldNumber = 5,
+    kStringTableFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeEventBundle"; }
+
+
+  using FieldMetadata_TraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTraceEvent,
+      ChromeEventBundle>;
+
+  static constexpr FieldMetadata_TraceEvents kTraceEvents{};
+  template <typename T = ChromeTraceEvent> T* add_trace_events() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Metadata =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeMetadata,
+      ChromeEventBundle>;
+
+  static constexpr FieldMetadata_Metadata kMetadata{};
+  template <typename T = ChromeMetadata> T* add_metadata() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_LegacyFtraceOutput =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeEventBundle>;
+
+  static constexpr FieldMetadata_LegacyFtraceOutput kLegacyFtraceOutput{};
+  void add_legacy_ftrace_output(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LegacyFtraceOutput::kFieldId, data, size);
+  }
+  void add_legacy_ftrace_output(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LegacyFtraceOutput::kFieldId, chars.data, chars.size);
+  }
+  void add_legacy_ftrace_output(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacyFtraceOutput::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LegacyJsonTrace =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeLegacyJsonTrace,
+      ChromeEventBundle>;
+
+  static constexpr FieldMetadata_LegacyJsonTrace kLegacyJsonTrace{};
+  template <typename T = ChromeLegacyJsonTrace> T* add_legacy_json_trace() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_StringTable =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeStringTableEntry,
+      ChromeEventBundle>;
+
+  static constexpr FieldMetadata_StringTable kStringTable{};
+  template <typename T = ChromeStringTableEntry> T* add_string_table() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class ChromeLegacyJsonTrace_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeLegacyJsonTrace_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeLegacyJsonTrace_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeLegacyJsonTrace_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  int32_t type() const { return at<1>().as_int32(); }
+  bool has_data() const { return at<2>().valid(); }
+  ::protozero::ConstChars data() const { return at<2>().as_string(); }
+};
+
+class ChromeLegacyJsonTrace : public ::protozero::Message {
+ public:
+  using Decoder = ChromeLegacyJsonTrace_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kDataFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeLegacyJsonTrace"; }
+
+
+  using TraceType = ::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType;
+  static inline const char* TraceType_Name(TraceType value) {
+    return ::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType_Name(value);
+  }
+  static inline const TraceType USER_TRACE = TraceType::USER_TRACE;
+  static inline const TraceType SYSTEM_TRACE = TraceType::SYSTEM_TRACE;
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType,
+      ChromeLegacyJsonTrace>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(::perfetto::protos::pbzero::ChromeLegacyJsonTrace_TraceType value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Data =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeLegacyJsonTrace>;
+
+  static constexpr FieldMetadata_Data kData{};
+  void set_data(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Data::kFieldId, data, size);
+  }
+  void set_data(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Data::kFieldId, chars.data, chars.size);
+  }
+  void set_data(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Data::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeMetadata_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeMetadata_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_string_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<2>().as_string(); }
+  bool has_bool_value() const { return at<3>().valid(); }
+  bool bool_value() const { return at<3>().as_bool(); }
+  bool has_int_value() const { return at<4>().valid(); }
+  int64_t int_value() const { return at<4>().as_int64(); }
+  bool has_json_value() const { return at<5>().valid(); }
+  ::protozero::ConstChars json_value() const { return at<5>().as_string(); }
+};
+
+class ChromeMetadata : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMetadata_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStringValueFieldNumber = 2,
+    kBoolValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kJsonValueFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeMetadata"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMetadata>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMetadata>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BoolValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeMetadata>;
+
+  static constexpr FieldMetadata_BoolValue kBoolValue{};
+  void set_bool_value(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BoolValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeMetadata>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_JsonValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMetadata>;
+
+  static constexpr FieldMetadata_JsonValue kJsonValue{};
+  void set_json_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_JsonValue::kFieldId, data, size);
+  }
+  void set_json_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_JsonValue::kFieldId, chars.data, chars.size);
+  }
+  void set_json_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_JsonValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeTraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/16, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeTraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeTraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeTraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_timestamp() const { return at<2>().valid(); }
+  int64_t timestamp() const { return at<2>().as_int64(); }
+  bool has_phase() const { return at<3>().valid(); }
+  int32_t phase() const { return at<3>().as_int32(); }
+  bool has_thread_id() const { return at<4>().valid(); }
+  int32_t thread_id() const { return at<4>().as_int32(); }
+  bool has_duration() const { return at<5>().valid(); }
+  int64_t duration() const { return at<5>().as_int64(); }
+  bool has_thread_duration() const { return at<6>().valid(); }
+  int64_t thread_duration() const { return at<6>().as_int64(); }
+  bool has_scope() const { return at<7>().valid(); }
+  ::protozero::ConstChars scope() const { return at<7>().as_string(); }
+  bool has_id() const { return at<8>().valid(); }
+  uint64_t id() const { return at<8>().as_uint64(); }
+  bool has_flags() const { return at<9>().valid(); }
+  uint32_t flags() const { return at<9>().as_uint32(); }
+  bool has_category_group_name() const { return at<10>().valid(); }
+  ::protozero::ConstChars category_group_name() const { return at<10>().as_string(); }
+  bool has_process_id() const { return at<11>().valid(); }
+  int32_t process_id() const { return at<11>().as_int32(); }
+  bool has_thread_timestamp() const { return at<12>().valid(); }
+  int64_t thread_timestamp() const { return at<12>().as_int64(); }
+  bool has_bind_id() const { return at<13>().valid(); }
+  uint64_t bind_id() const { return at<13>().as_uint64(); }
+  bool has_args() const { return at<14>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> args() const { return GetRepeated<::protozero::ConstBytes>(14); }
+  bool has_name_index() const { return at<15>().valid(); }
+  uint32_t name_index() const { return at<15>().as_uint32(); }
+  bool has_category_group_name_index() const { return at<16>().valid(); }
+  uint32_t category_group_name_index() const { return at<16>().as_uint32(); }
+};
+
+class ChromeTraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ChromeTraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kTimestampFieldNumber = 2,
+    kPhaseFieldNumber = 3,
+    kThreadIdFieldNumber = 4,
+    kDurationFieldNumber = 5,
+    kThreadDurationFieldNumber = 6,
+    kScopeFieldNumber = 7,
+    kIdFieldNumber = 8,
+    kFlagsFieldNumber = 9,
+    kCategoryGroupNameFieldNumber = 10,
+    kProcessIdFieldNumber = 11,
+    kThreadTimestampFieldNumber = 12,
+    kBindIdFieldNumber = 13,
+    kArgsFieldNumber = 14,
+    kNameIndexFieldNumber = 15,
+    kCategoryGroupNameIndexFieldNumber = 16,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeTraceEvent"; }
+
+  using Arg = ::perfetto::protos::pbzero::ChromeTraceEvent_Arg;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Phase =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Phase kPhase{};
+  void set_phase(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Phase::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_ThreadId kThreadId{};
+  void set_thread_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Duration =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Duration kDuration{};
+  void set_duration(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Duration::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadDuration =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_ThreadDuration kThreadDuration{};
+  void set_thread_duration(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadDuration::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Scope =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Scope kScope{};
+  void set_scope(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Scope::kFieldId, data, size);
+  }
+  void set_scope(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Scope::kFieldId, chars.data, chars.size);
+  }
+  void set_scope(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Scope::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CategoryGroupName =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_CategoryGroupName kCategoryGroupName{};
+  void set_category_group_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_CategoryGroupName::kFieldId, data, size);
+  }
+  void set_category_group_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_CategoryGroupName::kFieldId, chars.data, chars.size);
+  }
+  void set_category_group_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_CategoryGroupName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_ProcessId kProcessId{};
+  void set_process_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_ThreadTimestamp kThreadTimestamp{};
+  void set_thread_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BindId =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_BindId kBindId{};
+  void set_bind_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BindId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Args =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTraceEvent_Arg,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_Args kArgs{};
+  template <typename T = ChromeTraceEvent_Arg> T* add_args() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_NameIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_NameIndex kNameIndex{};
+  void set_name_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CategoryGroupNameIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeTraceEvent>;
+
+  static constexpr FieldMetadata_CategoryGroupNameIndex kCategoryGroupNameIndex{};
+  void set_category_group_name_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CategoryGroupNameIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeTraceEvent_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeTraceEvent_Arg_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeTraceEvent_Arg_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeTraceEvent_Arg_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_bool_value() const { return at<2>().valid(); }
+  bool bool_value() const { return at<2>().as_bool(); }
+  bool has_uint_value() const { return at<3>().valid(); }
+  uint64_t uint_value() const { return at<3>().as_uint64(); }
+  bool has_int_value() const { return at<4>().valid(); }
+  int64_t int_value() const { return at<4>().as_int64(); }
+  bool has_double_value() const { return at<5>().valid(); }
+  double double_value() const { return at<5>().as_double(); }
+  bool has_string_value() const { return at<6>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<6>().as_string(); }
+  bool has_pointer_value() const { return at<7>().valid(); }
+  uint64_t pointer_value() const { return at<7>().as_uint64(); }
+  bool has_json_value() const { return at<8>().valid(); }
+  ::protozero::ConstChars json_value() const { return at<8>().as_string(); }
+  bool has_traced_value() const { return at<10>().valid(); }
+  ::protozero::ConstBytes traced_value() const { return at<10>().as_bytes(); }
+  bool has_name_index() const { return at<9>().valid(); }
+  uint32_t name_index() const { return at<9>().as_uint32(); }
+};
+
+class ChromeTraceEvent_Arg : public ::protozero::Message {
+ public:
+  using Decoder = ChromeTraceEvent_Arg_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kBoolValueFieldNumber = 2,
+    kUintValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kDoubleValueFieldNumber = 5,
+    kStringValueFieldNumber = 6,
+    kPointerValueFieldNumber = 7,
+    kJsonValueFieldNumber = 8,
+    kTracedValueFieldNumber = 10,
+    kNameIndexFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeTraceEvent.Arg"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BoolValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_BoolValue kBoolValue{};
+  void set_bool_value(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BoolValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UintValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_UintValue kUintValue{};
+  void set_uint_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UintValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PointerValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_PointerValue kPointerValue{};
+  void set_pointer_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PointerValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_JsonValue =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_JsonValue kJsonValue{};
+  void set_json_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_JsonValue::kFieldId, data, size);
+  }
+  void set_json_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_JsonValue::kFieldId, chars.data, chars.size);
+  }
+  void set_json_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_JsonValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TracedValue =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTracedValue,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_TracedValue kTracedValue{};
+  template <typename T = ChromeTracedValue> T* set_traced_value() {
+    return BeginNestedMessage<T>(10);
+  }
+
+
+  using FieldMetadata_NameIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeTraceEvent_Arg>;
+
+  static constexpr FieldMetadata_NameIndex kNameIndex{};
+  void set_name_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeStringTableEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeStringTableEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeStringTableEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeStringTableEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_value() const { return at<1>().valid(); }
+  ::protozero::ConstChars value() const { return at<1>().as_string(); }
+  bool has_index() const { return at<2>().valid(); }
+  int32_t index() const { return at<2>().as_int32(); }
+};
+
+class ChromeStringTableEntry : public ::protozero::Message {
+ public:
+  using Decoder = ChromeStringTableEntry_Decoder;
+  enum : int32_t {
+    kValueFieldNumber = 1,
+    kIndexFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeStringTableEntry"; }
+
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeStringTableEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeStringTableEntry>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeTracedValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeTracedValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeTracedValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeTracedValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nested_type() const { return at<1>().valid(); }
+  int32_t nested_type() const { return at<1>().as_int32(); }
+  bool has_dict_keys() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> dict_keys() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_dict_values() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> dict_values() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_array_values() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> array_values() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_int_value() const { return at<5>().valid(); }
+  int32_t int_value() const { return at<5>().as_int32(); }
+  bool has_double_value() const { return at<6>().valid(); }
+  double double_value() const { return at<6>().as_double(); }
+  bool has_bool_value() const { return at<7>().valid(); }
+  bool bool_value() const { return at<7>().as_bool(); }
+  bool has_string_value() const { return at<8>().valid(); }
+  ::protozero::ConstChars string_value() const { return at<8>().as_string(); }
+};
+
+class ChromeTracedValue : public ::protozero::Message {
+ public:
+  using Decoder = ChromeTracedValue_Decoder;
+  enum : int32_t {
+    kNestedTypeFieldNumber = 1,
+    kDictKeysFieldNumber = 2,
+    kDictValuesFieldNumber = 3,
+    kArrayValuesFieldNumber = 4,
+    kIntValueFieldNumber = 5,
+    kDoubleValueFieldNumber = 6,
+    kBoolValueFieldNumber = 7,
+    kStringValueFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeTracedValue"; }
+
+
+  using NestedType = ::perfetto::protos::pbzero::ChromeTracedValue_NestedType;
+  static inline const char* NestedType_Name(NestedType value) {
+    return ::perfetto::protos::pbzero::ChromeTracedValue_NestedType_Name(value);
+  }
+  static inline const NestedType DICT = NestedType::DICT;
+  static inline const NestedType ARRAY = NestedType::ARRAY;
+
+  using FieldMetadata_NestedType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeTracedValue_NestedType,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_NestedType kNestedType{};
+  void set_nested_type(::perfetto::protos::pbzero::ChromeTracedValue_NestedType value) {
+    static constexpr uint32_t field_id = FieldMetadata_NestedType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DictKeys =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_DictKeys kDictKeys{};
+  void add_dict_keys(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, data, size);
+  }
+  void add_dict_keys(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DictKeys::kFieldId, chars.data, chars.size);
+  }
+  void add_dict_keys(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DictKeys::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DictValues =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTracedValue,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_DictValues kDictValues{};
+  template <typename T = ChromeTracedValue> T* add_dict_values() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ArrayValues =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeTracedValue,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_ArrayValues kArrayValues{};
+  template <typename T = ChromeTracedValue> T* add_array_values() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BoolValue =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_BoolValue kBoolValue{};
+  void set_bool_value(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BoolValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringValue =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeTracedValue>;
+
+  static constexpr FieldMetadata_StringValue kStringValue{};
+  void set_string_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, data, size);
+  }
+  void set_string_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringValue::kFieldId, chars.data, chars.size);
+  }
+  void set_string_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/etw/etw.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadState : int32_t;
+}  // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadState = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadState;
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadWaitMode : int32_t;
+}  // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadWaitMode = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadWaitMode;
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadWaitReason : int32_t;
+}  // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadWaitReason = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadWaitReason;
+namespace perfetto_pbzero_enum_ReadyThreadEtwEvent {
+enum AdjustReason : int32_t;
+}  // namespace perfetto_pbzero_enum_ReadyThreadEtwEvent
+using ReadyThreadEtwEvent_AdjustReason = perfetto_pbzero_enum_ReadyThreadEtwEvent::AdjustReason;
+namespace perfetto_pbzero_enum_ReadyThreadEtwEvent {
+enum TraceFlag : int32_t;
+}  // namespace perfetto_pbzero_enum_ReadyThreadEtwEvent
+using ReadyThreadEtwEvent_TraceFlag = perfetto_pbzero_enum_ReadyThreadEtwEvent::TraceFlag;
+
+namespace perfetto_pbzero_enum_ReadyThreadEtwEvent {
+enum AdjustReason : int32_t {
+  IGNORE_THE_INCREMENT = 0,
+  APPLY_INCREMENT = 1,
+  APPLY_INCREMENT_BOOST = 2,
+};
+} // namespace perfetto_pbzero_enum_ReadyThreadEtwEvent
+using ReadyThreadEtwEvent_AdjustReason = perfetto_pbzero_enum_ReadyThreadEtwEvent::AdjustReason;
+
+
+constexpr ReadyThreadEtwEvent_AdjustReason ReadyThreadEtwEvent_AdjustReason_MIN = ReadyThreadEtwEvent_AdjustReason::IGNORE_THE_INCREMENT;
+constexpr ReadyThreadEtwEvent_AdjustReason ReadyThreadEtwEvent_AdjustReason_MAX = ReadyThreadEtwEvent_AdjustReason::APPLY_INCREMENT_BOOST;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ReadyThreadEtwEvent_AdjustReason_Name(::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason::IGNORE_THE_INCREMENT:
+    return "IGNORE_THE_INCREMENT";
+
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason::APPLY_INCREMENT:
+    return "APPLY_INCREMENT";
+
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason::APPLY_INCREMENT_BOOST:
+    return "APPLY_INCREMENT_BOOST";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ReadyThreadEtwEvent {
+enum TraceFlag : int32_t {
+  TRACE_FLAG_UNSPECIFIED = 0,
+  THREAD_READIED = 1,
+  KERNEL_STACK_SWAPPED_OUT = 2,
+  PROCESS_ADDRESS_SWAPPED_OUT = 4,
+};
+} // namespace perfetto_pbzero_enum_ReadyThreadEtwEvent
+using ReadyThreadEtwEvent_TraceFlag = perfetto_pbzero_enum_ReadyThreadEtwEvent::TraceFlag;
+
+
+constexpr ReadyThreadEtwEvent_TraceFlag ReadyThreadEtwEvent_TraceFlag_MIN = ReadyThreadEtwEvent_TraceFlag::TRACE_FLAG_UNSPECIFIED;
+constexpr ReadyThreadEtwEvent_TraceFlag ReadyThreadEtwEvent_TraceFlag_MAX = ReadyThreadEtwEvent_TraceFlag::PROCESS_ADDRESS_SWAPPED_OUT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ReadyThreadEtwEvent_TraceFlag_Name(::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag::TRACE_FLAG_UNSPECIFIED:
+    return "TRACE_FLAG_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag::THREAD_READIED:
+    return "THREAD_READIED";
+
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag::KERNEL_STACK_SWAPPED_OUT:
+    return "KERNEL_STACK_SWAPPED_OUT";
+
+  case ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag::PROCESS_ADDRESS_SWAPPED_OUT:
+    return "PROCESS_ADDRESS_SWAPPED_OUT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadWaitReason : int32_t {
+  EXECUTIVE = 0,
+  FREE_PAGE = 1,
+  PAGE_IN = 2,
+  POOL_ALLOCATION = 3,
+  DELAY_EXECUTION = 4,
+  SUSPEND = 5,
+  USER_REQUEST = 6,
+  WR_EXECUTIVE = 7,
+  WR_FREE_PAGE = 8,
+  WR_PAGE_IN = 9,
+  WR_POOL_ALLOCATION = 10,
+  WR_DELAY_EXECUTION = 11,
+  WR_SUSPENDED = 12,
+  WR_USER_REQUEST = 13,
+  WR_EVENT_PAIR = 14,
+  WR_QUEUE = 15,
+  WR_LPC_RECEIVER = 16,
+  WR_LPC_REPLY = 17,
+  WR_VIRTUAL_MEMORY = 18,
+  WR_PAGE_OUT = 19,
+  WR_RENDEZ_VOUS = 20,
+  WR_KEYED_EVENT = 21,
+  WR_TERMINATED = 22,
+  WR_PROCESS_IN_SWAP = 23,
+  WR_CPU_RATE_CONTROL = 24,
+  WR_CALLOUT_STACK = 25,
+  WR_KERNEL = 26,
+  WR_RESOURCE = 27,
+  WR_PUSH_LOCK = 28,
+  WR_MUTEX = 29,
+  WR_QUANTUM_END = 30,
+  WR_DISPATCH_INT = 31,
+  WR_PREEMPTED = 32,
+  WR_YIELD_EXECUTION = 33,
+  WR_FAST_MUTEX = 34,
+  WR_GUARD_MUTEX = 35,
+  WR_RUNDOWN = 36,
+  MAXIMUM_WAIT_REASON = 37,
+};
+} // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadWaitReason = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadWaitReason;
+
+
+constexpr CSwitchEtwEvent_OldThreadWaitReason CSwitchEtwEvent_OldThreadWaitReason_MIN = CSwitchEtwEvent_OldThreadWaitReason::EXECUTIVE;
+constexpr CSwitchEtwEvent_OldThreadWaitReason CSwitchEtwEvent_OldThreadWaitReason_MAX = CSwitchEtwEvent_OldThreadWaitReason::MAXIMUM_WAIT_REASON;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* CSwitchEtwEvent_OldThreadWaitReason_Name(::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::EXECUTIVE:
+    return "EXECUTIVE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::FREE_PAGE:
+    return "FREE_PAGE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::PAGE_IN:
+    return "PAGE_IN";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::POOL_ALLOCATION:
+    return "POOL_ALLOCATION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::DELAY_EXECUTION:
+    return "DELAY_EXECUTION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::SUSPEND:
+    return "SUSPEND";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::USER_REQUEST:
+    return "USER_REQUEST";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_EXECUTIVE:
+    return "WR_EXECUTIVE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_FREE_PAGE:
+    return "WR_FREE_PAGE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_PAGE_IN:
+    return "WR_PAGE_IN";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_POOL_ALLOCATION:
+    return "WR_POOL_ALLOCATION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_DELAY_EXECUTION:
+    return "WR_DELAY_EXECUTION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_SUSPENDED:
+    return "WR_SUSPENDED";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_USER_REQUEST:
+    return "WR_USER_REQUEST";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_EVENT_PAIR:
+    return "WR_EVENT_PAIR";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_QUEUE:
+    return "WR_QUEUE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_LPC_RECEIVER:
+    return "WR_LPC_RECEIVER";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_LPC_REPLY:
+    return "WR_LPC_REPLY";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_VIRTUAL_MEMORY:
+    return "WR_VIRTUAL_MEMORY";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_PAGE_OUT:
+    return "WR_PAGE_OUT";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_RENDEZ_VOUS:
+    return "WR_RENDEZ_VOUS";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_KEYED_EVENT:
+    return "WR_KEYED_EVENT";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_TERMINATED:
+    return "WR_TERMINATED";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_PROCESS_IN_SWAP:
+    return "WR_PROCESS_IN_SWAP";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_CPU_RATE_CONTROL:
+    return "WR_CPU_RATE_CONTROL";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_CALLOUT_STACK:
+    return "WR_CALLOUT_STACK";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_KERNEL:
+    return "WR_KERNEL";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_RESOURCE:
+    return "WR_RESOURCE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_PUSH_LOCK:
+    return "WR_PUSH_LOCK";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_MUTEX:
+    return "WR_MUTEX";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_QUANTUM_END:
+    return "WR_QUANTUM_END";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_DISPATCH_INT:
+    return "WR_DISPATCH_INT";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_PREEMPTED:
+    return "WR_PREEMPTED";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_YIELD_EXECUTION:
+    return "WR_YIELD_EXECUTION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_FAST_MUTEX:
+    return "WR_FAST_MUTEX";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_GUARD_MUTEX:
+    return "WR_GUARD_MUTEX";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::WR_RUNDOWN:
+    return "WR_RUNDOWN";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason::MAXIMUM_WAIT_REASON:
+    return "MAXIMUM_WAIT_REASON";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadWaitMode : int32_t {
+  KERNEL_MODE = 0,
+  USER_MODE = 1,
+};
+} // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadWaitMode = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadWaitMode;
+
+
+constexpr CSwitchEtwEvent_OldThreadWaitMode CSwitchEtwEvent_OldThreadWaitMode_MIN = CSwitchEtwEvent_OldThreadWaitMode::KERNEL_MODE;
+constexpr CSwitchEtwEvent_OldThreadWaitMode CSwitchEtwEvent_OldThreadWaitMode_MAX = CSwitchEtwEvent_OldThreadWaitMode::USER_MODE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* CSwitchEtwEvent_OldThreadWaitMode_Name(::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode::KERNEL_MODE:
+    return "KERNEL_MODE";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode::USER_MODE:
+    return "USER_MODE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_CSwitchEtwEvent {
+enum OldThreadState : int32_t {
+  INITIALIZED = 0,
+  READY = 1,
+  RUNNING = 2,
+  STANDBY = 3,
+  TERMINATED = 4,
+  WAITING = 5,
+  TRANSITION = 6,
+  DEFERRED_READY = 7,
+};
+} // namespace perfetto_pbzero_enum_CSwitchEtwEvent
+using CSwitchEtwEvent_OldThreadState = perfetto_pbzero_enum_CSwitchEtwEvent::OldThreadState;
+
+
+constexpr CSwitchEtwEvent_OldThreadState CSwitchEtwEvent_OldThreadState_MIN = CSwitchEtwEvent_OldThreadState::INITIALIZED;
+constexpr CSwitchEtwEvent_OldThreadState CSwitchEtwEvent_OldThreadState_MAX = CSwitchEtwEvent_OldThreadState::DEFERRED_READY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* CSwitchEtwEvent_OldThreadState_Name(::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::INITIALIZED:
+    return "INITIALIZED";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::READY:
+    return "READY";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::RUNNING:
+    return "RUNNING";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::STANDBY:
+    return "STANDBY";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::TERMINATED:
+    return "TERMINATED";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::WAITING:
+    return "WAITING";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::TRANSITION:
+    return "TRANSITION";
+
+  case ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState::DEFERRED_READY:
+    return "DEFERRED_READY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ReadyThreadEtwEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ReadyThreadEtwEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ReadyThreadEtwEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ReadyThreadEtwEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_t_thread_id() const { return at<1>().valid(); }
+  uint32_t t_thread_id() const { return at<1>().as_uint32(); }
+  bool has_adjust_reason() const { return at<2>().valid(); }
+  int32_t adjust_reason() const { return at<2>().as_int32(); }
+  bool has_adjust_increment() const { return at<3>().valid(); }
+  int32_t adjust_increment() const { return at<3>().as_int32(); }
+  bool has_flag() const { return at<4>().valid(); }
+  int32_t flag() const { return at<4>().as_int32(); }
+};
+
+class ReadyThreadEtwEvent : public ::protozero::Message {
+ public:
+  using Decoder = ReadyThreadEtwEvent_Decoder;
+  enum : int32_t {
+    kTThreadIdFieldNumber = 1,
+    kAdjustReasonFieldNumber = 2,
+    kAdjustIncrementFieldNumber = 3,
+    kFlagFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ReadyThreadEtwEvent"; }
+
+
+  using AdjustReason = ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason;
+  static inline const char* AdjustReason_Name(AdjustReason value) {
+    return ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason_Name(value);
+  }
+
+  using TraceFlag = ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag;
+  static inline const char* TraceFlag_Name(TraceFlag value) {
+    return ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag_Name(value);
+  }
+  static inline const AdjustReason IGNORE_THE_INCREMENT = AdjustReason::IGNORE_THE_INCREMENT;
+  static inline const AdjustReason APPLY_INCREMENT = AdjustReason::APPLY_INCREMENT;
+  static inline const AdjustReason APPLY_INCREMENT_BOOST = AdjustReason::APPLY_INCREMENT_BOOST;
+  static inline const TraceFlag TRACE_FLAG_UNSPECIFIED = TraceFlag::TRACE_FLAG_UNSPECIFIED;
+  static inline const TraceFlag THREAD_READIED = TraceFlag::THREAD_READIED;
+  static inline const TraceFlag KERNEL_STACK_SWAPPED_OUT = TraceFlag::KERNEL_STACK_SWAPPED_OUT;
+  static inline const TraceFlag PROCESS_ADDRESS_SWAPPED_OUT = TraceFlag::PROCESS_ADDRESS_SWAPPED_OUT;
+
+  using FieldMetadata_TThreadId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ReadyThreadEtwEvent>;
+
+  static constexpr FieldMetadata_TThreadId kTThreadId{};
+  void set_t_thread_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TThreadId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AdjustReason =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason,
+      ReadyThreadEtwEvent>;
+
+  static constexpr FieldMetadata_AdjustReason kAdjustReason{};
+  void set_adjust_reason(::perfetto::protos::pbzero::ReadyThreadEtwEvent_AdjustReason value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdjustReason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AdjustIncrement =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      ReadyThreadEtwEvent>;
+
+  static constexpr FieldMetadata_AdjustIncrement kAdjustIncrement{};
+  void set_adjust_increment(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdjustIncrement::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flag =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag,
+      ReadyThreadEtwEvent>;
+
+  static constexpr FieldMetadata_Flag kFlag{};
+  void set_flag(::perfetto::protos::pbzero::ReadyThreadEtwEvent_TraceFlag value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CSwitchEtwEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CSwitchEtwEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CSwitchEtwEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CSwitchEtwEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_new_thread_id() const { return at<1>().valid(); }
+  uint32_t new_thread_id() const { return at<1>().as_uint32(); }
+  bool has_old_thread_id() const { return at<2>().valid(); }
+  uint32_t old_thread_id() const { return at<2>().as_uint32(); }
+  bool has_new_thread_priority() const { return at<3>().valid(); }
+  int32_t new_thread_priority() const { return at<3>().as_int32(); }
+  bool has_old_thread_priority() const { return at<4>().valid(); }
+  int32_t old_thread_priority() const { return at<4>().as_int32(); }
+  bool has_previous_c_state() const { return at<5>().valid(); }
+  uint32_t previous_c_state() const { return at<5>().as_uint32(); }
+  bool has_old_thread_wait_reason() const { return at<6>().valid(); }
+  int32_t old_thread_wait_reason() const { return at<6>().as_int32(); }
+  bool has_old_thread_wait_mode() const { return at<7>().valid(); }
+  int32_t old_thread_wait_mode() const { return at<7>().as_int32(); }
+  bool has_old_thread_state() const { return at<8>().valid(); }
+  int32_t old_thread_state() const { return at<8>().as_int32(); }
+  bool has_old_thread_wait_ideal_processor() const { return at<9>().valid(); }
+  int32_t old_thread_wait_ideal_processor() const { return at<9>().as_int32(); }
+  bool has_new_thread_wait_time() const { return at<10>().valid(); }
+  uint32_t new_thread_wait_time() const { return at<10>().as_uint32(); }
+};
+
+class CSwitchEtwEvent : public ::protozero::Message {
+ public:
+  using Decoder = CSwitchEtwEvent_Decoder;
+  enum : int32_t {
+    kNewThreadIdFieldNumber = 1,
+    kOldThreadIdFieldNumber = 2,
+    kNewThreadPriorityFieldNumber = 3,
+    kOldThreadPriorityFieldNumber = 4,
+    kPreviousCStateFieldNumber = 5,
+    kOldThreadWaitReasonFieldNumber = 6,
+    kOldThreadWaitModeFieldNumber = 7,
+    kOldThreadStateFieldNumber = 8,
+    kOldThreadWaitIdealProcessorFieldNumber = 9,
+    kNewThreadWaitTimeFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CSwitchEtwEvent"; }
+
+
+  using OldThreadWaitReason = ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason;
+  static inline const char* OldThreadWaitReason_Name(OldThreadWaitReason value) {
+    return ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason_Name(value);
+  }
+
+  using OldThreadWaitMode = ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode;
+  static inline const char* OldThreadWaitMode_Name(OldThreadWaitMode value) {
+    return ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode_Name(value);
+  }
+
+  using OldThreadState = ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState;
+  static inline const char* OldThreadState_Name(OldThreadState value) {
+    return ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState_Name(value);
+  }
+  static inline const OldThreadWaitReason EXECUTIVE = OldThreadWaitReason::EXECUTIVE;
+  static inline const OldThreadWaitReason FREE_PAGE = OldThreadWaitReason::FREE_PAGE;
+  static inline const OldThreadWaitReason PAGE_IN = OldThreadWaitReason::PAGE_IN;
+  static inline const OldThreadWaitReason POOL_ALLOCATION = OldThreadWaitReason::POOL_ALLOCATION;
+  static inline const OldThreadWaitReason DELAY_EXECUTION = OldThreadWaitReason::DELAY_EXECUTION;
+  static inline const OldThreadWaitReason SUSPEND = OldThreadWaitReason::SUSPEND;
+  static inline const OldThreadWaitReason USER_REQUEST = OldThreadWaitReason::USER_REQUEST;
+  static inline const OldThreadWaitReason WR_EXECUTIVE = OldThreadWaitReason::WR_EXECUTIVE;
+  static inline const OldThreadWaitReason WR_FREE_PAGE = OldThreadWaitReason::WR_FREE_PAGE;
+  static inline const OldThreadWaitReason WR_PAGE_IN = OldThreadWaitReason::WR_PAGE_IN;
+  static inline const OldThreadWaitReason WR_POOL_ALLOCATION = OldThreadWaitReason::WR_POOL_ALLOCATION;
+  static inline const OldThreadWaitReason WR_DELAY_EXECUTION = OldThreadWaitReason::WR_DELAY_EXECUTION;
+  static inline const OldThreadWaitReason WR_SUSPENDED = OldThreadWaitReason::WR_SUSPENDED;
+  static inline const OldThreadWaitReason WR_USER_REQUEST = OldThreadWaitReason::WR_USER_REQUEST;
+  static inline const OldThreadWaitReason WR_EVENT_PAIR = OldThreadWaitReason::WR_EVENT_PAIR;
+  static inline const OldThreadWaitReason WR_QUEUE = OldThreadWaitReason::WR_QUEUE;
+  static inline const OldThreadWaitReason WR_LPC_RECEIVER = OldThreadWaitReason::WR_LPC_RECEIVER;
+  static inline const OldThreadWaitReason WR_LPC_REPLY = OldThreadWaitReason::WR_LPC_REPLY;
+  static inline const OldThreadWaitReason WR_VIRTUAL_MEMORY = OldThreadWaitReason::WR_VIRTUAL_MEMORY;
+  static inline const OldThreadWaitReason WR_PAGE_OUT = OldThreadWaitReason::WR_PAGE_OUT;
+  static inline const OldThreadWaitReason WR_RENDEZ_VOUS = OldThreadWaitReason::WR_RENDEZ_VOUS;
+  static inline const OldThreadWaitReason WR_KEYED_EVENT = OldThreadWaitReason::WR_KEYED_EVENT;
+  static inline const OldThreadWaitReason WR_TERMINATED = OldThreadWaitReason::WR_TERMINATED;
+  static inline const OldThreadWaitReason WR_PROCESS_IN_SWAP = OldThreadWaitReason::WR_PROCESS_IN_SWAP;
+  static inline const OldThreadWaitReason WR_CPU_RATE_CONTROL = OldThreadWaitReason::WR_CPU_RATE_CONTROL;
+  static inline const OldThreadWaitReason WR_CALLOUT_STACK = OldThreadWaitReason::WR_CALLOUT_STACK;
+  static inline const OldThreadWaitReason WR_KERNEL = OldThreadWaitReason::WR_KERNEL;
+  static inline const OldThreadWaitReason WR_RESOURCE = OldThreadWaitReason::WR_RESOURCE;
+  static inline const OldThreadWaitReason WR_PUSH_LOCK = OldThreadWaitReason::WR_PUSH_LOCK;
+  static inline const OldThreadWaitReason WR_MUTEX = OldThreadWaitReason::WR_MUTEX;
+  static inline const OldThreadWaitReason WR_QUANTUM_END = OldThreadWaitReason::WR_QUANTUM_END;
+  static inline const OldThreadWaitReason WR_DISPATCH_INT = OldThreadWaitReason::WR_DISPATCH_INT;
+  static inline const OldThreadWaitReason WR_PREEMPTED = OldThreadWaitReason::WR_PREEMPTED;
+  static inline const OldThreadWaitReason WR_YIELD_EXECUTION = OldThreadWaitReason::WR_YIELD_EXECUTION;
+  static inline const OldThreadWaitReason WR_FAST_MUTEX = OldThreadWaitReason::WR_FAST_MUTEX;
+  static inline const OldThreadWaitReason WR_GUARD_MUTEX = OldThreadWaitReason::WR_GUARD_MUTEX;
+  static inline const OldThreadWaitReason WR_RUNDOWN = OldThreadWaitReason::WR_RUNDOWN;
+  static inline const OldThreadWaitReason MAXIMUM_WAIT_REASON = OldThreadWaitReason::MAXIMUM_WAIT_REASON;
+  static inline const OldThreadWaitMode KERNEL_MODE = OldThreadWaitMode::KERNEL_MODE;
+  static inline const OldThreadWaitMode USER_MODE = OldThreadWaitMode::USER_MODE;
+  static inline const OldThreadState INITIALIZED = OldThreadState::INITIALIZED;
+  static inline const OldThreadState READY = OldThreadState::READY;
+  static inline const OldThreadState RUNNING = OldThreadState::RUNNING;
+  static inline const OldThreadState STANDBY = OldThreadState::STANDBY;
+  static inline const OldThreadState TERMINATED = OldThreadState::TERMINATED;
+  static inline const OldThreadState WAITING = OldThreadState::WAITING;
+  static inline const OldThreadState TRANSITION = OldThreadState::TRANSITION;
+  static inline const OldThreadState DEFERRED_READY = OldThreadState::DEFERRED_READY;
+
+  using FieldMetadata_NewThreadId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_NewThreadId kNewThreadId{};
+  void set_new_thread_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewThreadId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldThreadId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadId kOldThreadId{};
+  void set_old_thread_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NewThreadPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_NewThreadPriority kNewThreadPriority{};
+  void set_new_thread_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewThreadPriority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldThreadPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadPriority kOldThreadPriority{};
+  void set_old_thread_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadPriority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PreviousCState =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_PreviousCState kPreviousCState{};
+  void set_previous_c_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreviousCState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldThreadWaitReason =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadWaitReason kOldThreadWaitReason{};
+  void set_old_thread_wait_reason(::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitReason value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadWaitReason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldThreadWaitMode =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadWaitMode kOldThreadWaitMode{};
+  void set_old_thread_wait_mode(::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadWaitMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadWaitMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldThreadState =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadState kOldThreadState{};
+  void set_old_thread_state(::perfetto::protos::pbzero::CSwitchEtwEvent_OldThreadState value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldThreadWaitIdealProcessor =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kSint32,
+      int32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_OldThreadWaitIdealProcessor kOldThreadWaitIdealProcessor{};
+  void set_old_thread_wait_ideal_processor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldThreadWaitIdealProcessor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kSint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NewThreadWaitTime =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CSwitchEtwEvent>;
+
+  static constexpr FieldMetadata_NewThreadWaitTime kNewThreadWaitTime{};
+  void set_new_thread_wait_time(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewThreadWaitTime::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/etw/etw_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class CSwitchEtwEvent;
+class ReadyThreadEtwEvent;
+
+class EtwTraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EtwTraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EtwTraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EtwTraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timestamp() const { return at<1>().valid(); }
+  uint64_t timestamp() const { return at<1>().as_uint64(); }
+  bool has_cpu() const { return at<4>().valid(); }
+  uint32_t cpu() const { return at<4>().as_uint32(); }
+  bool has_c_switch() const { return at<2>().valid(); }
+  ::protozero::ConstBytes c_switch() const { return at<2>().as_bytes(); }
+  bool has_ready_thread() const { return at<3>().valid(); }
+  ::protozero::ConstBytes ready_thread() const { return at<3>().as_bytes(); }
+};
+
+class EtwTraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = EtwTraceEvent_Decoder;
+  enum : int32_t {
+    kTimestampFieldNumber = 1,
+    kCpuFieldNumber = 4,
+    kCSwitchFieldNumber = 2,
+    kReadyThreadFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EtwTraceEvent"; }
+
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EtwTraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      EtwTraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CSwitch =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CSwitchEtwEvent,
+      EtwTraceEvent>;
+
+  static constexpr FieldMetadata_CSwitch kCSwitch{};
+  template <typename T = CSwitchEtwEvent> T* set_c_switch() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ReadyThread =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ReadyThreadEtwEvent,
+      EtwTraceEvent>;
+
+  static constexpr FieldMetadata_ReadyThread kReadyThread{};
+  template <typename T = ReadyThreadEtwEvent> T* set_ready_thread() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/etw/etw_event_bundle.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_EVENT_BUNDLE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_ETW_ETW_EVENT_BUNDLE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class EtwTraceEvent;
+
+class EtwTraceEventBundle_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  EtwTraceEventBundle_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EtwTraceEventBundle_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EtwTraceEventBundle_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_event() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> event() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class EtwTraceEventBundle : public ::protozero::Message {
+ public:
+  using Decoder = EtwTraceEventBundle_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kEventFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EtwTraceEventBundle"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      EtwTraceEventBundle>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Event =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EtwTraceEvent,
+      EtwTraceEventBundle>;
+
+  static constexpr FieldMetadata_Event kEvent{};
+  template <typename T = EtwTraceEvent> T* add_event() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/filesystem/inode_file_map.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FILESYSTEM_INODE_FILE_MAP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FILESYSTEM_INODE_FILE_MAP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class InodeFileMap_Entry;
+namespace perfetto_pbzero_enum_InodeFileMap_Entry {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_InodeFileMap_Entry
+using InodeFileMap_Entry_Type = perfetto_pbzero_enum_InodeFileMap_Entry::Type;
+
+namespace perfetto_pbzero_enum_InodeFileMap_Entry {
+enum Type : int32_t {
+  UNKNOWN = 0,
+  FILE = 1,
+  DIRECTORY = 2,
+};
+} // namespace perfetto_pbzero_enum_InodeFileMap_Entry
+using InodeFileMap_Entry_Type = perfetto_pbzero_enum_InodeFileMap_Entry::Type;
+
+
+constexpr InodeFileMap_Entry_Type InodeFileMap_Entry_Type_MIN = InodeFileMap_Entry_Type::UNKNOWN;
+constexpr InodeFileMap_Entry_Type InodeFileMap_Entry_Type_MAX = InodeFileMap_Entry_Type::DIRECTORY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* InodeFileMap_Entry_Type_Name(::perfetto::protos::pbzero::InodeFileMap_Entry_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::InodeFileMap_Entry_Type::UNKNOWN:
+    return "UNKNOWN";
+
+  case ::perfetto::protos::pbzero::InodeFileMap_Entry_Type::FILE:
+    return "FILE";
+
+  case ::perfetto::protos::pbzero::InodeFileMap_Entry_Type::DIRECTORY:
+    return "DIRECTORY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class InodeFileMap_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  InodeFileMap_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InodeFileMap_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InodeFileMap_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_block_device_id() const { return at<1>().valid(); }
+  uint64_t block_device_id() const { return at<1>().as_uint64(); }
+  bool has_mount_points() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> mount_points() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_entries() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> entries() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class InodeFileMap : public ::protozero::Message {
+ public:
+  using Decoder = InodeFileMap_Decoder;
+  enum : int32_t {
+    kBlockDeviceIdFieldNumber = 1,
+    kMountPointsFieldNumber = 2,
+    kEntriesFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InodeFileMap"; }
+
+  using Entry = ::perfetto::protos::pbzero::InodeFileMap_Entry;
+
+  using FieldMetadata_BlockDeviceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InodeFileMap>;
+
+  static constexpr FieldMetadata_BlockDeviceId kBlockDeviceId{};
+  void set_block_device_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockDeviceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MountPoints =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileMap>;
+
+  static constexpr FieldMetadata_MountPoints kMountPoints{};
+  void add_mount_points(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_MountPoints::kFieldId, data, size);
+  }
+  void add_mount_points(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_MountPoints::kFieldId, chars.data, chars.size);
+  }
+  void add_mount_points(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_MountPoints::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Entries =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InodeFileMap_Entry,
+      InodeFileMap>;
+
+  static constexpr FieldMetadata_Entries kEntries{};
+  template <typename T = InodeFileMap_Entry> T* add_entries() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class InodeFileMap_Entry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  InodeFileMap_Entry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InodeFileMap_Entry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InodeFileMap_Entry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_inode_number() const { return at<1>().valid(); }
+  uint64_t inode_number() const { return at<1>().as_uint64(); }
+  bool has_paths() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> paths() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_type() const { return at<3>().valid(); }
+  int32_t type() const { return at<3>().as_int32(); }
+};
+
+class InodeFileMap_Entry : public ::protozero::Message {
+ public:
+  using Decoder = InodeFileMap_Entry_Decoder;
+  enum : int32_t {
+    kInodeNumberFieldNumber = 1,
+    kPathsFieldNumber = 2,
+    kTypeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InodeFileMap.Entry"; }
+
+
+  using Type = ::perfetto::protos::pbzero::InodeFileMap_Entry_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::InodeFileMap_Entry_Type_Name(value);
+  }
+  static inline const Type UNKNOWN = Type::UNKNOWN;
+  static inline const Type FILE = Type::FILE;
+  static inline const Type DIRECTORY = Type::DIRECTORY;
+
+  using FieldMetadata_InodeNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InodeFileMap_Entry>;
+
+  static constexpr FieldMetadata_InodeNumber kInodeNumber{};
+  void set_inode_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InodeNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Paths =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InodeFileMap_Entry>;
+
+  static constexpr FieldMetadata_Paths kPaths{};
+  void add_paths(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Paths::kFieldId, data, size);
+  }
+  void add_paths(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Paths::kFieldId, chars.data, chars.size);
+  }
+  void add_paths(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Paths::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::InodeFileMap_Entry_Type,
+      InodeFileMap_Entry>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(::perfetto::protos::pbzero::InodeFileMap_Entry_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ftrace_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AllocPagesIommuEndFtraceEvent;
+class AllocPagesIommuFailFtraceEvent;
+class AllocPagesIommuStartFtraceEvent;
+class AllocPagesSysEndFtraceEvent;
+class AllocPagesSysFailFtraceEvent;
+class AllocPagesSysStartFtraceEvent;
+class AndroidFsDatareadEndFtraceEvent;
+class AndroidFsDatareadStartFtraceEvent;
+class AndroidFsDatawriteEndFtraceEvent;
+class AndroidFsDatawriteStartFtraceEvent;
+class AndroidFsFsyncEndFtraceEvent;
+class AndroidFsFsyncStartFtraceEvent;
+class BinderCommandFtraceEvent;
+class BinderLockFtraceEvent;
+class BinderLockedFtraceEvent;
+class BinderReturnFtraceEvent;
+class BinderSetPriorityFtraceEvent;
+class BinderTransactionAllocBufFtraceEvent;
+class BinderTransactionFtraceEvent;
+class BinderTransactionReceivedFtraceEvent;
+class BinderUnlockFtraceEvent;
+class BlockBioBackmergeFtraceEvent;
+class BlockBioBounceFtraceEvent;
+class BlockBioCompleteFtraceEvent;
+class BlockBioFrontmergeFtraceEvent;
+class BlockBioQueueFtraceEvent;
+class BlockBioRemapFtraceEvent;
+class BlockDirtyBufferFtraceEvent;
+class BlockGetrqFtraceEvent;
+class BlockPlugFtraceEvent;
+class BlockRqAbortFtraceEvent;
+class BlockRqCompleteFtraceEvent;
+class BlockRqInsertFtraceEvent;
+class BlockRqIssueFtraceEvent;
+class BlockRqRemapFtraceEvent;
+class BlockRqRequeueFtraceEvent;
+class BlockSleeprqFtraceEvent;
+class BlockSplitFtraceEvent;
+class BlockTouchBufferFtraceEvent;
+class BlockUnplugFtraceEvent;
+class CdevUpdateFtraceEvent;
+class CgroupAttachTaskFtraceEvent;
+class CgroupDestroyRootFtraceEvent;
+class CgroupMkdirFtraceEvent;
+class CgroupReleaseFtraceEvent;
+class CgroupRemountFtraceEvent;
+class CgroupRenameFtraceEvent;
+class CgroupRmdirFtraceEvent;
+class CgroupSetupRootFtraceEvent;
+class CgroupTransferTasksFtraceEvent;
+class ClkDisableFtraceEvent;
+class ClkEnableFtraceEvent;
+class ClkSetRateFtraceEvent;
+class ClockDisableFtraceEvent;
+class ClockEnableFtraceEvent;
+class ClockSetRateFtraceEvent;
+class CmaAllocInfoFtraceEvent;
+class CmaAllocStartFtraceEvent;
+class ConsoleFtraceEvent;
+class CpuFrequencyFtraceEvent;
+class CpuFrequencyLimitsFtraceEvent;
+class CpuIdleFtraceEvent;
+class CpuhpEnterFtraceEvent;
+class CpuhpExitFtraceEvent;
+class CpuhpLatencyFtraceEvent;
+class CpuhpMultiEnterFtraceEvent;
+class CpuhpPauseFtraceEvent;
+class CrosEcSensorhubDataFtraceEvent;
+class DmaAllocContiguousRetryFtraceEvent;
+class DmaFenceEmitFtraceEvent;
+class DmaFenceInitFtraceEvent;
+class DmaFenceSignaledFtraceEvent;
+class DmaFenceWaitEndFtraceEvent;
+class DmaFenceWaitStartFtraceEvent;
+class DmaHeapStatFtraceEvent;
+class DpuTracingMarkWriteFtraceEvent;
+class DrmRunJobFtraceEvent;
+class DrmSchedJobFtraceEvent;
+class DrmSchedProcessJobFtraceEvent;
+class DrmVblankEventDeliveredFtraceEvent;
+class DrmVblankEventFtraceEvent;
+class DsiCmdFifoStatusFtraceEvent;
+class DsiRxFtraceEvent;
+class DsiTxFtraceEvent;
+class Ext4AllocDaBlocksFtraceEvent;
+class Ext4AllocateBlocksFtraceEvent;
+class Ext4AllocateInodeFtraceEvent;
+class Ext4BeginOrderedTruncateFtraceEvent;
+class Ext4CollapseRangeFtraceEvent;
+class Ext4DaReleaseSpaceFtraceEvent;
+class Ext4DaReserveSpaceFtraceEvent;
+class Ext4DaUpdateReserveSpaceFtraceEvent;
+class Ext4DaWriteBeginFtraceEvent;
+class Ext4DaWriteEndFtraceEvent;
+class Ext4DaWritePagesExtentFtraceEvent;
+class Ext4DaWritePagesFtraceEvent;
+class Ext4DirectIOEnterFtraceEvent;
+class Ext4DirectIOExitFtraceEvent;
+class Ext4DiscardBlocksFtraceEvent;
+class Ext4DiscardPreallocationsFtraceEvent;
+class Ext4DropInodeFtraceEvent;
+class Ext4EsCacheExtentFtraceEvent;
+class Ext4EsFindDelayedExtentRangeEnterFtraceEvent;
+class Ext4EsFindDelayedExtentRangeExitFtraceEvent;
+class Ext4EsInsertExtentFtraceEvent;
+class Ext4EsLookupExtentEnterFtraceEvent;
+class Ext4EsLookupExtentExitFtraceEvent;
+class Ext4EsRemoveExtentFtraceEvent;
+class Ext4EsShrinkCountFtraceEvent;
+class Ext4EsShrinkFtraceEvent;
+class Ext4EsShrinkScanEnterFtraceEvent;
+class Ext4EsShrinkScanExitFtraceEvent;
+class Ext4EvictInodeFtraceEvent;
+class Ext4ExtConvertToInitializedEnterFtraceEvent;
+class Ext4ExtConvertToInitializedFastpathFtraceEvent;
+class Ext4ExtHandleUnwrittenExtentsFtraceEvent;
+class Ext4ExtInCacheFtraceEvent;
+class Ext4ExtLoadExtentFtraceEvent;
+class Ext4ExtMapBlocksEnterFtraceEvent;
+class Ext4ExtMapBlocksExitFtraceEvent;
+class Ext4ExtPutInCacheFtraceEvent;
+class Ext4ExtRemoveSpaceDoneFtraceEvent;
+class Ext4ExtRemoveSpaceFtraceEvent;
+class Ext4ExtRmIdxFtraceEvent;
+class Ext4ExtRmLeafFtraceEvent;
+class Ext4ExtShowExtentFtraceEvent;
+class Ext4FallocateEnterFtraceEvent;
+class Ext4FallocateExitFtraceEvent;
+class Ext4FindDelallocRangeFtraceEvent;
+class Ext4ForgetFtraceEvent;
+class Ext4FreeBlocksFtraceEvent;
+class Ext4FreeInodeFtraceEvent;
+class Ext4GetImpliedClusterAllocExitFtraceEvent;
+class Ext4GetReservedClusterAllocFtraceEvent;
+class Ext4IndMapBlocksEnterFtraceEvent;
+class Ext4IndMapBlocksExitFtraceEvent;
+class Ext4InsertRangeFtraceEvent;
+class Ext4InvalidatepageFtraceEvent;
+class Ext4JournalStartFtraceEvent;
+class Ext4JournalStartReservedFtraceEvent;
+class Ext4JournalledInvalidatepageFtraceEvent;
+class Ext4JournalledWriteEndFtraceEvent;
+class Ext4LoadInodeBitmapFtraceEvent;
+class Ext4LoadInodeFtraceEvent;
+class Ext4MarkInodeDirtyFtraceEvent;
+class Ext4MbBitmapLoadFtraceEvent;
+class Ext4MbBuddyBitmapLoadFtraceEvent;
+class Ext4MbDiscardPreallocationsFtraceEvent;
+class Ext4MbNewGroupPaFtraceEvent;
+class Ext4MbNewInodePaFtraceEvent;
+class Ext4MbReleaseGroupPaFtraceEvent;
+class Ext4MbReleaseInodePaFtraceEvent;
+class Ext4MballocAllocFtraceEvent;
+class Ext4MballocDiscardFtraceEvent;
+class Ext4MballocFreeFtraceEvent;
+class Ext4MballocPreallocFtraceEvent;
+class Ext4OtherInodeUpdateTimeFtraceEvent;
+class Ext4PunchHoleFtraceEvent;
+class Ext4ReadBlockBitmapLoadFtraceEvent;
+class Ext4ReadpageFtraceEvent;
+class Ext4ReleasepageFtraceEvent;
+class Ext4RemoveBlocksFtraceEvent;
+class Ext4RequestBlocksFtraceEvent;
+class Ext4RequestInodeFtraceEvent;
+class Ext4SyncFileEnterFtraceEvent;
+class Ext4SyncFileExitFtraceEvent;
+class Ext4SyncFsFtraceEvent;
+class Ext4TrimAllFreeFtraceEvent;
+class Ext4TrimExtentFtraceEvent;
+class Ext4TruncateEnterFtraceEvent;
+class Ext4TruncateExitFtraceEvent;
+class Ext4UnlinkEnterFtraceEvent;
+class Ext4UnlinkExitFtraceEvent;
+class Ext4WriteBeginFtraceEvent;
+class Ext4WriteEndFtraceEvent;
+class Ext4WritepageFtraceEvent;
+class Ext4WritepagesFtraceEvent;
+class Ext4WritepagesResultFtraceEvent;
+class Ext4ZeroRangeFtraceEvent;
+class F2fsDoSubmitBioFtraceEvent;
+class F2fsEvictInodeFtraceEvent;
+class F2fsFallocateFtraceEvent;
+class F2fsGetDataBlockFtraceEvent;
+class F2fsGetVictimFtraceEvent;
+class F2fsIgetExitFtraceEvent;
+class F2fsIgetFtraceEvent;
+class F2fsIostatFtraceEvent;
+class F2fsIostatLatencyFtraceEvent;
+class F2fsNewInodeFtraceEvent;
+class F2fsReadpageFtraceEvent;
+class F2fsReserveNewBlockFtraceEvent;
+class F2fsSetPageDirtyFtraceEvent;
+class F2fsSubmitWritePageFtraceEvent;
+class F2fsSyncFileEnterFtraceEvent;
+class F2fsSyncFileExitFtraceEvent;
+class F2fsSyncFsFtraceEvent;
+class F2fsTruncateBlocksEnterFtraceEvent;
+class F2fsTruncateBlocksExitFtraceEvent;
+class F2fsTruncateDataBlocksRangeFtraceEvent;
+class F2fsTruncateFtraceEvent;
+class F2fsTruncateInodeBlocksEnterFtraceEvent;
+class F2fsTruncateInodeBlocksExitFtraceEvent;
+class F2fsTruncateNodeFtraceEvent;
+class F2fsTruncateNodesEnterFtraceEvent;
+class F2fsTruncateNodesExitFtraceEvent;
+class F2fsTruncatePartialNodesFtraceEvent;
+class F2fsUnlinkEnterFtraceEvent;
+class F2fsUnlinkExitFtraceEvent;
+class F2fsVmPageMkwriteFtraceEvent;
+class F2fsWriteBeginFtraceEvent;
+class F2fsWriteCheckpointFtraceEvent;
+class F2fsWriteEndFtraceEvent;
+class FastrpcDmaStatFtraceEvent;
+class FenceDestroyFtraceEvent;
+class FenceEnableSignalFtraceEvent;
+class FenceInitFtraceEvent;
+class FenceSignaledFtraceEvent;
+class FuncgraphEntryFtraceEvent;
+class FuncgraphExitFtraceEvent;
+class G2dTracingMarkWriteFtraceEvent;
+class GenericFtraceEvent;
+class GpuFrequencyFtraceEvent;
+class GpuMemTotalFtraceEvent;
+class GpuWorkPeriodFtraceEvent;
+class HostHcallFtraceEvent;
+class HostMemAbortFtraceEvent;
+class HostSmcFtraceEvent;
+class HypEnterFtraceEvent;
+class HypExitFtraceEvent;
+class I2cReadFtraceEvent;
+class I2cReplyFtraceEvent;
+class I2cResultFtraceEvent;
+class I2cWriteFtraceEvent;
+class InetSockSetStateFtraceEvent;
+class IommuMapRangeFtraceEvent;
+class IommuSecPtblMapRangeEndFtraceEvent;
+class IommuSecPtblMapRangeStartFtraceEvent;
+class IonAllocBufferEndFtraceEvent;
+class IonAllocBufferFailFtraceEvent;
+class IonAllocBufferFallbackFtraceEvent;
+class IonAllocBufferStartFtraceEvent;
+class IonBufferCreateFtraceEvent;
+class IonBufferDestroyFtraceEvent;
+class IonCpAllocRetryFtraceEvent;
+class IonCpSecureBufferEndFtraceEvent;
+class IonCpSecureBufferStartFtraceEvent;
+class IonHeapGrowFtraceEvent;
+class IonHeapShrinkFtraceEvent;
+class IonPrefetchingFtraceEvent;
+class IonSecureCmaAddToPoolEndFtraceEvent;
+class IonSecureCmaAddToPoolStartFtraceEvent;
+class IonSecureCmaAllocateEndFtraceEvent;
+class IonSecureCmaAllocateStartFtraceEvent;
+class IonSecureCmaShrinkPoolEndFtraceEvent;
+class IonSecureCmaShrinkPoolStartFtraceEvent;
+class IonStatFtraceEvent;
+class IpiEntryFtraceEvent;
+class IpiExitFtraceEvent;
+class IpiRaiseFtraceEvent;
+class IrqHandlerEntryFtraceEvent;
+class IrqHandlerExitFtraceEvent;
+class KfreeFtraceEvent;
+class KfreeSkbFtraceEvent;
+class KmallocFtraceEvent;
+class KmallocNodeFtraceEvent;
+class KmemCacheAllocFtraceEvent;
+class KmemCacheAllocNodeFtraceEvent;
+class KmemCacheFreeFtraceEvent;
+class KvmAccessFaultFtraceEvent;
+class KvmAckIrqFtraceEvent;
+class KvmAgeHvaFtraceEvent;
+class KvmAgePageFtraceEvent;
+class KvmArmClearDebugFtraceEvent;
+class KvmArmSetDreg32FtraceEvent;
+class KvmArmSetRegsetFtraceEvent;
+class KvmArmSetupDebugFtraceEvent;
+class KvmEntryFtraceEvent;
+class KvmExitFtraceEvent;
+class KvmFpuFtraceEvent;
+class KvmGetTimerMapFtraceEvent;
+class KvmGuestFaultFtraceEvent;
+class KvmHandleSysRegFtraceEvent;
+class KvmHvcArm64FtraceEvent;
+class KvmIrqLineFtraceEvent;
+class KvmMmioEmulateFtraceEvent;
+class KvmMmioFtraceEvent;
+class KvmSetGuestDebugFtraceEvent;
+class KvmSetIrqFtraceEvent;
+class KvmSetSpteHvaFtraceEvent;
+class KvmSetWayFlushFtraceEvent;
+class KvmSysAccessFtraceEvent;
+class KvmTestAgeHvaFtraceEvent;
+class KvmTimerEmulateFtraceEvent;
+class KvmTimerHrtimerExpireFtraceEvent;
+class KvmTimerRestoreStateFtraceEvent;
+class KvmTimerSaveStateFtraceEvent;
+class KvmTimerUpdateIrqFtraceEvent;
+class KvmToggleCacheFtraceEvent;
+class KvmUnmapHvaRangeFtraceEvent;
+class KvmUserspaceExitFtraceEvent;
+class KvmVcpuWakeupFtraceEvent;
+class KvmWfxArm64FtraceEvent;
+class LowmemoryKillFtraceEvent;
+class LwisTracingMarkWriteFtraceEvent;
+class MaliMaliCSFINTERRUPTENDFtraceEvent;
+class MaliMaliCSFINTERRUPTSTARTFtraceEvent;
+class MaliMaliKCPUCQSSETFtraceEvent;
+class MaliMaliKCPUCQSWAITENDFtraceEvent;
+class MaliMaliKCPUCQSWAITSTARTFtraceEvent;
+class MaliMaliKCPUFENCESIGNALFtraceEvent;
+class MaliMaliKCPUFENCEWAITENDFtraceEvent;
+class MaliMaliKCPUFENCEWAITSTARTFtraceEvent;
+class MaliTracingMarkWriteFtraceEvent;
+class MarkVictimFtraceEvent;
+class MdpCmdKickoffFtraceEvent;
+class MdpCmdPingpongDoneFtraceEvent;
+class MdpCmdReadptrDoneFtraceEvent;
+class MdpCmdReleaseBwFtraceEvent;
+class MdpCmdWaitPingpongFtraceEvent;
+class MdpCommitFtraceEvent;
+class MdpCompareBwFtraceEvent;
+class MdpMisrCrcFtraceEvent;
+class MdpMixerUpdateFtraceEvent;
+class MdpPerfPrefillCalcFtraceEvent;
+class MdpPerfSetOtFtraceEvent;
+class MdpPerfSetPanicLutsFtraceEvent;
+class MdpPerfSetQosLutsFtraceEvent;
+class MdpPerfSetWmLevelsFtraceEvent;
+class MdpPerfUpdateBusFtraceEvent;
+class MdpSsppChangeFtraceEvent;
+class MdpSsppSetFtraceEvent;
+class MdpTraceCounterFtraceEvent;
+class MdpVideoUnderrunDoneFtraceEvent;
+class MigratePagesEndFtraceEvent;
+class MigratePagesStartFtraceEvent;
+class MigrateRetryFtraceEvent;
+class MmCompactionBeginFtraceEvent;
+class MmCompactionDeferCompactionFtraceEvent;
+class MmCompactionDeferResetFtraceEvent;
+class MmCompactionDeferredFtraceEvent;
+class MmCompactionEndFtraceEvent;
+class MmCompactionFinishedFtraceEvent;
+class MmCompactionIsolateFreepagesFtraceEvent;
+class MmCompactionIsolateMigratepagesFtraceEvent;
+class MmCompactionKcompactdSleepFtraceEvent;
+class MmCompactionKcompactdWakeFtraceEvent;
+class MmCompactionMigratepagesFtraceEvent;
+class MmCompactionSuitableFtraceEvent;
+class MmCompactionTryToCompactPagesFtraceEvent;
+class MmCompactionWakeupKcompactdFtraceEvent;
+class MmEventRecordFtraceEvent;
+class MmFilemapAddToPageCacheFtraceEvent;
+class MmFilemapDeleteFromPageCacheFtraceEvent;
+class MmPageAllocExtfragFtraceEvent;
+class MmPageAllocFtraceEvent;
+class MmPageAllocZoneLockedFtraceEvent;
+class MmPageFreeBatchedFtraceEvent;
+class MmPageFreeFtraceEvent;
+class MmPagePcpuDrainFtraceEvent;
+class MmShrinkSlabEndFtraceEvent;
+class MmShrinkSlabStartFtraceEvent;
+class MmVmscanDirectReclaimBeginFtraceEvent;
+class MmVmscanDirectReclaimEndFtraceEvent;
+class MmVmscanKswapdSleepFtraceEvent;
+class MmVmscanKswapdWakeFtraceEvent;
+class NapiGroReceiveEntryFtraceEvent;
+class NapiGroReceiveExitFtraceEvent;
+class NetDevXmitFtraceEvent;
+class NetifReceiveSkbFtraceEvent;
+class OomScoreAdjUpdateFtraceEvent;
+class PrintFtraceEvent;
+class RegulatorDisableCompleteFtraceEvent;
+class RegulatorDisableFtraceEvent;
+class RegulatorEnableCompleteFtraceEvent;
+class RegulatorEnableDelayFtraceEvent;
+class RegulatorEnableFtraceEvent;
+class RegulatorSetVoltageCompleteFtraceEvent;
+class RegulatorSetVoltageFtraceEvent;
+class RotatorBwAoAsContextFtraceEvent;
+class RssStatFtraceEvent;
+class RssStatThrottledFtraceEvent;
+class SamsungTracingMarkWriteFtraceEvent;
+class SchedBlockedReasonFtraceEvent;
+class SchedCpuHotplugFtraceEvent;
+class SchedCpuUtilCfsFtraceEvent;
+class SchedPiSetprioFtraceEvent;
+class SchedProcessExecFtraceEvent;
+class SchedProcessExitFtraceEvent;
+class SchedProcessForkFtraceEvent;
+class SchedProcessFreeFtraceEvent;
+class SchedProcessHangFtraceEvent;
+class SchedProcessWaitFtraceEvent;
+class SchedSwitchFtraceEvent;
+class SchedSwitchWithCtrsFtraceEvent;
+class SchedWakeupFtraceEvent;
+class SchedWakeupNewFtraceEvent;
+class SchedWakingFtraceEvent;
+class ScmCallEndFtraceEvent;
+class ScmCallStartFtraceEvent;
+class SdeSdeEvtlogFtraceEvent;
+class SdeSdePerfCalcCrtcFtraceEvent;
+class SdeSdePerfCrtcUpdateFtraceEvent;
+class SdeSdePerfSetQosLutsFtraceEvent;
+class SdeSdePerfUpdateBusFtraceEvent;
+class SdeTracingMarkWriteFtraceEvent;
+class SignalDeliverFtraceEvent;
+class SignalGenerateFtraceEvent;
+class SmbusReadFtraceEvent;
+class SmbusReplyFtraceEvent;
+class SmbusResultFtraceEvent;
+class SmbusWriteFtraceEvent;
+class SoftirqEntryFtraceEvent;
+class SoftirqExitFtraceEvent;
+class SoftirqRaiseFtraceEvent;
+class SuspendResumeFtraceEvent;
+class SuspendResumeMinimalFtraceEvent;
+class SyncPtFtraceEvent;
+class SyncTimelineFtraceEvent;
+class SyncWaitFtraceEvent;
+class SysEnterFtraceEvent;
+class SysExitFtraceEvent;
+class TaskNewtaskFtraceEvent;
+class TaskRenameFtraceEvent;
+class TcpRetransmitSkbFtraceEvent;
+class ThermalTemperatureFtraceEvent;
+class TracingMarkWriteFtraceEvent;
+class TrapRegFtraceEvent;
+class TrustyEnqueueNopFtraceEvent;
+class TrustyIpcConnectEndFtraceEvent;
+class TrustyIpcConnectFtraceEvent;
+class TrustyIpcHandleEventFtraceEvent;
+class TrustyIpcPollFtraceEvent;
+class TrustyIpcReadEndFtraceEvent;
+class TrustyIpcReadFtraceEvent;
+class TrustyIpcRxFtraceEvent;
+class TrustyIpcWriteFtraceEvent;
+class TrustyIrqFtraceEvent;
+class TrustyReclaimMemoryDoneFtraceEvent;
+class TrustyReclaimMemoryFtraceEvent;
+class TrustyShareMemoryDoneFtraceEvent;
+class TrustyShareMemoryFtraceEvent;
+class TrustySmcDoneFtraceEvent;
+class TrustySmcFtraceEvent;
+class TrustyStdCall32DoneFtraceEvent;
+class TrustyStdCall32FtraceEvent;
+class UfshcdClkGatingFtraceEvent;
+class UfshcdCommandFtraceEvent;
+class V4l2DqbufFtraceEvent;
+class V4l2QbufFtraceEvent;
+class Vb2V4l2BufDoneFtraceEvent;
+class Vb2V4l2BufQueueFtraceEvent;
+class Vb2V4l2DqbufFtraceEvent;
+class Vb2V4l2QbufFtraceEvent;
+class VgicUpdateIrqPendingFtraceEvent;
+class VirtioGpuCmdQueueFtraceEvent;
+class VirtioGpuCmdResponseFtraceEvent;
+class VirtioVideoCmdDoneFtraceEvent;
+class VirtioVideoCmdFtraceEvent;
+class VirtioVideoResourceQueueDoneFtraceEvent;
+class VirtioVideoResourceQueueFtraceEvent;
+class WakeupSourceActivateFtraceEvent;
+class WakeupSourceDeactivateFtraceEvent;
+class WorkqueueActivateWorkFtraceEvent;
+class WorkqueueExecuteEndFtraceEvent;
+class WorkqueueExecuteStartFtraceEvent;
+class WorkqueueQueueWorkFtraceEvent;
+class ZeroFtraceEvent;
+
+class FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/488, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timestamp() const { return at<1>().valid(); }
+  uint64_t timestamp() const { return at<1>().as_uint64(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_common_flags() const { return at<5>().valid(); }
+  uint32_t common_flags() const { return at<5>().as_uint32(); }
+  bool has_print() const { return at<3>().valid(); }
+  ::protozero::ConstBytes print() const { return at<3>().as_bytes(); }
+  bool has_sched_switch() const { return at<4>().valid(); }
+  ::protozero::ConstBytes sched_switch() const { return at<4>().as_bytes(); }
+  bool has_cpu_frequency() const { return at<11>().valid(); }
+  ::protozero::ConstBytes cpu_frequency() const { return at<11>().as_bytes(); }
+  bool has_cpu_frequency_limits() const { return at<12>().valid(); }
+  ::protozero::ConstBytes cpu_frequency_limits() const { return at<12>().as_bytes(); }
+  bool has_cpu_idle() const { return at<13>().valid(); }
+  ::protozero::ConstBytes cpu_idle() const { return at<13>().as_bytes(); }
+  bool has_clock_enable() const { return at<14>().valid(); }
+  ::protozero::ConstBytes clock_enable() const { return at<14>().as_bytes(); }
+  bool has_clock_disable() const { return at<15>().valid(); }
+  ::protozero::ConstBytes clock_disable() const { return at<15>().as_bytes(); }
+  bool has_clock_set_rate() const { return at<16>().valid(); }
+  ::protozero::ConstBytes clock_set_rate() const { return at<16>().as_bytes(); }
+  bool has_sched_wakeup() const { return at<17>().valid(); }
+  ::protozero::ConstBytes sched_wakeup() const { return at<17>().as_bytes(); }
+  bool has_sched_blocked_reason() const { return at<18>().valid(); }
+  ::protozero::ConstBytes sched_blocked_reason() const { return at<18>().as_bytes(); }
+  bool has_sched_cpu_hotplug() const { return at<19>().valid(); }
+  ::protozero::ConstBytes sched_cpu_hotplug() const { return at<19>().as_bytes(); }
+  bool has_sched_waking() const { return at<20>().valid(); }
+  ::protozero::ConstBytes sched_waking() const { return at<20>().as_bytes(); }
+  bool has_ipi_entry() const { return at<21>().valid(); }
+  ::protozero::ConstBytes ipi_entry() const { return at<21>().as_bytes(); }
+  bool has_ipi_exit() const { return at<22>().valid(); }
+  ::protozero::ConstBytes ipi_exit() const { return at<22>().as_bytes(); }
+  bool has_ipi_raise() const { return at<23>().valid(); }
+  ::protozero::ConstBytes ipi_raise() const { return at<23>().as_bytes(); }
+  bool has_softirq_entry() const { return at<24>().valid(); }
+  ::protozero::ConstBytes softirq_entry() const { return at<24>().as_bytes(); }
+  bool has_softirq_exit() const { return at<25>().valid(); }
+  ::protozero::ConstBytes softirq_exit() const { return at<25>().as_bytes(); }
+  bool has_softirq_raise() const { return at<26>().valid(); }
+  ::protozero::ConstBytes softirq_raise() const { return at<26>().as_bytes(); }
+  bool has_i2c_read() const { return at<27>().valid(); }
+  ::protozero::ConstBytes i2c_read() const { return at<27>().as_bytes(); }
+  bool has_i2c_write() const { return at<28>().valid(); }
+  ::protozero::ConstBytes i2c_write() const { return at<28>().as_bytes(); }
+  bool has_i2c_result() const { return at<29>().valid(); }
+  ::protozero::ConstBytes i2c_result() const { return at<29>().as_bytes(); }
+  bool has_i2c_reply() const { return at<30>().valid(); }
+  ::protozero::ConstBytes i2c_reply() const { return at<30>().as_bytes(); }
+  bool has_smbus_read() const { return at<31>().valid(); }
+  ::protozero::ConstBytes smbus_read() const { return at<31>().as_bytes(); }
+  bool has_smbus_write() const { return at<32>().valid(); }
+  ::protozero::ConstBytes smbus_write() const { return at<32>().as_bytes(); }
+  bool has_smbus_result() const { return at<33>().valid(); }
+  ::protozero::ConstBytes smbus_result() const { return at<33>().as_bytes(); }
+  bool has_smbus_reply() const { return at<34>().valid(); }
+  ::protozero::ConstBytes smbus_reply() const { return at<34>().as_bytes(); }
+  bool has_lowmemory_kill() const { return at<35>().valid(); }
+  ::protozero::ConstBytes lowmemory_kill() const { return at<35>().as_bytes(); }
+  bool has_irq_handler_entry() const { return at<36>().valid(); }
+  ::protozero::ConstBytes irq_handler_entry() const { return at<36>().as_bytes(); }
+  bool has_irq_handler_exit() const { return at<37>().valid(); }
+  ::protozero::ConstBytes irq_handler_exit() const { return at<37>().as_bytes(); }
+  bool has_sync_pt() const { return at<38>().valid(); }
+  ::protozero::ConstBytes sync_pt() const { return at<38>().as_bytes(); }
+  bool has_sync_timeline() const { return at<39>().valid(); }
+  ::protozero::ConstBytes sync_timeline() const { return at<39>().as_bytes(); }
+  bool has_sync_wait() const { return at<40>().valid(); }
+  ::protozero::ConstBytes sync_wait() const { return at<40>().as_bytes(); }
+  bool has_ext4_da_write_begin() const { return at<41>().valid(); }
+  ::protozero::ConstBytes ext4_da_write_begin() const { return at<41>().as_bytes(); }
+  bool has_ext4_da_write_end() const { return at<42>().valid(); }
+  ::protozero::ConstBytes ext4_da_write_end() const { return at<42>().as_bytes(); }
+  bool has_ext4_sync_file_enter() const { return at<43>().valid(); }
+  ::protozero::ConstBytes ext4_sync_file_enter() const { return at<43>().as_bytes(); }
+  bool has_ext4_sync_file_exit() const { return at<44>().valid(); }
+  ::protozero::ConstBytes ext4_sync_file_exit() const { return at<44>().as_bytes(); }
+  bool has_block_rq_issue() const { return at<45>().valid(); }
+  ::protozero::ConstBytes block_rq_issue() const { return at<45>().as_bytes(); }
+  bool has_mm_vmscan_direct_reclaim_begin() const { return at<46>().valid(); }
+  ::protozero::ConstBytes mm_vmscan_direct_reclaim_begin() const { return at<46>().as_bytes(); }
+  bool has_mm_vmscan_direct_reclaim_end() const { return at<47>().valid(); }
+  ::protozero::ConstBytes mm_vmscan_direct_reclaim_end() const { return at<47>().as_bytes(); }
+  bool has_mm_vmscan_kswapd_wake() const { return at<48>().valid(); }
+  ::protozero::ConstBytes mm_vmscan_kswapd_wake() const { return at<48>().as_bytes(); }
+  bool has_mm_vmscan_kswapd_sleep() const { return at<49>().valid(); }
+  ::protozero::ConstBytes mm_vmscan_kswapd_sleep() const { return at<49>().as_bytes(); }
+  bool has_binder_transaction() const { return at<50>().valid(); }
+  ::protozero::ConstBytes binder_transaction() const { return at<50>().as_bytes(); }
+  bool has_binder_transaction_received() const { return at<51>().valid(); }
+  ::protozero::ConstBytes binder_transaction_received() const { return at<51>().as_bytes(); }
+  bool has_binder_set_priority() const { return at<52>().valid(); }
+  ::protozero::ConstBytes binder_set_priority() const { return at<52>().as_bytes(); }
+  bool has_binder_lock() const { return at<53>().valid(); }
+  ::protozero::ConstBytes binder_lock() const { return at<53>().as_bytes(); }
+  bool has_binder_locked() const { return at<54>().valid(); }
+  ::protozero::ConstBytes binder_locked() const { return at<54>().as_bytes(); }
+  bool has_binder_unlock() const { return at<55>().valid(); }
+  ::protozero::ConstBytes binder_unlock() const { return at<55>().as_bytes(); }
+  bool has_workqueue_activate_work() const { return at<56>().valid(); }
+  ::protozero::ConstBytes workqueue_activate_work() const { return at<56>().as_bytes(); }
+  bool has_workqueue_execute_end() const { return at<57>().valid(); }
+  ::protozero::ConstBytes workqueue_execute_end() const { return at<57>().as_bytes(); }
+  bool has_workqueue_execute_start() const { return at<58>().valid(); }
+  ::protozero::ConstBytes workqueue_execute_start() const { return at<58>().as_bytes(); }
+  bool has_workqueue_queue_work() const { return at<59>().valid(); }
+  ::protozero::ConstBytes workqueue_queue_work() const { return at<59>().as_bytes(); }
+  bool has_regulator_disable() const { return at<60>().valid(); }
+  ::protozero::ConstBytes regulator_disable() const { return at<60>().as_bytes(); }
+  bool has_regulator_disable_complete() const { return at<61>().valid(); }
+  ::protozero::ConstBytes regulator_disable_complete() const { return at<61>().as_bytes(); }
+  bool has_regulator_enable() const { return at<62>().valid(); }
+  ::protozero::ConstBytes regulator_enable() const { return at<62>().as_bytes(); }
+  bool has_regulator_enable_complete() const { return at<63>().valid(); }
+  ::protozero::ConstBytes regulator_enable_complete() const { return at<63>().as_bytes(); }
+  bool has_regulator_enable_delay() const { return at<64>().valid(); }
+  ::protozero::ConstBytes regulator_enable_delay() const { return at<64>().as_bytes(); }
+  bool has_regulator_set_voltage() const { return at<65>().valid(); }
+  ::protozero::ConstBytes regulator_set_voltage() const { return at<65>().as_bytes(); }
+  bool has_regulator_set_voltage_complete() const { return at<66>().valid(); }
+  ::protozero::ConstBytes regulator_set_voltage_complete() const { return at<66>().as_bytes(); }
+  bool has_cgroup_attach_task() const { return at<67>().valid(); }
+  ::protozero::ConstBytes cgroup_attach_task() const { return at<67>().as_bytes(); }
+  bool has_cgroup_mkdir() const { return at<68>().valid(); }
+  ::protozero::ConstBytes cgroup_mkdir() const { return at<68>().as_bytes(); }
+  bool has_cgroup_remount() const { return at<69>().valid(); }
+  ::protozero::ConstBytes cgroup_remount() const { return at<69>().as_bytes(); }
+  bool has_cgroup_rmdir() const { return at<70>().valid(); }
+  ::protozero::ConstBytes cgroup_rmdir() const { return at<70>().as_bytes(); }
+  bool has_cgroup_transfer_tasks() const { return at<71>().valid(); }
+  ::protozero::ConstBytes cgroup_transfer_tasks() const { return at<71>().as_bytes(); }
+  bool has_cgroup_destroy_root() const { return at<72>().valid(); }
+  ::protozero::ConstBytes cgroup_destroy_root() const { return at<72>().as_bytes(); }
+  bool has_cgroup_release() const { return at<73>().valid(); }
+  ::protozero::ConstBytes cgroup_release() const { return at<73>().as_bytes(); }
+  bool has_cgroup_rename() const { return at<74>().valid(); }
+  ::protozero::ConstBytes cgroup_rename() const { return at<74>().as_bytes(); }
+  bool has_cgroup_setup_root() const { return at<75>().valid(); }
+  ::protozero::ConstBytes cgroup_setup_root() const { return at<75>().as_bytes(); }
+  bool has_mdp_cmd_kickoff() const { return at<76>().valid(); }
+  ::protozero::ConstBytes mdp_cmd_kickoff() const { return at<76>().as_bytes(); }
+  bool has_mdp_commit() const { return at<77>().valid(); }
+  ::protozero::ConstBytes mdp_commit() const { return at<77>().as_bytes(); }
+  bool has_mdp_perf_set_ot() const { return at<78>().valid(); }
+  ::protozero::ConstBytes mdp_perf_set_ot() const { return at<78>().as_bytes(); }
+  bool has_mdp_sspp_change() const { return at<79>().valid(); }
+  ::protozero::ConstBytes mdp_sspp_change() const { return at<79>().as_bytes(); }
+  bool has_tracing_mark_write() const { return at<80>().valid(); }
+  ::protozero::ConstBytes tracing_mark_write() const { return at<80>().as_bytes(); }
+  bool has_mdp_cmd_pingpong_done() const { return at<81>().valid(); }
+  ::protozero::ConstBytes mdp_cmd_pingpong_done() const { return at<81>().as_bytes(); }
+  bool has_mdp_compare_bw() const { return at<82>().valid(); }
+  ::protozero::ConstBytes mdp_compare_bw() const { return at<82>().as_bytes(); }
+  bool has_mdp_perf_set_panic_luts() const { return at<83>().valid(); }
+  ::protozero::ConstBytes mdp_perf_set_panic_luts() const { return at<83>().as_bytes(); }
+  bool has_mdp_sspp_set() const { return at<84>().valid(); }
+  ::protozero::ConstBytes mdp_sspp_set() const { return at<84>().as_bytes(); }
+  bool has_mdp_cmd_readptr_done() const { return at<85>().valid(); }
+  ::protozero::ConstBytes mdp_cmd_readptr_done() const { return at<85>().as_bytes(); }
+  bool has_mdp_misr_crc() const { return at<86>().valid(); }
+  ::protozero::ConstBytes mdp_misr_crc() const { return at<86>().as_bytes(); }
+  bool has_mdp_perf_set_qos_luts() const { return at<87>().valid(); }
+  ::protozero::ConstBytes mdp_perf_set_qos_luts() const { return at<87>().as_bytes(); }
+  bool has_mdp_trace_counter() const { return at<88>().valid(); }
+  ::protozero::ConstBytes mdp_trace_counter() const { return at<88>().as_bytes(); }
+  bool has_mdp_cmd_release_bw() const { return at<89>().valid(); }
+  ::protozero::ConstBytes mdp_cmd_release_bw() const { return at<89>().as_bytes(); }
+  bool has_mdp_mixer_update() const { return at<90>().valid(); }
+  ::protozero::ConstBytes mdp_mixer_update() const { return at<90>().as_bytes(); }
+  bool has_mdp_perf_set_wm_levels() const { return at<91>().valid(); }
+  ::protozero::ConstBytes mdp_perf_set_wm_levels() const { return at<91>().as_bytes(); }
+  bool has_mdp_video_underrun_done() const { return at<92>().valid(); }
+  ::protozero::ConstBytes mdp_video_underrun_done() const { return at<92>().as_bytes(); }
+  bool has_mdp_cmd_wait_pingpong() const { return at<93>().valid(); }
+  ::protozero::ConstBytes mdp_cmd_wait_pingpong() const { return at<93>().as_bytes(); }
+  bool has_mdp_perf_prefill_calc() const { return at<94>().valid(); }
+  ::protozero::ConstBytes mdp_perf_prefill_calc() const { return at<94>().as_bytes(); }
+  bool has_mdp_perf_update_bus() const { return at<95>().valid(); }
+  ::protozero::ConstBytes mdp_perf_update_bus() const { return at<95>().as_bytes(); }
+  bool has_rotator_bw_ao_as_context() const { return at<96>().valid(); }
+  ::protozero::ConstBytes rotator_bw_ao_as_context() const { return at<96>().as_bytes(); }
+  bool has_mm_filemap_add_to_page_cache() const { return at<97>().valid(); }
+  ::protozero::ConstBytes mm_filemap_add_to_page_cache() const { return at<97>().as_bytes(); }
+  bool has_mm_filemap_delete_from_page_cache() const { return at<98>().valid(); }
+  ::protozero::ConstBytes mm_filemap_delete_from_page_cache() const { return at<98>().as_bytes(); }
+  bool has_mm_compaction_begin() const { return at<99>().valid(); }
+  ::protozero::ConstBytes mm_compaction_begin() const { return at<99>().as_bytes(); }
+  bool has_mm_compaction_defer_compaction() const { return at<100>().valid(); }
+  ::protozero::ConstBytes mm_compaction_defer_compaction() const { return at<100>().as_bytes(); }
+  bool has_mm_compaction_deferred() const { return at<101>().valid(); }
+  ::protozero::ConstBytes mm_compaction_deferred() const { return at<101>().as_bytes(); }
+  bool has_mm_compaction_defer_reset() const { return at<102>().valid(); }
+  ::protozero::ConstBytes mm_compaction_defer_reset() const { return at<102>().as_bytes(); }
+  bool has_mm_compaction_end() const { return at<103>().valid(); }
+  ::protozero::ConstBytes mm_compaction_end() const { return at<103>().as_bytes(); }
+  bool has_mm_compaction_finished() const { return at<104>().valid(); }
+  ::protozero::ConstBytes mm_compaction_finished() const { return at<104>().as_bytes(); }
+  bool has_mm_compaction_isolate_freepages() const { return at<105>().valid(); }
+  ::protozero::ConstBytes mm_compaction_isolate_freepages() const { return at<105>().as_bytes(); }
+  bool has_mm_compaction_isolate_migratepages() const { return at<106>().valid(); }
+  ::protozero::ConstBytes mm_compaction_isolate_migratepages() const { return at<106>().as_bytes(); }
+  bool has_mm_compaction_kcompactd_sleep() const { return at<107>().valid(); }
+  ::protozero::ConstBytes mm_compaction_kcompactd_sleep() const { return at<107>().as_bytes(); }
+  bool has_mm_compaction_kcompactd_wake() const { return at<108>().valid(); }
+  ::protozero::ConstBytes mm_compaction_kcompactd_wake() const { return at<108>().as_bytes(); }
+  bool has_mm_compaction_migratepages() const { return at<109>().valid(); }
+  ::protozero::ConstBytes mm_compaction_migratepages() const { return at<109>().as_bytes(); }
+  bool has_mm_compaction_suitable() const { return at<110>().valid(); }
+  ::protozero::ConstBytes mm_compaction_suitable() const { return at<110>().as_bytes(); }
+  bool has_mm_compaction_try_to_compact_pages() const { return at<111>().valid(); }
+  ::protozero::ConstBytes mm_compaction_try_to_compact_pages() const { return at<111>().as_bytes(); }
+  bool has_mm_compaction_wakeup_kcompactd() const { return at<112>().valid(); }
+  ::protozero::ConstBytes mm_compaction_wakeup_kcompactd() const { return at<112>().as_bytes(); }
+  bool has_suspend_resume() const { return at<113>().valid(); }
+  ::protozero::ConstBytes suspend_resume() const { return at<113>().as_bytes(); }
+  bool has_sched_wakeup_new() const { return at<114>().valid(); }
+  ::protozero::ConstBytes sched_wakeup_new() const { return at<114>().as_bytes(); }
+  bool has_block_bio_backmerge() const { return at<115>().valid(); }
+  ::protozero::ConstBytes block_bio_backmerge() const { return at<115>().as_bytes(); }
+  bool has_block_bio_bounce() const { return at<116>().valid(); }
+  ::protozero::ConstBytes block_bio_bounce() const { return at<116>().as_bytes(); }
+  bool has_block_bio_complete() const { return at<117>().valid(); }
+  ::protozero::ConstBytes block_bio_complete() const { return at<117>().as_bytes(); }
+  bool has_block_bio_frontmerge() const { return at<118>().valid(); }
+  ::protozero::ConstBytes block_bio_frontmerge() const { return at<118>().as_bytes(); }
+  bool has_block_bio_queue() const { return at<119>().valid(); }
+  ::protozero::ConstBytes block_bio_queue() const { return at<119>().as_bytes(); }
+  bool has_block_bio_remap() const { return at<120>().valid(); }
+  ::protozero::ConstBytes block_bio_remap() const { return at<120>().as_bytes(); }
+  bool has_block_dirty_buffer() const { return at<121>().valid(); }
+  ::protozero::ConstBytes block_dirty_buffer() const { return at<121>().as_bytes(); }
+  bool has_block_getrq() const { return at<122>().valid(); }
+  ::protozero::ConstBytes block_getrq() const { return at<122>().as_bytes(); }
+  bool has_block_plug() const { return at<123>().valid(); }
+  ::protozero::ConstBytes block_plug() const { return at<123>().as_bytes(); }
+  bool has_block_rq_abort() const { return at<124>().valid(); }
+  ::protozero::ConstBytes block_rq_abort() const { return at<124>().as_bytes(); }
+  bool has_block_rq_complete() const { return at<125>().valid(); }
+  ::protozero::ConstBytes block_rq_complete() const { return at<125>().as_bytes(); }
+  bool has_block_rq_insert() const { return at<126>().valid(); }
+  ::protozero::ConstBytes block_rq_insert() const { return at<126>().as_bytes(); }
+  bool has_block_rq_remap() const { return at<128>().valid(); }
+  ::protozero::ConstBytes block_rq_remap() const { return at<128>().as_bytes(); }
+  bool has_block_rq_requeue() const { return at<129>().valid(); }
+  ::protozero::ConstBytes block_rq_requeue() const { return at<129>().as_bytes(); }
+  bool has_block_sleeprq() const { return at<130>().valid(); }
+  ::protozero::ConstBytes block_sleeprq() const { return at<130>().as_bytes(); }
+  bool has_block_split() const { return at<131>().valid(); }
+  ::protozero::ConstBytes block_split() const { return at<131>().as_bytes(); }
+  bool has_block_touch_buffer() const { return at<132>().valid(); }
+  ::protozero::ConstBytes block_touch_buffer() const { return at<132>().as_bytes(); }
+  bool has_block_unplug() const { return at<133>().valid(); }
+  ::protozero::ConstBytes block_unplug() const { return at<133>().as_bytes(); }
+  bool has_ext4_alloc_da_blocks() const { return at<134>().valid(); }
+  ::protozero::ConstBytes ext4_alloc_da_blocks() const { return at<134>().as_bytes(); }
+  bool has_ext4_allocate_blocks() const { return at<135>().valid(); }
+  ::protozero::ConstBytes ext4_allocate_blocks() const { return at<135>().as_bytes(); }
+  bool has_ext4_allocate_inode() const { return at<136>().valid(); }
+  ::protozero::ConstBytes ext4_allocate_inode() const { return at<136>().as_bytes(); }
+  bool has_ext4_begin_ordered_truncate() const { return at<137>().valid(); }
+  ::protozero::ConstBytes ext4_begin_ordered_truncate() const { return at<137>().as_bytes(); }
+  bool has_ext4_collapse_range() const { return at<138>().valid(); }
+  ::protozero::ConstBytes ext4_collapse_range() const { return at<138>().as_bytes(); }
+  bool has_ext4_da_release_space() const { return at<139>().valid(); }
+  ::protozero::ConstBytes ext4_da_release_space() const { return at<139>().as_bytes(); }
+  bool has_ext4_da_reserve_space() const { return at<140>().valid(); }
+  ::protozero::ConstBytes ext4_da_reserve_space() const { return at<140>().as_bytes(); }
+  bool has_ext4_da_update_reserve_space() const { return at<141>().valid(); }
+  ::protozero::ConstBytes ext4_da_update_reserve_space() const { return at<141>().as_bytes(); }
+  bool has_ext4_da_write_pages() const { return at<142>().valid(); }
+  ::protozero::ConstBytes ext4_da_write_pages() const { return at<142>().as_bytes(); }
+  bool has_ext4_da_write_pages_extent() const { return at<143>().valid(); }
+  ::protozero::ConstBytes ext4_da_write_pages_extent() const { return at<143>().as_bytes(); }
+  bool has_ext4_direct_io_enter() const { return at<144>().valid(); }
+  ::protozero::ConstBytes ext4_direct_io_enter() const { return at<144>().as_bytes(); }
+  bool has_ext4_direct_io_exit() const { return at<145>().valid(); }
+  ::protozero::ConstBytes ext4_direct_io_exit() const { return at<145>().as_bytes(); }
+  bool has_ext4_discard_blocks() const { return at<146>().valid(); }
+  ::protozero::ConstBytes ext4_discard_blocks() const { return at<146>().as_bytes(); }
+  bool has_ext4_discard_preallocations() const { return at<147>().valid(); }
+  ::protozero::ConstBytes ext4_discard_preallocations() const { return at<147>().as_bytes(); }
+  bool has_ext4_drop_inode() const { return at<148>().valid(); }
+  ::protozero::ConstBytes ext4_drop_inode() const { return at<148>().as_bytes(); }
+  bool has_ext4_es_cache_extent() const { return at<149>().valid(); }
+  ::protozero::ConstBytes ext4_es_cache_extent() const { return at<149>().as_bytes(); }
+  bool has_ext4_es_find_delayed_extent_range_enter() const { return at<150>().valid(); }
+  ::protozero::ConstBytes ext4_es_find_delayed_extent_range_enter() const { return at<150>().as_bytes(); }
+  bool has_ext4_es_find_delayed_extent_range_exit() const { return at<151>().valid(); }
+  ::protozero::ConstBytes ext4_es_find_delayed_extent_range_exit() const { return at<151>().as_bytes(); }
+  bool has_ext4_es_insert_extent() const { return at<152>().valid(); }
+  ::protozero::ConstBytes ext4_es_insert_extent() const { return at<152>().as_bytes(); }
+  bool has_ext4_es_lookup_extent_enter() const { return at<153>().valid(); }
+  ::protozero::ConstBytes ext4_es_lookup_extent_enter() const { return at<153>().as_bytes(); }
+  bool has_ext4_es_lookup_extent_exit() const { return at<154>().valid(); }
+  ::protozero::ConstBytes ext4_es_lookup_extent_exit() const { return at<154>().as_bytes(); }
+  bool has_ext4_es_remove_extent() const { return at<155>().valid(); }
+  ::protozero::ConstBytes ext4_es_remove_extent() const { return at<155>().as_bytes(); }
+  bool has_ext4_es_shrink() const { return at<156>().valid(); }
+  ::protozero::ConstBytes ext4_es_shrink() const { return at<156>().as_bytes(); }
+  bool has_ext4_es_shrink_count() const { return at<157>().valid(); }
+  ::protozero::ConstBytes ext4_es_shrink_count() const { return at<157>().as_bytes(); }
+  bool has_ext4_es_shrink_scan_enter() const { return at<158>().valid(); }
+  ::protozero::ConstBytes ext4_es_shrink_scan_enter() const { return at<158>().as_bytes(); }
+  bool has_ext4_es_shrink_scan_exit() const { return at<159>().valid(); }
+  ::protozero::ConstBytes ext4_es_shrink_scan_exit() const { return at<159>().as_bytes(); }
+  bool has_ext4_evict_inode() const { return at<160>().valid(); }
+  ::protozero::ConstBytes ext4_evict_inode() const { return at<160>().as_bytes(); }
+  bool has_ext4_ext_convert_to_initialized_enter() const { return at<161>().valid(); }
+  ::protozero::ConstBytes ext4_ext_convert_to_initialized_enter() const { return at<161>().as_bytes(); }
+  bool has_ext4_ext_convert_to_initialized_fastpath() const { return at<162>().valid(); }
+  ::protozero::ConstBytes ext4_ext_convert_to_initialized_fastpath() const { return at<162>().as_bytes(); }
+  bool has_ext4_ext_handle_unwritten_extents() const { return at<163>().valid(); }
+  ::protozero::ConstBytes ext4_ext_handle_unwritten_extents() const { return at<163>().as_bytes(); }
+  bool has_ext4_ext_in_cache() const { return at<164>().valid(); }
+  ::protozero::ConstBytes ext4_ext_in_cache() const { return at<164>().as_bytes(); }
+  bool has_ext4_ext_load_extent() const { return at<165>().valid(); }
+  ::protozero::ConstBytes ext4_ext_load_extent() const { return at<165>().as_bytes(); }
+  bool has_ext4_ext_map_blocks_enter() const { return at<166>().valid(); }
+  ::protozero::ConstBytes ext4_ext_map_blocks_enter() const { return at<166>().as_bytes(); }
+  bool has_ext4_ext_map_blocks_exit() const { return at<167>().valid(); }
+  ::protozero::ConstBytes ext4_ext_map_blocks_exit() const { return at<167>().as_bytes(); }
+  bool has_ext4_ext_put_in_cache() const { return at<168>().valid(); }
+  ::protozero::ConstBytes ext4_ext_put_in_cache() const { return at<168>().as_bytes(); }
+  bool has_ext4_ext_remove_space() const { return at<169>().valid(); }
+  ::protozero::ConstBytes ext4_ext_remove_space() const { return at<169>().as_bytes(); }
+  bool has_ext4_ext_remove_space_done() const { return at<170>().valid(); }
+  ::protozero::ConstBytes ext4_ext_remove_space_done() const { return at<170>().as_bytes(); }
+  bool has_ext4_ext_rm_idx() const { return at<171>().valid(); }
+  ::protozero::ConstBytes ext4_ext_rm_idx() const { return at<171>().as_bytes(); }
+  bool has_ext4_ext_rm_leaf() const { return at<172>().valid(); }
+  ::protozero::ConstBytes ext4_ext_rm_leaf() const { return at<172>().as_bytes(); }
+  bool has_ext4_ext_show_extent() const { return at<173>().valid(); }
+  ::protozero::ConstBytes ext4_ext_show_extent() const { return at<173>().as_bytes(); }
+  bool has_ext4_fallocate_enter() const { return at<174>().valid(); }
+  ::protozero::ConstBytes ext4_fallocate_enter() const { return at<174>().as_bytes(); }
+  bool has_ext4_fallocate_exit() const { return at<175>().valid(); }
+  ::protozero::ConstBytes ext4_fallocate_exit() const { return at<175>().as_bytes(); }
+  bool has_ext4_find_delalloc_range() const { return at<176>().valid(); }
+  ::protozero::ConstBytes ext4_find_delalloc_range() const { return at<176>().as_bytes(); }
+  bool has_ext4_forget() const { return at<177>().valid(); }
+  ::protozero::ConstBytes ext4_forget() const { return at<177>().as_bytes(); }
+  bool has_ext4_free_blocks() const { return at<178>().valid(); }
+  ::protozero::ConstBytes ext4_free_blocks() const { return at<178>().as_bytes(); }
+  bool has_ext4_free_inode() const { return at<179>().valid(); }
+  ::protozero::ConstBytes ext4_free_inode() const { return at<179>().as_bytes(); }
+  bool has_ext4_get_implied_cluster_alloc_exit() const { return at<180>().valid(); }
+  ::protozero::ConstBytes ext4_get_implied_cluster_alloc_exit() const { return at<180>().as_bytes(); }
+  bool has_ext4_get_reserved_cluster_alloc() const { return at<181>().valid(); }
+  ::protozero::ConstBytes ext4_get_reserved_cluster_alloc() const { return at<181>().as_bytes(); }
+  bool has_ext4_ind_map_blocks_enter() const { return at<182>().valid(); }
+  ::protozero::ConstBytes ext4_ind_map_blocks_enter() const { return at<182>().as_bytes(); }
+  bool has_ext4_ind_map_blocks_exit() const { return at<183>().valid(); }
+  ::protozero::ConstBytes ext4_ind_map_blocks_exit() const { return at<183>().as_bytes(); }
+  bool has_ext4_insert_range() const { return at<184>().valid(); }
+  ::protozero::ConstBytes ext4_insert_range() const { return at<184>().as_bytes(); }
+  bool has_ext4_invalidatepage() const { return at<185>().valid(); }
+  ::protozero::ConstBytes ext4_invalidatepage() const { return at<185>().as_bytes(); }
+  bool has_ext4_journal_start() const { return at<186>().valid(); }
+  ::protozero::ConstBytes ext4_journal_start() const { return at<186>().as_bytes(); }
+  bool has_ext4_journal_start_reserved() const { return at<187>().valid(); }
+  ::protozero::ConstBytes ext4_journal_start_reserved() const { return at<187>().as_bytes(); }
+  bool has_ext4_journalled_invalidatepage() const { return at<188>().valid(); }
+  ::protozero::ConstBytes ext4_journalled_invalidatepage() const { return at<188>().as_bytes(); }
+  bool has_ext4_journalled_write_end() const { return at<189>().valid(); }
+  ::protozero::ConstBytes ext4_journalled_write_end() const { return at<189>().as_bytes(); }
+  bool has_ext4_load_inode() const { return at<190>().valid(); }
+  ::protozero::ConstBytes ext4_load_inode() const { return at<190>().as_bytes(); }
+  bool has_ext4_load_inode_bitmap() const { return at<191>().valid(); }
+  ::protozero::ConstBytes ext4_load_inode_bitmap() const { return at<191>().as_bytes(); }
+  bool has_ext4_mark_inode_dirty() const { return at<192>().valid(); }
+  ::protozero::ConstBytes ext4_mark_inode_dirty() const { return at<192>().as_bytes(); }
+  bool has_ext4_mb_bitmap_load() const { return at<193>().valid(); }
+  ::protozero::ConstBytes ext4_mb_bitmap_load() const { return at<193>().as_bytes(); }
+  bool has_ext4_mb_buddy_bitmap_load() const { return at<194>().valid(); }
+  ::protozero::ConstBytes ext4_mb_buddy_bitmap_load() const { return at<194>().as_bytes(); }
+  bool has_ext4_mb_discard_preallocations() const { return at<195>().valid(); }
+  ::protozero::ConstBytes ext4_mb_discard_preallocations() const { return at<195>().as_bytes(); }
+  bool has_ext4_mb_new_group_pa() const { return at<196>().valid(); }
+  ::protozero::ConstBytes ext4_mb_new_group_pa() const { return at<196>().as_bytes(); }
+  bool has_ext4_mb_new_inode_pa() const { return at<197>().valid(); }
+  ::protozero::ConstBytes ext4_mb_new_inode_pa() const { return at<197>().as_bytes(); }
+  bool has_ext4_mb_release_group_pa() const { return at<198>().valid(); }
+  ::protozero::ConstBytes ext4_mb_release_group_pa() const { return at<198>().as_bytes(); }
+  bool has_ext4_mb_release_inode_pa() const { return at<199>().valid(); }
+  ::protozero::ConstBytes ext4_mb_release_inode_pa() const { return at<199>().as_bytes(); }
+  bool has_ext4_mballoc_alloc() const { return at<200>().valid(); }
+  ::protozero::ConstBytes ext4_mballoc_alloc() const { return at<200>().as_bytes(); }
+  bool has_ext4_mballoc_discard() const { return at<201>().valid(); }
+  ::protozero::ConstBytes ext4_mballoc_discard() const { return at<201>().as_bytes(); }
+  bool has_ext4_mballoc_free() const { return at<202>().valid(); }
+  ::protozero::ConstBytes ext4_mballoc_free() const { return at<202>().as_bytes(); }
+  bool has_ext4_mballoc_prealloc() const { return at<203>().valid(); }
+  ::protozero::ConstBytes ext4_mballoc_prealloc() const { return at<203>().as_bytes(); }
+  bool has_ext4_other_inode_update_time() const { return at<204>().valid(); }
+  ::protozero::ConstBytes ext4_other_inode_update_time() const { return at<204>().as_bytes(); }
+  bool has_ext4_punch_hole() const { return at<205>().valid(); }
+  ::protozero::ConstBytes ext4_punch_hole() const { return at<205>().as_bytes(); }
+  bool has_ext4_read_block_bitmap_load() const { return at<206>().valid(); }
+  ::protozero::ConstBytes ext4_read_block_bitmap_load() const { return at<206>().as_bytes(); }
+  bool has_ext4_readpage() const { return at<207>().valid(); }
+  ::protozero::ConstBytes ext4_readpage() const { return at<207>().as_bytes(); }
+  bool has_ext4_releasepage() const { return at<208>().valid(); }
+  ::protozero::ConstBytes ext4_releasepage() const { return at<208>().as_bytes(); }
+  bool has_ext4_remove_blocks() const { return at<209>().valid(); }
+  ::protozero::ConstBytes ext4_remove_blocks() const { return at<209>().as_bytes(); }
+  bool has_ext4_request_blocks() const { return at<210>().valid(); }
+  ::protozero::ConstBytes ext4_request_blocks() const { return at<210>().as_bytes(); }
+  bool has_ext4_request_inode() const { return at<211>().valid(); }
+  ::protozero::ConstBytes ext4_request_inode() const { return at<211>().as_bytes(); }
+  bool has_ext4_sync_fs() const { return at<212>().valid(); }
+  ::protozero::ConstBytes ext4_sync_fs() const { return at<212>().as_bytes(); }
+  bool has_ext4_trim_all_free() const { return at<213>().valid(); }
+  ::protozero::ConstBytes ext4_trim_all_free() const { return at<213>().as_bytes(); }
+  bool has_ext4_trim_extent() const { return at<214>().valid(); }
+  ::protozero::ConstBytes ext4_trim_extent() const { return at<214>().as_bytes(); }
+  bool has_ext4_truncate_enter() const { return at<215>().valid(); }
+  ::protozero::ConstBytes ext4_truncate_enter() const { return at<215>().as_bytes(); }
+  bool has_ext4_truncate_exit() const { return at<216>().valid(); }
+  ::protozero::ConstBytes ext4_truncate_exit() const { return at<216>().as_bytes(); }
+  bool has_ext4_unlink_enter() const { return at<217>().valid(); }
+  ::protozero::ConstBytes ext4_unlink_enter() const { return at<217>().as_bytes(); }
+  bool has_ext4_unlink_exit() const { return at<218>().valid(); }
+  ::protozero::ConstBytes ext4_unlink_exit() const { return at<218>().as_bytes(); }
+  bool has_ext4_write_begin() const { return at<219>().valid(); }
+  ::protozero::ConstBytes ext4_write_begin() const { return at<219>().as_bytes(); }
+  bool has_ext4_write_end() const { return at<230>().valid(); }
+  ::protozero::ConstBytes ext4_write_end() const { return at<230>().as_bytes(); }
+  bool has_ext4_writepage() const { return at<231>().valid(); }
+  ::protozero::ConstBytes ext4_writepage() const { return at<231>().as_bytes(); }
+  bool has_ext4_writepages() const { return at<232>().valid(); }
+  ::protozero::ConstBytes ext4_writepages() const { return at<232>().as_bytes(); }
+  bool has_ext4_writepages_result() const { return at<233>().valid(); }
+  ::protozero::ConstBytes ext4_writepages_result() const { return at<233>().as_bytes(); }
+  bool has_ext4_zero_range() const { return at<234>().valid(); }
+  ::protozero::ConstBytes ext4_zero_range() const { return at<234>().as_bytes(); }
+  bool has_task_newtask() const { return at<235>().valid(); }
+  ::protozero::ConstBytes task_newtask() const { return at<235>().as_bytes(); }
+  bool has_task_rename() const { return at<236>().valid(); }
+  ::protozero::ConstBytes task_rename() const { return at<236>().as_bytes(); }
+  bool has_sched_process_exec() const { return at<237>().valid(); }
+  ::protozero::ConstBytes sched_process_exec() const { return at<237>().as_bytes(); }
+  bool has_sched_process_exit() const { return at<238>().valid(); }
+  ::protozero::ConstBytes sched_process_exit() const { return at<238>().as_bytes(); }
+  bool has_sched_process_fork() const { return at<239>().valid(); }
+  ::protozero::ConstBytes sched_process_fork() const { return at<239>().as_bytes(); }
+  bool has_sched_process_free() const { return at<240>().valid(); }
+  ::protozero::ConstBytes sched_process_free() const { return at<240>().as_bytes(); }
+  bool has_sched_process_hang() const { return at<241>().valid(); }
+  ::protozero::ConstBytes sched_process_hang() const { return at<241>().as_bytes(); }
+  bool has_sched_process_wait() const { return at<242>().valid(); }
+  ::protozero::ConstBytes sched_process_wait() const { return at<242>().as_bytes(); }
+  bool has_f2fs_do_submit_bio() const { return at<243>().valid(); }
+  ::protozero::ConstBytes f2fs_do_submit_bio() const { return at<243>().as_bytes(); }
+  bool has_f2fs_evict_inode() const { return at<244>().valid(); }
+  ::protozero::ConstBytes f2fs_evict_inode() const { return at<244>().as_bytes(); }
+  bool has_f2fs_fallocate() const { return at<245>().valid(); }
+  ::protozero::ConstBytes f2fs_fallocate() const { return at<245>().as_bytes(); }
+  bool has_f2fs_get_data_block() const { return at<246>().valid(); }
+  ::protozero::ConstBytes f2fs_get_data_block() const { return at<246>().as_bytes(); }
+  bool has_f2fs_get_victim() const { return at<247>().valid(); }
+  ::protozero::ConstBytes f2fs_get_victim() const { return at<247>().as_bytes(); }
+  bool has_f2fs_iget() const { return at<248>().valid(); }
+  ::protozero::ConstBytes f2fs_iget() const { return at<248>().as_bytes(); }
+  bool has_f2fs_iget_exit() const { return at<249>().valid(); }
+  ::protozero::ConstBytes f2fs_iget_exit() const { return at<249>().as_bytes(); }
+  bool has_f2fs_new_inode() const { return at<250>().valid(); }
+  ::protozero::ConstBytes f2fs_new_inode() const { return at<250>().as_bytes(); }
+  bool has_f2fs_readpage() const { return at<251>().valid(); }
+  ::protozero::ConstBytes f2fs_readpage() const { return at<251>().as_bytes(); }
+  bool has_f2fs_reserve_new_block() const { return at<252>().valid(); }
+  ::protozero::ConstBytes f2fs_reserve_new_block() const { return at<252>().as_bytes(); }
+  bool has_f2fs_set_page_dirty() const { return at<253>().valid(); }
+  ::protozero::ConstBytes f2fs_set_page_dirty() const { return at<253>().as_bytes(); }
+  bool has_f2fs_submit_write_page() const { return at<254>().valid(); }
+  ::protozero::ConstBytes f2fs_submit_write_page() const { return at<254>().as_bytes(); }
+  bool has_f2fs_sync_file_enter() const { return at<255>().valid(); }
+  ::protozero::ConstBytes f2fs_sync_file_enter() const { return at<255>().as_bytes(); }
+  bool has_f2fs_sync_file_exit() const { return at<256>().valid(); }
+  ::protozero::ConstBytes f2fs_sync_file_exit() const { return at<256>().as_bytes(); }
+  bool has_f2fs_sync_fs() const { return at<257>().valid(); }
+  ::protozero::ConstBytes f2fs_sync_fs() const { return at<257>().as_bytes(); }
+  bool has_f2fs_truncate() const { return at<258>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate() const { return at<258>().as_bytes(); }
+  bool has_f2fs_truncate_blocks_enter() const { return at<259>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_blocks_enter() const { return at<259>().as_bytes(); }
+  bool has_f2fs_truncate_blocks_exit() const { return at<260>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_blocks_exit() const { return at<260>().as_bytes(); }
+  bool has_f2fs_truncate_data_blocks_range() const { return at<261>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_data_blocks_range() const { return at<261>().as_bytes(); }
+  bool has_f2fs_truncate_inode_blocks_enter() const { return at<262>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_inode_blocks_enter() const { return at<262>().as_bytes(); }
+  bool has_f2fs_truncate_inode_blocks_exit() const { return at<263>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_inode_blocks_exit() const { return at<263>().as_bytes(); }
+  bool has_f2fs_truncate_node() const { return at<264>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_node() const { return at<264>().as_bytes(); }
+  bool has_f2fs_truncate_nodes_enter() const { return at<265>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_nodes_enter() const { return at<265>().as_bytes(); }
+  bool has_f2fs_truncate_nodes_exit() const { return at<266>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_nodes_exit() const { return at<266>().as_bytes(); }
+  bool has_f2fs_truncate_partial_nodes() const { return at<267>().valid(); }
+  ::protozero::ConstBytes f2fs_truncate_partial_nodes() const { return at<267>().as_bytes(); }
+  bool has_f2fs_unlink_enter() const { return at<268>().valid(); }
+  ::protozero::ConstBytes f2fs_unlink_enter() const { return at<268>().as_bytes(); }
+  bool has_f2fs_unlink_exit() const { return at<269>().valid(); }
+  ::protozero::ConstBytes f2fs_unlink_exit() const { return at<269>().as_bytes(); }
+  bool has_f2fs_vm_page_mkwrite() const { return at<270>().valid(); }
+  ::protozero::ConstBytes f2fs_vm_page_mkwrite() const { return at<270>().as_bytes(); }
+  bool has_f2fs_write_begin() const { return at<271>().valid(); }
+  ::protozero::ConstBytes f2fs_write_begin() const { return at<271>().as_bytes(); }
+  bool has_f2fs_write_checkpoint() const { return at<272>().valid(); }
+  ::protozero::ConstBytes f2fs_write_checkpoint() const { return at<272>().as_bytes(); }
+  bool has_f2fs_write_end() const { return at<273>().valid(); }
+  ::protozero::ConstBytes f2fs_write_end() const { return at<273>().as_bytes(); }
+  bool has_alloc_pages_iommu_end() const { return at<274>().valid(); }
+  ::protozero::ConstBytes alloc_pages_iommu_end() const { return at<274>().as_bytes(); }
+  bool has_alloc_pages_iommu_fail() const { return at<275>().valid(); }
+  ::protozero::ConstBytes alloc_pages_iommu_fail() const { return at<275>().as_bytes(); }
+  bool has_alloc_pages_iommu_start() const { return at<276>().valid(); }
+  ::protozero::ConstBytes alloc_pages_iommu_start() const { return at<276>().as_bytes(); }
+  bool has_alloc_pages_sys_end() const { return at<277>().valid(); }
+  ::protozero::ConstBytes alloc_pages_sys_end() const { return at<277>().as_bytes(); }
+  bool has_alloc_pages_sys_fail() const { return at<278>().valid(); }
+  ::protozero::ConstBytes alloc_pages_sys_fail() const { return at<278>().as_bytes(); }
+  bool has_alloc_pages_sys_start() const { return at<279>().valid(); }
+  ::protozero::ConstBytes alloc_pages_sys_start() const { return at<279>().as_bytes(); }
+  bool has_dma_alloc_contiguous_retry() const { return at<280>().valid(); }
+  ::protozero::ConstBytes dma_alloc_contiguous_retry() const { return at<280>().as_bytes(); }
+  bool has_iommu_map_range() const { return at<281>().valid(); }
+  ::protozero::ConstBytes iommu_map_range() const { return at<281>().as_bytes(); }
+  bool has_iommu_sec_ptbl_map_range_end() const { return at<282>().valid(); }
+  ::protozero::ConstBytes iommu_sec_ptbl_map_range_end() const { return at<282>().as_bytes(); }
+  bool has_iommu_sec_ptbl_map_range_start() const { return at<283>().valid(); }
+  ::protozero::ConstBytes iommu_sec_ptbl_map_range_start() const { return at<283>().as_bytes(); }
+  bool has_ion_alloc_buffer_end() const { return at<284>().valid(); }
+  ::protozero::ConstBytes ion_alloc_buffer_end() const { return at<284>().as_bytes(); }
+  bool has_ion_alloc_buffer_fail() const { return at<285>().valid(); }
+  ::protozero::ConstBytes ion_alloc_buffer_fail() const { return at<285>().as_bytes(); }
+  bool has_ion_alloc_buffer_fallback() const { return at<286>().valid(); }
+  ::protozero::ConstBytes ion_alloc_buffer_fallback() const { return at<286>().as_bytes(); }
+  bool has_ion_alloc_buffer_start() const { return at<287>().valid(); }
+  ::protozero::ConstBytes ion_alloc_buffer_start() const { return at<287>().as_bytes(); }
+  bool has_ion_cp_alloc_retry() const { return at<288>().valid(); }
+  ::protozero::ConstBytes ion_cp_alloc_retry() const { return at<288>().as_bytes(); }
+  bool has_ion_cp_secure_buffer_end() const { return at<289>().valid(); }
+  ::protozero::ConstBytes ion_cp_secure_buffer_end() const { return at<289>().as_bytes(); }
+  bool has_ion_cp_secure_buffer_start() const { return at<290>().valid(); }
+  ::protozero::ConstBytes ion_cp_secure_buffer_start() const { return at<290>().as_bytes(); }
+  bool has_ion_prefetching() const { return at<291>().valid(); }
+  ::protozero::ConstBytes ion_prefetching() const { return at<291>().as_bytes(); }
+  bool has_ion_secure_cma_add_to_pool_end() const { return at<292>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_add_to_pool_end() const { return at<292>().as_bytes(); }
+  bool has_ion_secure_cma_add_to_pool_start() const { return at<293>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_add_to_pool_start() const { return at<293>().as_bytes(); }
+  bool has_ion_secure_cma_allocate_end() const { return at<294>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_allocate_end() const { return at<294>().as_bytes(); }
+  bool has_ion_secure_cma_allocate_start() const { return at<295>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_allocate_start() const { return at<295>().as_bytes(); }
+  bool has_ion_secure_cma_shrink_pool_end() const { return at<296>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_shrink_pool_end() const { return at<296>().as_bytes(); }
+  bool has_ion_secure_cma_shrink_pool_start() const { return at<297>().valid(); }
+  ::protozero::ConstBytes ion_secure_cma_shrink_pool_start() const { return at<297>().as_bytes(); }
+  bool has_kfree() const { return at<298>().valid(); }
+  ::protozero::ConstBytes kfree() const { return at<298>().as_bytes(); }
+  bool has_kmalloc() const { return at<299>().valid(); }
+  ::protozero::ConstBytes kmalloc() const { return at<299>().as_bytes(); }
+  bool has_kmalloc_node() const { return at<300>().valid(); }
+  ::protozero::ConstBytes kmalloc_node() const { return at<300>().as_bytes(); }
+  bool has_kmem_cache_alloc() const { return at<301>().valid(); }
+  ::protozero::ConstBytes kmem_cache_alloc() const { return at<301>().as_bytes(); }
+  bool has_kmem_cache_alloc_node() const { return at<302>().valid(); }
+  ::protozero::ConstBytes kmem_cache_alloc_node() const { return at<302>().as_bytes(); }
+  bool has_kmem_cache_free() const { return at<303>().valid(); }
+  ::protozero::ConstBytes kmem_cache_free() const { return at<303>().as_bytes(); }
+  bool has_migrate_pages_end() const { return at<304>().valid(); }
+  ::protozero::ConstBytes migrate_pages_end() const { return at<304>().as_bytes(); }
+  bool has_migrate_pages_start() const { return at<305>().valid(); }
+  ::protozero::ConstBytes migrate_pages_start() const { return at<305>().as_bytes(); }
+  bool has_migrate_retry() const { return at<306>().valid(); }
+  ::protozero::ConstBytes migrate_retry() const { return at<306>().as_bytes(); }
+  bool has_mm_page_alloc() const { return at<307>().valid(); }
+  ::protozero::ConstBytes mm_page_alloc() const { return at<307>().as_bytes(); }
+  bool has_mm_page_alloc_extfrag() const { return at<308>().valid(); }
+  ::protozero::ConstBytes mm_page_alloc_extfrag() const { return at<308>().as_bytes(); }
+  bool has_mm_page_alloc_zone_locked() const { return at<309>().valid(); }
+  ::protozero::ConstBytes mm_page_alloc_zone_locked() const { return at<309>().as_bytes(); }
+  bool has_mm_page_free() const { return at<310>().valid(); }
+  ::protozero::ConstBytes mm_page_free() const { return at<310>().as_bytes(); }
+  bool has_mm_page_free_batched() const { return at<311>().valid(); }
+  ::protozero::ConstBytes mm_page_free_batched() const { return at<311>().as_bytes(); }
+  bool has_mm_page_pcpu_drain() const { return at<312>().valid(); }
+  ::protozero::ConstBytes mm_page_pcpu_drain() const { return at<312>().as_bytes(); }
+  bool has_rss_stat() const { return at<313>().valid(); }
+  ::protozero::ConstBytes rss_stat() const { return at<313>().as_bytes(); }
+  bool has_ion_heap_shrink() const { return at<314>().valid(); }
+  ::protozero::ConstBytes ion_heap_shrink() const { return at<314>().as_bytes(); }
+  bool has_ion_heap_grow() const { return at<315>().valid(); }
+  ::protozero::ConstBytes ion_heap_grow() const { return at<315>().as_bytes(); }
+  bool has_fence_init() const { return at<316>().valid(); }
+  ::protozero::ConstBytes fence_init() const { return at<316>().as_bytes(); }
+  bool has_fence_destroy() const { return at<317>().valid(); }
+  ::protozero::ConstBytes fence_destroy() const { return at<317>().as_bytes(); }
+  bool has_fence_enable_signal() const { return at<318>().valid(); }
+  ::protozero::ConstBytes fence_enable_signal() const { return at<318>().as_bytes(); }
+  bool has_fence_signaled() const { return at<319>().valid(); }
+  ::protozero::ConstBytes fence_signaled() const { return at<319>().as_bytes(); }
+  bool has_clk_enable() const { return at<320>().valid(); }
+  ::protozero::ConstBytes clk_enable() const { return at<320>().as_bytes(); }
+  bool has_clk_disable() const { return at<321>().valid(); }
+  ::protozero::ConstBytes clk_disable() const { return at<321>().as_bytes(); }
+  bool has_clk_set_rate() const { return at<322>().valid(); }
+  ::protozero::ConstBytes clk_set_rate() const { return at<322>().as_bytes(); }
+  bool has_binder_transaction_alloc_buf() const { return at<323>().valid(); }
+  ::protozero::ConstBytes binder_transaction_alloc_buf() const { return at<323>().as_bytes(); }
+  bool has_signal_deliver() const { return at<324>().valid(); }
+  ::protozero::ConstBytes signal_deliver() const { return at<324>().as_bytes(); }
+  bool has_signal_generate() const { return at<325>().valid(); }
+  ::protozero::ConstBytes signal_generate() const { return at<325>().as_bytes(); }
+  bool has_oom_score_adj_update() const { return at<326>().valid(); }
+  ::protozero::ConstBytes oom_score_adj_update() const { return at<326>().as_bytes(); }
+  bool has_generic() const { return at<327>().valid(); }
+  ::protozero::ConstBytes generic() const { return at<327>().as_bytes(); }
+  bool has_mm_event_record() const { return at<328>().valid(); }
+  ::protozero::ConstBytes mm_event_record() const { return at<328>().as_bytes(); }
+  bool has_sys_enter() const { return at<329>().valid(); }
+  ::protozero::ConstBytes sys_enter() const { return at<329>().as_bytes(); }
+  bool has_sys_exit() const { return at<330>().valid(); }
+  ::protozero::ConstBytes sys_exit() const { return at<330>().as_bytes(); }
+  bool has_zero() const { return at<331>().valid(); }
+  ::protozero::ConstBytes zero() const { return at<331>().as_bytes(); }
+  bool has_gpu_frequency() const { return at<332>().valid(); }
+  ::protozero::ConstBytes gpu_frequency() const { return at<332>().as_bytes(); }
+  bool has_sde_tracing_mark_write() const { return at<333>().valid(); }
+  ::protozero::ConstBytes sde_tracing_mark_write() const { return at<333>().as_bytes(); }
+  bool has_mark_victim() const { return at<334>().valid(); }
+  ::protozero::ConstBytes mark_victim() const { return at<334>().as_bytes(); }
+  bool has_ion_stat() const { return at<335>().valid(); }
+  ::protozero::ConstBytes ion_stat() const { return at<335>().as_bytes(); }
+  bool has_ion_buffer_create() const { return at<336>().valid(); }
+  ::protozero::ConstBytes ion_buffer_create() const { return at<336>().as_bytes(); }
+  bool has_ion_buffer_destroy() const { return at<337>().valid(); }
+  ::protozero::ConstBytes ion_buffer_destroy() const { return at<337>().as_bytes(); }
+  bool has_scm_call_start() const { return at<338>().valid(); }
+  ::protozero::ConstBytes scm_call_start() const { return at<338>().as_bytes(); }
+  bool has_scm_call_end() const { return at<339>().valid(); }
+  ::protozero::ConstBytes scm_call_end() const { return at<339>().as_bytes(); }
+  bool has_gpu_mem_total() const { return at<340>().valid(); }
+  ::protozero::ConstBytes gpu_mem_total() const { return at<340>().as_bytes(); }
+  bool has_thermal_temperature() const { return at<341>().valid(); }
+  ::protozero::ConstBytes thermal_temperature() const { return at<341>().as_bytes(); }
+  bool has_cdev_update() const { return at<342>().valid(); }
+  ::protozero::ConstBytes cdev_update() const { return at<342>().as_bytes(); }
+  bool has_cpuhp_exit() const { return at<343>().valid(); }
+  ::protozero::ConstBytes cpuhp_exit() const { return at<343>().as_bytes(); }
+  bool has_cpuhp_multi_enter() const { return at<344>().valid(); }
+  ::protozero::ConstBytes cpuhp_multi_enter() const { return at<344>().as_bytes(); }
+  bool has_cpuhp_enter() const { return at<345>().valid(); }
+  ::protozero::ConstBytes cpuhp_enter() const { return at<345>().as_bytes(); }
+  bool has_cpuhp_latency() const { return at<346>().valid(); }
+  ::protozero::ConstBytes cpuhp_latency() const { return at<346>().as_bytes(); }
+  bool has_fastrpc_dma_stat() const { return at<347>().valid(); }
+  ::protozero::ConstBytes fastrpc_dma_stat() const { return at<347>().as_bytes(); }
+  bool has_dpu_tracing_mark_write() const { return at<348>().valid(); }
+  ::protozero::ConstBytes dpu_tracing_mark_write() const { return at<348>().as_bytes(); }
+  bool has_g2d_tracing_mark_write() const { return at<349>().valid(); }
+  ::protozero::ConstBytes g2d_tracing_mark_write() const { return at<349>().as_bytes(); }
+  bool has_mali_tracing_mark_write() const { return at<350>().valid(); }
+  ::protozero::ConstBytes mali_tracing_mark_write() const { return at<350>().as_bytes(); }
+  bool has_dma_heap_stat() const { return at<351>().valid(); }
+  ::protozero::ConstBytes dma_heap_stat() const { return at<351>().as_bytes(); }
+  bool has_cpuhp_pause() const { return at<352>().valid(); }
+  ::protozero::ConstBytes cpuhp_pause() const { return at<352>().as_bytes(); }
+  bool has_sched_pi_setprio() const { return at<353>().valid(); }
+  ::protozero::ConstBytes sched_pi_setprio() const { return at<353>().as_bytes(); }
+  bool has_sde_sde_evtlog() const { return at<354>().valid(); }
+  ::protozero::ConstBytes sde_sde_evtlog() const { return at<354>().as_bytes(); }
+  bool has_sde_sde_perf_calc_crtc() const { return at<355>().valid(); }
+  ::protozero::ConstBytes sde_sde_perf_calc_crtc() const { return at<355>().as_bytes(); }
+  bool has_sde_sde_perf_crtc_update() const { return at<356>().valid(); }
+  ::protozero::ConstBytes sde_sde_perf_crtc_update() const { return at<356>().as_bytes(); }
+  bool has_sde_sde_perf_set_qos_luts() const { return at<357>().valid(); }
+  ::protozero::ConstBytes sde_sde_perf_set_qos_luts() const { return at<357>().as_bytes(); }
+  bool has_sde_sde_perf_update_bus() const { return at<358>().valid(); }
+  ::protozero::ConstBytes sde_sde_perf_update_bus() const { return at<358>().as_bytes(); }
+  bool has_rss_stat_throttled() const { return at<359>().valid(); }
+  ::protozero::ConstBytes rss_stat_throttled() const { return at<359>().as_bytes(); }
+  bool has_netif_receive_skb() const { return at<360>().valid(); }
+  ::protozero::ConstBytes netif_receive_skb() const { return at<360>().as_bytes(); }
+  bool has_net_dev_xmit() const { return at<361>().valid(); }
+  ::protozero::ConstBytes net_dev_xmit() const { return at<361>().as_bytes(); }
+  bool has_inet_sock_set_state() const { return at<362>().valid(); }
+  ::protozero::ConstBytes inet_sock_set_state() const { return at<362>().as_bytes(); }
+  bool has_tcp_retransmit_skb() const { return at<363>().valid(); }
+  ::protozero::ConstBytes tcp_retransmit_skb() const { return at<363>().as_bytes(); }
+  bool has_cros_ec_sensorhub_data() const { return at<364>().valid(); }
+  ::protozero::ConstBytes cros_ec_sensorhub_data() const { return at<364>().as_bytes(); }
+  bool has_napi_gro_receive_entry() const { return at<365>().valid(); }
+  ::protozero::ConstBytes napi_gro_receive_entry() const { return at<365>().as_bytes(); }
+  bool has_napi_gro_receive_exit() const { return at<366>().valid(); }
+  ::protozero::ConstBytes napi_gro_receive_exit() const { return at<366>().as_bytes(); }
+  bool has_kfree_skb() const { return at<367>().valid(); }
+  ::protozero::ConstBytes kfree_skb() const { return at<367>().as_bytes(); }
+  bool has_kvm_access_fault() const { return at<368>().valid(); }
+  ::protozero::ConstBytes kvm_access_fault() const { return at<368>().as_bytes(); }
+  bool has_kvm_ack_irq() const { return at<369>().valid(); }
+  ::protozero::ConstBytes kvm_ack_irq() const { return at<369>().as_bytes(); }
+  bool has_kvm_age_hva() const { return at<370>().valid(); }
+  ::protozero::ConstBytes kvm_age_hva() const { return at<370>().as_bytes(); }
+  bool has_kvm_age_page() const { return at<371>().valid(); }
+  ::protozero::ConstBytes kvm_age_page() const { return at<371>().as_bytes(); }
+  bool has_kvm_arm_clear_debug() const { return at<372>().valid(); }
+  ::protozero::ConstBytes kvm_arm_clear_debug() const { return at<372>().as_bytes(); }
+  bool has_kvm_arm_set_dreg32() const { return at<373>().valid(); }
+  ::protozero::ConstBytes kvm_arm_set_dreg32() const { return at<373>().as_bytes(); }
+  bool has_kvm_arm_set_regset() const { return at<374>().valid(); }
+  ::protozero::ConstBytes kvm_arm_set_regset() const { return at<374>().as_bytes(); }
+  bool has_kvm_arm_setup_debug() const { return at<375>().valid(); }
+  ::protozero::ConstBytes kvm_arm_setup_debug() const { return at<375>().as_bytes(); }
+  bool has_kvm_entry() const { return at<376>().valid(); }
+  ::protozero::ConstBytes kvm_entry() const { return at<376>().as_bytes(); }
+  bool has_kvm_exit() const { return at<377>().valid(); }
+  ::protozero::ConstBytes kvm_exit() const { return at<377>().as_bytes(); }
+  bool has_kvm_fpu() const { return at<378>().valid(); }
+  ::protozero::ConstBytes kvm_fpu() const { return at<378>().as_bytes(); }
+  bool has_kvm_get_timer_map() const { return at<379>().valid(); }
+  ::protozero::ConstBytes kvm_get_timer_map() const { return at<379>().as_bytes(); }
+  bool has_kvm_guest_fault() const { return at<380>().valid(); }
+  ::protozero::ConstBytes kvm_guest_fault() const { return at<380>().as_bytes(); }
+  bool has_kvm_handle_sys_reg() const { return at<381>().valid(); }
+  ::protozero::ConstBytes kvm_handle_sys_reg() const { return at<381>().as_bytes(); }
+  bool has_kvm_hvc_arm64() const { return at<382>().valid(); }
+  ::protozero::ConstBytes kvm_hvc_arm64() const { return at<382>().as_bytes(); }
+  bool has_kvm_irq_line() const { return at<383>().valid(); }
+  ::protozero::ConstBytes kvm_irq_line() const { return at<383>().as_bytes(); }
+  bool has_kvm_mmio() const { return at<384>().valid(); }
+  ::protozero::ConstBytes kvm_mmio() const { return at<384>().as_bytes(); }
+  bool has_kvm_mmio_emulate() const { return at<385>().valid(); }
+  ::protozero::ConstBytes kvm_mmio_emulate() const { return at<385>().as_bytes(); }
+  bool has_kvm_set_guest_debug() const { return at<386>().valid(); }
+  ::protozero::ConstBytes kvm_set_guest_debug() const { return at<386>().as_bytes(); }
+  bool has_kvm_set_irq() const { return at<387>().valid(); }
+  ::protozero::ConstBytes kvm_set_irq() const { return at<387>().as_bytes(); }
+  bool has_kvm_set_spte_hva() const { return at<388>().valid(); }
+  ::protozero::ConstBytes kvm_set_spte_hva() const { return at<388>().as_bytes(); }
+  bool has_kvm_set_way_flush() const { return at<389>().valid(); }
+  ::protozero::ConstBytes kvm_set_way_flush() const { return at<389>().as_bytes(); }
+  bool has_kvm_sys_access() const { return at<390>().valid(); }
+  ::protozero::ConstBytes kvm_sys_access() const { return at<390>().as_bytes(); }
+  bool has_kvm_test_age_hva() const { return at<391>().valid(); }
+  ::protozero::ConstBytes kvm_test_age_hva() const { return at<391>().as_bytes(); }
+  bool has_kvm_timer_emulate() const { return at<392>().valid(); }
+  ::protozero::ConstBytes kvm_timer_emulate() const { return at<392>().as_bytes(); }
+  bool has_kvm_timer_hrtimer_expire() const { return at<393>().valid(); }
+  ::protozero::ConstBytes kvm_timer_hrtimer_expire() const { return at<393>().as_bytes(); }
+  bool has_kvm_timer_restore_state() const { return at<394>().valid(); }
+  ::protozero::ConstBytes kvm_timer_restore_state() const { return at<394>().as_bytes(); }
+  bool has_kvm_timer_save_state() const { return at<395>().valid(); }
+  ::protozero::ConstBytes kvm_timer_save_state() const { return at<395>().as_bytes(); }
+  bool has_kvm_timer_update_irq() const { return at<396>().valid(); }
+  ::protozero::ConstBytes kvm_timer_update_irq() const { return at<396>().as_bytes(); }
+  bool has_kvm_toggle_cache() const { return at<397>().valid(); }
+  ::protozero::ConstBytes kvm_toggle_cache() const { return at<397>().as_bytes(); }
+  bool has_kvm_unmap_hva_range() const { return at<398>().valid(); }
+  ::protozero::ConstBytes kvm_unmap_hva_range() const { return at<398>().as_bytes(); }
+  bool has_kvm_userspace_exit() const { return at<399>().valid(); }
+  ::protozero::ConstBytes kvm_userspace_exit() const { return at<399>().as_bytes(); }
+  bool has_kvm_vcpu_wakeup() const { return at<400>().valid(); }
+  ::protozero::ConstBytes kvm_vcpu_wakeup() const { return at<400>().as_bytes(); }
+  bool has_kvm_wfx_arm64() const { return at<401>().valid(); }
+  ::protozero::ConstBytes kvm_wfx_arm64() const { return at<401>().as_bytes(); }
+  bool has_trap_reg() const { return at<402>().valid(); }
+  ::protozero::ConstBytes trap_reg() const { return at<402>().as_bytes(); }
+  bool has_vgic_update_irq_pending() const { return at<403>().valid(); }
+  ::protozero::ConstBytes vgic_update_irq_pending() const { return at<403>().as_bytes(); }
+  bool has_wakeup_source_activate() const { return at<404>().valid(); }
+  ::protozero::ConstBytes wakeup_source_activate() const { return at<404>().as_bytes(); }
+  bool has_wakeup_source_deactivate() const { return at<405>().valid(); }
+  ::protozero::ConstBytes wakeup_source_deactivate() const { return at<405>().as_bytes(); }
+  bool has_ufshcd_command() const { return at<406>().valid(); }
+  ::protozero::ConstBytes ufshcd_command() const { return at<406>().as_bytes(); }
+  bool has_ufshcd_clk_gating() const { return at<407>().valid(); }
+  ::protozero::ConstBytes ufshcd_clk_gating() const { return at<407>().as_bytes(); }
+  bool has_console() const { return at<408>().valid(); }
+  ::protozero::ConstBytes console() const { return at<408>().as_bytes(); }
+  bool has_drm_vblank_event() const { return at<409>().valid(); }
+  ::protozero::ConstBytes drm_vblank_event() const { return at<409>().as_bytes(); }
+  bool has_drm_vblank_event_delivered() const { return at<410>().valid(); }
+  ::protozero::ConstBytes drm_vblank_event_delivered() const { return at<410>().as_bytes(); }
+  bool has_drm_sched_job() const { return at<411>().valid(); }
+  ::protozero::ConstBytes drm_sched_job() const { return at<411>().as_bytes(); }
+  bool has_drm_run_job() const { return at<412>().valid(); }
+  ::protozero::ConstBytes drm_run_job() const { return at<412>().as_bytes(); }
+  bool has_drm_sched_process_job() const { return at<413>().valid(); }
+  ::protozero::ConstBytes drm_sched_process_job() const { return at<413>().as_bytes(); }
+  bool has_dma_fence_init() const { return at<414>().valid(); }
+  ::protozero::ConstBytes dma_fence_init() const { return at<414>().as_bytes(); }
+  bool has_dma_fence_emit() const { return at<415>().valid(); }
+  ::protozero::ConstBytes dma_fence_emit() const { return at<415>().as_bytes(); }
+  bool has_dma_fence_signaled() const { return at<416>().valid(); }
+  ::protozero::ConstBytes dma_fence_signaled() const { return at<416>().as_bytes(); }
+  bool has_dma_fence_wait_start() const { return at<417>().valid(); }
+  ::protozero::ConstBytes dma_fence_wait_start() const { return at<417>().as_bytes(); }
+  bool has_dma_fence_wait_end() const { return at<418>().valid(); }
+  ::protozero::ConstBytes dma_fence_wait_end() const { return at<418>().as_bytes(); }
+  bool has_f2fs_iostat() const { return at<419>().valid(); }
+  ::protozero::ConstBytes f2fs_iostat() const { return at<419>().as_bytes(); }
+  bool has_f2fs_iostat_latency() const { return at<420>().valid(); }
+  ::protozero::ConstBytes f2fs_iostat_latency() const { return at<420>().as_bytes(); }
+  bool has_sched_cpu_util_cfs() const { return at<421>().valid(); }
+  ::protozero::ConstBytes sched_cpu_util_cfs() const { return at<421>().as_bytes(); }
+  bool has_v4l2_qbuf() const { return at<422>().valid(); }
+  ::protozero::ConstBytes v4l2_qbuf() const { return at<422>().as_bytes(); }
+  bool has_v4l2_dqbuf() const { return at<423>().valid(); }
+  ::protozero::ConstBytes v4l2_dqbuf() const { return at<423>().as_bytes(); }
+  bool has_vb2_v4l2_buf_queue() const { return at<424>().valid(); }
+  ::protozero::ConstBytes vb2_v4l2_buf_queue() const { return at<424>().as_bytes(); }
+  bool has_vb2_v4l2_buf_done() const { return at<425>().valid(); }
+  ::protozero::ConstBytes vb2_v4l2_buf_done() const { return at<425>().as_bytes(); }
+  bool has_vb2_v4l2_qbuf() const { return at<426>().valid(); }
+  ::protozero::ConstBytes vb2_v4l2_qbuf() const { return at<426>().as_bytes(); }
+  bool has_vb2_v4l2_dqbuf() const { return at<427>().valid(); }
+  ::protozero::ConstBytes vb2_v4l2_dqbuf() const { return at<427>().as_bytes(); }
+  bool has_dsi_cmd_fifo_status() const { return at<428>().valid(); }
+  ::protozero::ConstBytes dsi_cmd_fifo_status() const { return at<428>().as_bytes(); }
+  bool has_dsi_rx() const { return at<429>().valid(); }
+  ::protozero::ConstBytes dsi_rx() const { return at<429>().as_bytes(); }
+  bool has_dsi_tx() const { return at<430>().valid(); }
+  ::protozero::ConstBytes dsi_tx() const { return at<430>().as_bytes(); }
+  bool has_android_fs_dataread_end() const { return at<431>().valid(); }
+  ::protozero::ConstBytes android_fs_dataread_end() const { return at<431>().as_bytes(); }
+  bool has_android_fs_dataread_start() const { return at<432>().valid(); }
+  ::protozero::ConstBytes android_fs_dataread_start() const { return at<432>().as_bytes(); }
+  bool has_android_fs_datawrite_end() const { return at<433>().valid(); }
+  ::protozero::ConstBytes android_fs_datawrite_end() const { return at<433>().as_bytes(); }
+  bool has_android_fs_datawrite_start() const { return at<434>().valid(); }
+  ::protozero::ConstBytes android_fs_datawrite_start() const { return at<434>().as_bytes(); }
+  bool has_android_fs_fsync_end() const { return at<435>().valid(); }
+  ::protozero::ConstBytes android_fs_fsync_end() const { return at<435>().as_bytes(); }
+  bool has_android_fs_fsync_start() const { return at<436>().valid(); }
+  ::protozero::ConstBytes android_fs_fsync_start() const { return at<436>().as_bytes(); }
+  bool has_funcgraph_entry() const { return at<437>().valid(); }
+  ::protozero::ConstBytes funcgraph_entry() const { return at<437>().as_bytes(); }
+  bool has_funcgraph_exit() const { return at<438>().valid(); }
+  ::protozero::ConstBytes funcgraph_exit() const { return at<438>().as_bytes(); }
+  bool has_virtio_video_cmd() const { return at<439>().valid(); }
+  ::protozero::ConstBytes virtio_video_cmd() const { return at<439>().as_bytes(); }
+  bool has_virtio_video_cmd_done() const { return at<440>().valid(); }
+  ::protozero::ConstBytes virtio_video_cmd_done() const { return at<440>().as_bytes(); }
+  bool has_virtio_video_resource_queue() const { return at<441>().valid(); }
+  ::protozero::ConstBytes virtio_video_resource_queue() const { return at<441>().as_bytes(); }
+  bool has_virtio_video_resource_queue_done() const { return at<442>().valid(); }
+  ::protozero::ConstBytes virtio_video_resource_queue_done() const { return at<442>().as_bytes(); }
+  bool has_mm_shrink_slab_start() const { return at<443>().valid(); }
+  ::protozero::ConstBytes mm_shrink_slab_start() const { return at<443>().as_bytes(); }
+  bool has_mm_shrink_slab_end() const { return at<444>().valid(); }
+  ::protozero::ConstBytes mm_shrink_slab_end() const { return at<444>().as_bytes(); }
+  bool has_trusty_smc() const { return at<445>().valid(); }
+  ::protozero::ConstBytes trusty_smc() const { return at<445>().as_bytes(); }
+  bool has_trusty_smc_done() const { return at<446>().valid(); }
+  ::protozero::ConstBytes trusty_smc_done() const { return at<446>().as_bytes(); }
+  bool has_trusty_std_call32() const { return at<447>().valid(); }
+  ::protozero::ConstBytes trusty_std_call32() const { return at<447>().as_bytes(); }
+  bool has_trusty_std_call32_done() const { return at<448>().valid(); }
+  ::protozero::ConstBytes trusty_std_call32_done() const { return at<448>().as_bytes(); }
+  bool has_trusty_share_memory() const { return at<449>().valid(); }
+  ::protozero::ConstBytes trusty_share_memory() const { return at<449>().as_bytes(); }
+  bool has_trusty_share_memory_done() const { return at<450>().valid(); }
+  ::protozero::ConstBytes trusty_share_memory_done() const { return at<450>().as_bytes(); }
+  bool has_trusty_reclaim_memory() const { return at<451>().valid(); }
+  ::protozero::ConstBytes trusty_reclaim_memory() const { return at<451>().as_bytes(); }
+  bool has_trusty_reclaim_memory_done() const { return at<452>().valid(); }
+  ::protozero::ConstBytes trusty_reclaim_memory_done() const { return at<452>().as_bytes(); }
+  bool has_trusty_irq() const { return at<453>().valid(); }
+  ::protozero::ConstBytes trusty_irq() const { return at<453>().as_bytes(); }
+  bool has_trusty_ipc_handle_event() const { return at<454>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_handle_event() const { return at<454>().as_bytes(); }
+  bool has_trusty_ipc_connect() const { return at<455>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_connect() const { return at<455>().as_bytes(); }
+  bool has_trusty_ipc_connect_end() const { return at<456>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_connect_end() const { return at<456>().as_bytes(); }
+  bool has_trusty_ipc_write() const { return at<457>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_write() const { return at<457>().as_bytes(); }
+  bool has_trusty_ipc_poll() const { return at<458>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_poll() const { return at<458>().as_bytes(); }
+  bool has_trusty_ipc_read() const { return at<460>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_read() const { return at<460>().as_bytes(); }
+  bool has_trusty_ipc_read_end() const { return at<461>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_read_end() const { return at<461>().as_bytes(); }
+  bool has_trusty_ipc_rx() const { return at<462>().valid(); }
+  ::protozero::ConstBytes trusty_ipc_rx() const { return at<462>().as_bytes(); }
+  bool has_trusty_enqueue_nop() const { return at<464>().valid(); }
+  ::protozero::ConstBytes trusty_enqueue_nop() const { return at<464>().as_bytes(); }
+  bool has_cma_alloc_start() const { return at<465>().valid(); }
+  ::protozero::ConstBytes cma_alloc_start() const { return at<465>().as_bytes(); }
+  bool has_cma_alloc_info() const { return at<466>().valid(); }
+  ::protozero::ConstBytes cma_alloc_info() const { return at<466>().as_bytes(); }
+  bool has_lwis_tracing_mark_write() const { return at<467>().valid(); }
+  ::protozero::ConstBytes lwis_tracing_mark_write() const { return at<467>().as_bytes(); }
+  bool has_virtio_gpu_cmd_queue() const { return at<468>().valid(); }
+  ::protozero::ConstBytes virtio_gpu_cmd_queue() const { return at<468>().as_bytes(); }
+  bool has_virtio_gpu_cmd_response() const { return at<469>().valid(); }
+  ::protozero::ConstBytes virtio_gpu_cmd_response() const { return at<469>().as_bytes(); }
+  bool has_mali_mali_kcpu_cqs_set() const { return at<470>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_cqs_set() const { return at<470>().as_bytes(); }
+  bool has_mali_mali_kcpu_cqs_wait_start() const { return at<471>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_cqs_wait_start() const { return at<471>().as_bytes(); }
+  bool has_mali_mali_kcpu_cqs_wait_end() const { return at<472>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_cqs_wait_end() const { return at<472>().as_bytes(); }
+  bool has_mali_mali_kcpu_fence_signal() const { return at<473>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_fence_signal() const { return at<473>().as_bytes(); }
+  bool has_mali_mali_kcpu_fence_wait_start() const { return at<474>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_fence_wait_start() const { return at<474>().as_bytes(); }
+  bool has_mali_mali_kcpu_fence_wait_end() const { return at<475>().valid(); }
+  ::protozero::ConstBytes mali_mali_kcpu_fence_wait_end() const { return at<475>().as_bytes(); }
+  bool has_hyp_enter() const { return at<476>().valid(); }
+  ::protozero::ConstBytes hyp_enter() const { return at<476>().as_bytes(); }
+  bool has_hyp_exit() const { return at<477>().valid(); }
+  ::protozero::ConstBytes hyp_exit() const { return at<477>().as_bytes(); }
+  bool has_host_hcall() const { return at<478>().valid(); }
+  ::protozero::ConstBytes host_hcall() const { return at<478>().as_bytes(); }
+  bool has_host_smc() const { return at<479>().valid(); }
+  ::protozero::ConstBytes host_smc() const { return at<479>().as_bytes(); }
+  bool has_host_mem_abort() const { return at<480>().valid(); }
+  ::protozero::ConstBytes host_mem_abort() const { return at<480>().as_bytes(); }
+  bool has_suspend_resume_minimal() const { return at<481>().valid(); }
+  ::protozero::ConstBytes suspend_resume_minimal() const { return at<481>().as_bytes(); }
+  bool has_mali_mali_csf_interrupt_start() const { return at<482>().valid(); }
+  ::protozero::ConstBytes mali_mali_csf_interrupt_start() const { return at<482>().as_bytes(); }
+  bool has_mali_mali_csf_interrupt_end() const { return at<483>().valid(); }
+  ::protozero::ConstBytes mali_mali_csf_interrupt_end() const { return at<483>().as_bytes(); }
+  bool has_samsung_tracing_mark_write() const { return at<484>().valid(); }
+  ::protozero::ConstBytes samsung_tracing_mark_write() const { return at<484>().as_bytes(); }
+  bool has_binder_command() const { return at<485>().valid(); }
+  ::protozero::ConstBytes binder_command() const { return at<485>().as_bytes(); }
+  bool has_binder_return() const { return at<486>().valid(); }
+  ::protozero::ConstBytes binder_return() const { return at<486>().as_bytes(); }
+  bool has_sched_switch_with_ctrs() const { return at<487>().valid(); }
+  ::protozero::ConstBytes sched_switch_with_ctrs() const { return at<487>().as_bytes(); }
+  bool has_gpu_work_period() const { return at<488>().valid(); }
+  ::protozero::ConstBytes gpu_work_period() const { return at<488>().as_bytes(); }
+};
+
+class FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FtraceEvent_Decoder;
+  enum : int32_t {
+    kTimestampFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kCommonFlagsFieldNumber = 5,
+    kPrintFieldNumber = 3,
+    kSchedSwitchFieldNumber = 4,
+    kCpuFrequencyFieldNumber = 11,
+    kCpuFrequencyLimitsFieldNumber = 12,
+    kCpuIdleFieldNumber = 13,
+    kClockEnableFieldNumber = 14,
+    kClockDisableFieldNumber = 15,
+    kClockSetRateFieldNumber = 16,
+    kSchedWakeupFieldNumber = 17,
+    kSchedBlockedReasonFieldNumber = 18,
+    kSchedCpuHotplugFieldNumber = 19,
+    kSchedWakingFieldNumber = 20,
+    kIpiEntryFieldNumber = 21,
+    kIpiExitFieldNumber = 22,
+    kIpiRaiseFieldNumber = 23,
+    kSoftirqEntryFieldNumber = 24,
+    kSoftirqExitFieldNumber = 25,
+    kSoftirqRaiseFieldNumber = 26,
+    kI2cReadFieldNumber = 27,
+    kI2cWriteFieldNumber = 28,
+    kI2cResultFieldNumber = 29,
+    kI2cReplyFieldNumber = 30,
+    kSmbusReadFieldNumber = 31,
+    kSmbusWriteFieldNumber = 32,
+    kSmbusResultFieldNumber = 33,
+    kSmbusReplyFieldNumber = 34,
+    kLowmemoryKillFieldNumber = 35,
+    kIrqHandlerEntryFieldNumber = 36,
+    kIrqHandlerExitFieldNumber = 37,
+    kSyncPtFieldNumber = 38,
+    kSyncTimelineFieldNumber = 39,
+    kSyncWaitFieldNumber = 40,
+    kExt4DaWriteBeginFieldNumber = 41,
+    kExt4DaWriteEndFieldNumber = 42,
+    kExt4SyncFileEnterFieldNumber = 43,
+    kExt4SyncFileExitFieldNumber = 44,
+    kBlockRqIssueFieldNumber = 45,
+    kMmVmscanDirectReclaimBeginFieldNumber = 46,
+    kMmVmscanDirectReclaimEndFieldNumber = 47,
+    kMmVmscanKswapdWakeFieldNumber = 48,
+    kMmVmscanKswapdSleepFieldNumber = 49,
+    kBinderTransactionFieldNumber = 50,
+    kBinderTransactionReceivedFieldNumber = 51,
+    kBinderSetPriorityFieldNumber = 52,
+    kBinderLockFieldNumber = 53,
+    kBinderLockedFieldNumber = 54,
+    kBinderUnlockFieldNumber = 55,
+    kWorkqueueActivateWorkFieldNumber = 56,
+    kWorkqueueExecuteEndFieldNumber = 57,
+    kWorkqueueExecuteStartFieldNumber = 58,
+    kWorkqueueQueueWorkFieldNumber = 59,
+    kRegulatorDisableFieldNumber = 60,
+    kRegulatorDisableCompleteFieldNumber = 61,
+    kRegulatorEnableFieldNumber = 62,
+    kRegulatorEnableCompleteFieldNumber = 63,
+    kRegulatorEnableDelayFieldNumber = 64,
+    kRegulatorSetVoltageFieldNumber = 65,
+    kRegulatorSetVoltageCompleteFieldNumber = 66,
+    kCgroupAttachTaskFieldNumber = 67,
+    kCgroupMkdirFieldNumber = 68,
+    kCgroupRemountFieldNumber = 69,
+    kCgroupRmdirFieldNumber = 70,
+    kCgroupTransferTasksFieldNumber = 71,
+    kCgroupDestroyRootFieldNumber = 72,
+    kCgroupReleaseFieldNumber = 73,
+    kCgroupRenameFieldNumber = 74,
+    kCgroupSetupRootFieldNumber = 75,
+    kMdpCmdKickoffFieldNumber = 76,
+    kMdpCommitFieldNumber = 77,
+    kMdpPerfSetOtFieldNumber = 78,
+    kMdpSsppChangeFieldNumber = 79,
+    kTracingMarkWriteFieldNumber = 80,
+    kMdpCmdPingpongDoneFieldNumber = 81,
+    kMdpCompareBwFieldNumber = 82,
+    kMdpPerfSetPanicLutsFieldNumber = 83,
+    kMdpSsppSetFieldNumber = 84,
+    kMdpCmdReadptrDoneFieldNumber = 85,
+    kMdpMisrCrcFieldNumber = 86,
+    kMdpPerfSetQosLutsFieldNumber = 87,
+    kMdpTraceCounterFieldNumber = 88,
+    kMdpCmdReleaseBwFieldNumber = 89,
+    kMdpMixerUpdateFieldNumber = 90,
+    kMdpPerfSetWmLevelsFieldNumber = 91,
+    kMdpVideoUnderrunDoneFieldNumber = 92,
+    kMdpCmdWaitPingpongFieldNumber = 93,
+    kMdpPerfPrefillCalcFieldNumber = 94,
+    kMdpPerfUpdateBusFieldNumber = 95,
+    kRotatorBwAoAsContextFieldNumber = 96,
+    kMmFilemapAddToPageCacheFieldNumber = 97,
+    kMmFilemapDeleteFromPageCacheFieldNumber = 98,
+    kMmCompactionBeginFieldNumber = 99,
+    kMmCompactionDeferCompactionFieldNumber = 100,
+    kMmCompactionDeferredFieldNumber = 101,
+    kMmCompactionDeferResetFieldNumber = 102,
+    kMmCompactionEndFieldNumber = 103,
+    kMmCompactionFinishedFieldNumber = 104,
+    kMmCompactionIsolateFreepagesFieldNumber = 105,
+    kMmCompactionIsolateMigratepagesFieldNumber = 106,
+    kMmCompactionKcompactdSleepFieldNumber = 107,
+    kMmCompactionKcompactdWakeFieldNumber = 108,
+    kMmCompactionMigratepagesFieldNumber = 109,
+    kMmCompactionSuitableFieldNumber = 110,
+    kMmCompactionTryToCompactPagesFieldNumber = 111,
+    kMmCompactionWakeupKcompactdFieldNumber = 112,
+    kSuspendResumeFieldNumber = 113,
+    kSchedWakeupNewFieldNumber = 114,
+    kBlockBioBackmergeFieldNumber = 115,
+    kBlockBioBounceFieldNumber = 116,
+    kBlockBioCompleteFieldNumber = 117,
+    kBlockBioFrontmergeFieldNumber = 118,
+    kBlockBioQueueFieldNumber = 119,
+    kBlockBioRemapFieldNumber = 120,
+    kBlockDirtyBufferFieldNumber = 121,
+    kBlockGetrqFieldNumber = 122,
+    kBlockPlugFieldNumber = 123,
+    kBlockRqAbortFieldNumber = 124,
+    kBlockRqCompleteFieldNumber = 125,
+    kBlockRqInsertFieldNumber = 126,
+    kBlockRqRemapFieldNumber = 128,
+    kBlockRqRequeueFieldNumber = 129,
+    kBlockSleeprqFieldNumber = 130,
+    kBlockSplitFieldNumber = 131,
+    kBlockTouchBufferFieldNumber = 132,
+    kBlockUnplugFieldNumber = 133,
+    kExt4AllocDaBlocksFieldNumber = 134,
+    kExt4AllocateBlocksFieldNumber = 135,
+    kExt4AllocateInodeFieldNumber = 136,
+    kExt4BeginOrderedTruncateFieldNumber = 137,
+    kExt4CollapseRangeFieldNumber = 138,
+    kExt4DaReleaseSpaceFieldNumber = 139,
+    kExt4DaReserveSpaceFieldNumber = 140,
+    kExt4DaUpdateReserveSpaceFieldNumber = 141,
+    kExt4DaWritePagesFieldNumber = 142,
+    kExt4DaWritePagesExtentFieldNumber = 143,
+    kExt4DirectIOEnterFieldNumber = 144,
+    kExt4DirectIOExitFieldNumber = 145,
+    kExt4DiscardBlocksFieldNumber = 146,
+    kExt4DiscardPreallocationsFieldNumber = 147,
+    kExt4DropInodeFieldNumber = 148,
+    kExt4EsCacheExtentFieldNumber = 149,
+    kExt4EsFindDelayedExtentRangeEnterFieldNumber = 150,
+    kExt4EsFindDelayedExtentRangeExitFieldNumber = 151,
+    kExt4EsInsertExtentFieldNumber = 152,
+    kExt4EsLookupExtentEnterFieldNumber = 153,
+    kExt4EsLookupExtentExitFieldNumber = 154,
+    kExt4EsRemoveExtentFieldNumber = 155,
+    kExt4EsShrinkFieldNumber = 156,
+    kExt4EsShrinkCountFieldNumber = 157,
+    kExt4EsShrinkScanEnterFieldNumber = 158,
+    kExt4EsShrinkScanExitFieldNumber = 159,
+    kExt4EvictInodeFieldNumber = 160,
+    kExt4ExtConvertToInitializedEnterFieldNumber = 161,
+    kExt4ExtConvertToInitializedFastpathFieldNumber = 162,
+    kExt4ExtHandleUnwrittenExtentsFieldNumber = 163,
+    kExt4ExtInCacheFieldNumber = 164,
+    kExt4ExtLoadExtentFieldNumber = 165,
+    kExt4ExtMapBlocksEnterFieldNumber = 166,
+    kExt4ExtMapBlocksExitFieldNumber = 167,
+    kExt4ExtPutInCacheFieldNumber = 168,
+    kExt4ExtRemoveSpaceFieldNumber = 169,
+    kExt4ExtRemoveSpaceDoneFieldNumber = 170,
+    kExt4ExtRmIdxFieldNumber = 171,
+    kExt4ExtRmLeafFieldNumber = 172,
+    kExt4ExtShowExtentFieldNumber = 173,
+    kExt4FallocateEnterFieldNumber = 174,
+    kExt4FallocateExitFieldNumber = 175,
+    kExt4FindDelallocRangeFieldNumber = 176,
+    kExt4ForgetFieldNumber = 177,
+    kExt4FreeBlocksFieldNumber = 178,
+    kExt4FreeInodeFieldNumber = 179,
+    kExt4GetImpliedClusterAllocExitFieldNumber = 180,
+    kExt4GetReservedClusterAllocFieldNumber = 181,
+    kExt4IndMapBlocksEnterFieldNumber = 182,
+    kExt4IndMapBlocksExitFieldNumber = 183,
+    kExt4InsertRangeFieldNumber = 184,
+    kExt4InvalidatepageFieldNumber = 185,
+    kExt4JournalStartFieldNumber = 186,
+    kExt4JournalStartReservedFieldNumber = 187,
+    kExt4JournalledInvalidatepageFieldNumber = 188,
+    kExt4JournalledWriteEndFieldNumber = 189,
+    kExt4LoadInodeFieldNumber = 190,
+    kExt4LoadInodeBitmapFieldNumber = 191,
+    kExt4MarkInodeDirtyFieldNumber = 192,
+    kExt4MbBitmapLoadFieldNumber = 193,
+    kExt4MbBuddyBitmapLoadFieldNumber = 194,
+    kExt4MbDiscardPreallocationsFieldNumber = 195,
+    kExt4MbNewGroupPaFieldNumber = 196,
+    kExt4MbNewInodePaFieldNumber = 197,
+    kExt4MbReleaseGroupPaFieldNumber = 198,
+    kExt4MbReleaseInodePaFieldNumber = 199,
+    kExt4MballocAllocFieldNumber = 200,
+    kExt4MballocDiscardFieldNumber = 201,
+    kExt4MballocFreeFieldNumber = 202,
+    kExt4MballocPreallocFieldNumber = 203,
+    kExt4OtherInodeUpdateTimeFieldNumber = 204,
+    kExt4PunchHoleFieldNumber = 205,
+    kExt4ReadBlockBitmapLoadFieldNumber = 206,
+    kExt4ReadpageFieldNumber = 207,
+    kExt4ReleasepageFieldNumber = 208,
+    kExt4RemoveBlocksFieldNumber = 209,
+    kExt4RequestBlocksFieldNumber = 210,
+    kExt4RequestInodeFieldNumber = 211,
+    kExt4SyncFsFieldNumber = 212,
+    kExt4TrimAllFreeFieldNumber = 213,
+    kExt4TrimExtentFieldNumber = 214,
+    kExt4TruncateEnterFieldNumber = 215,
+    kExt4TruncateExitFieldNumber = 216,
+    kExt4UnlinkEnterFieldNumber = 217,
+    kExt4UnlinkExitFieldNumber = 218,
+    kExt4WriteBeginFieldNumber = 219,
+    kExt4WriteEndFieldNumber = 230,
+    kExt4WritepageFieldNumber = 231,
+    kExt4WritepagesFieldNumber = 232,
+    kExt4WritepagesResultFieldNumber = 233,
+    kExt4ZeroRangeFieldNumber = 234,
+    kTaskNewtaskFieldNumber = 235,
+    kTaskRenameFieldNumber = 236,
+    kSchedProcessExecFieldNumber = 237,
+    kSchedProcessExitFieldNumber = 238,
+    kSchedProcessForkFieldNumber = 239,
+    kSchedProcessFreeFieldNumber = 240,
+    kSchedProcessHangFieldNumber = 241,
+    kSchedProcessWaitFieldNumber = 242,
+    kF2fsDoSubmitBioFieldNumber = 243,
+    kF2fsEvictInodeFieldNumber = 244,
+    kF2fsFallocateFieldNumber = 245,
+    kF2fsGetDataBlockFieldNumber = 246,
+    kF2fsGetVictimFieldNumber = 247,
+    kF2fsIgetFieldNumber = 248,
+    kF2fsIgetExitFieldNumber = 249,
+    kF2fsNewInodeFieldNumber = 250,
+    kF2fsReadpageFieldNumber = 251,
+    kF2fsReserveNewBlockFieldNumber = 252,
+    kF2fsSetPageDirtyFieldNumber = 253,
+    kF2fsSubmitWritePageFieldNumber = 254,
+    kF2fsSyncFileEnterFieldNumber = 255,
+    kF2fsSyncFileExitFieldNumber = 256,
+    kF2fsSyncFsFieldNumber = 257,
+    kF2fsTruncateFieldNumber = 258,
+    kF2fsTruncateBlocksEnterFieldNumber = 259,
+    kF2fsTruncateBlocksExitFieldNumber = 260,
+    kF2fsTruncateDataBlocksRangeFieldNumber = 261,
+    kF2fsTruncateInodeBlocksEnterFieldNumber = 262,
+    kF2fsTruncateInodeBlocksExitFieldNumber = 263,
+    kF2fsTruncateNodeFieldNumber = 264,
+    kF2fsTruncateNodesEnterFieldNumber = 265,
+    kF2fsTruncateNodesExitFieldNumber = 266,
+    kF2fsTruncatePartialNodesFieldNumber = 267,
+    kF2fsUnlinkEnterFieldNumber = 268,
+    kF2fsUnlinkExitFieldNumber = 269,
+    kF2fsVmPageMkwriteFieldNumber = 270,
+    kF2fsWriteBeginFieldNumber = 271,
+    kF2fsWriteCheckpointFieldNumber = 272,
+    kF2fsWriteEndFieldNumber = 273,
+    kAllocPagesIommuEndFieldNumber = 274,
+    kAllocPagesIommuFailFieldNumber = 275,
+    kAllocPagesIommuStartFieldNumber = 276,
+    kAllocPagesSysEndFieldNumber = 277,
+    kAllocPagesSysFailFieldNumber = 278,
+    kAllocPagesSysStartFieldNumber = 279,
+    kDmaAllocContiguousRetryFieldNumber = 280,
+    kIommuMapRangeFieldNumber = 281,
+    kIommuSecPtblMapRangeEndFieldNumber = 282,
+    kIommuSecPtblMapRangeStartFieldNumber = 283,
+    kIonAllocBufferEndFieldNumber = 284,
+    kIonAllocBufferFailFieldNumber = 285,
+    kIonAllocBufferFallbackFieldNumber = 286,
+    kIonAllocBufferStartFieldNumber = 287,
+    kIonCpAllocRetryFieldNumber = 288,
+    kIonCpSecureBufferEndFieldNumber = 289,
+    kIonCpSecureBufferStartFieldNumber = 290,
+    kIonPrefetchingFieldNumber = 291,
+    kIonSecureCmaAddToPoolEndFieldNumber = 292,
+    kIonSecureCmaAddToPoolStartFieldNumber = 293,
+    kIonSecureCmaAllocateEndFieldNumber = 294,
+    kIonSecureCmaAllocateStartFieldNumber = 295,
+    kIonSecureCmaShrinkPoolEndFieldNumber = 296,
+    kIonSecureCmaShrinkPoolStartFieldNumber = 297,
+    kKfreeFieldNumber = 298,
+    kKmallocFieldNumber = 299,
+    kKmallocNodeFieldNumber = 300,
+    kKmemCacheAllocFieldNumber = 301,
+    kKmemCacheAllocNodeFieldNumber = 302,
+    kKmemCacheFreeFieldNumber = 303,
+    kMigratePagesEndFieldNumber = 304,
+    kMigratePagesStartFieldNumber = 305,
+    kMigrateRetryFieldNumber = 306,
+    kMmPageAllocFieldNumber = 307,
+    kMmPageAllocExtfragFieldNumber = 308,
+    kMmPageAllocZoneLockedFieldNumber = 309,
+    kMmPageFreeFieldNumber = 310,
+    kMmPageFreeBatchedFieldNumber = 311,
+    kMmPagePcpuDrainFieldNumber = 312,
+    kRssStatFieldNumber = 313,
+    kIonHeapShrinkFieldNumber = 314,
+    kIonHeapGrowFieldNumber = 315,
+    kFenceInitFieldNumber = 316,
+    kFenceDestroyFieldNumber = 317,
+    kFenceEnableSignalFieldNumber = 318,
+    kFenceSignaledFieldNumber = 319,
+    kClkEnableFieldNumber = 320,
+    kClkDisableFieldNumber = 321,
+    kClkSetRateFieldNumber = 322,
+    kBinderTransactionAllocBufFieldNumber = 323,
+    kSignalDeliverFieldNumber = 324,
+    kSignalGenerateFieldNumber = 325,
+    kOomScoreAdjUpdateFieldNumber = 326,
+    kGenericFieldNumber = 327,
+    kMmEventRecordFieldNumber = 328,
+    kSysEnterFieldNumber = 329,
+    kSysExitFieldNumber = 330,
+    kZeroFieldNumber = 331,
+    kGpuFrequencyFieldNumber = 332,
+    kSdeTracingMarkWriteFieldNumber = 333,
+    kMarkVictimFieldNumber = 334,
+    kIonStatFieldNumber = 335,
+    kIonBufferCreateFieldNumber = 336,
+    kIonBufferDestroyFieldNumber = 337,
+    kScmCallStartFieldNumber = 338,
+    kScmCallEndFieldNumber = 339,
+    kGpuMemTotalFieldNumber = 340,
+    kThermalTemperatureFieldNumber = 341,
+    kCdevUpdateFieldNumber = 342,
+    kCpuhpExitFieldNumber = 343,
+    kCpuhpMultiEnterFieldNumber = 344,
+    kCpuhpEnterFieldNumber = 345,
+    kCpuhpLatencyFieldNumber = 346,
+    kFastrpcDmaStatFieldNumber = 347,
+    kDpuTracingMarkWriteFieldNumber = 348,
+    kG2dTracingMarkWriteFieldNumber = 349,
+    kMaliTracingMarkWriteFieldNumber = 350,
+    kDmaHeapStatFieldNumber = 351,
+    kCpuhpPauseFieldNumber = 352,
+    kSchedPiSetprioFieldNumber = 353,
+    kSdeSdeEvtlogFieldNumber = 354,
+    kSdeSdePerfCalcCrtcFieldNumber = 355,
+    kSdeSdePerfCrtcUpdateFieldNumber = 356,
+    kSdeSdePerfSetQosLutsFieldNumber = 357,
+    kSdeSdePerfUpdateBusFieldNumber = 358,
+    kRssStatThrottledFieldNumber = 359,
+    kNetifReceiveSkbFieldNumber = 360,
+    kNetDevXmitFieldNumber = 361,
+    kInetSockSetStateFieldNumber = 362,
+    kTcpRetransmitSkbFieldNumber = 363,
+    kCrosEcSensorhubDataFieldNumber = 364,
+    kNapiGroReceiveEntryFieldNumber = 365,
+    kNapiGroReceiveExitFieldNumber = 366,
+    kKfreeSkbFieldNumber = 367,
+    kKvmAccessFaultFieldNumber = 368,
+    kKvmAckIrqFieldNumber = 369,
+    kKvmAgeHvaFieldNumber = 370,
+    kKvmAgePageFieldNumber = 371,
+    kKvmArmClearDebugFieldNumber = 372,
+    kKvmArmSetDreg32FieldNumber = 373,
+    kKvmArmSetRegsetFieldNumber = 374,
+    kKvmArmSetupDebugFieldNumber = 375,
+    kKvmEntryFieldNumber = 376,
+    kKvmExitFieldNumber = 377,
+    kKvmFpuFieldNumber = 378,
+    kKvmGetTimerMapFieldNumber = 379,
+    kKvmGuestFaultFieldNumber = 380,
+    kKvmHandleSysRegFieldNumber = 381,
+    kKvmHvcArm64FieldNumber = 382,
+    kKvmIrqLineFieldNumber = 383,
+    kKvmMmioFieldNumber = 384,
+    kKvmMmioEmulateFieldNumber = 385,
+    kKvmSetGuestDebugFieldNumber = 386,
+    kKvmSetIrqFieldNumber = 387,
+    kKvmSetSpteHvaFieldNumber = 388,
+    kKvmSetWayFlushFieldNumber = 389,
+    kKvmSysAccessFieldNumber = 390,
+    kKvmTestAgeHvaFieldNumber = 391,
+    kKvmTimerEmulateFieldNumber = 392,
+    kKvmTimerHrtimerExpireFieldNumber = 393,
+    kKvmTimerRestoreStateFieldNumber = 394,
+    kKvmTimerSaveStateFieldNumber = 395,
+    kKvmTimerUpdateIrqFieldNumber = 396,
+    kKvmToggleCacheFieldNumber = 397,
+    kKvmUnmapHvaRangeFieldNumber = 398,
+    kKvmUserspaceExitFieldNumber = 399,
+    kKvmVcpuWakeupFieldNumber = 400,
+    kKvmWfxArm64FieldNumber = 401,
+    kTrapRegFieldNumber = 402,
+    kVgicUpdateIrqPendingFieldNumber = 403,
+    kWakeupSourceActivateFieldNumber = 404,
+    kWakeupSourceDeactivateFieldNumber = 405,
+    kUfshcdCommandFieldNumber = 406,
+    kUfshcdClkGatingFieldNumber = 407,
+    kConsoleFieldNumber = 408,
+    kDrmVblankEventFieldNumber = 409,
+    kDrmVblankEventDeliveredFieldNumber = 410,
+    kDrmSchedJobFieldNumber = 411,
+    kDrmRunJobFieldNumber = 412,
+    kDrmSchedProcessJobFieldNumber = 413,
+    kDmaFenceInitFieldNumber = 414,
+    kDmaFenceEmitFieldNumber = 415,
+    kDmaFenceSignaledFieldNumber = 416,
+    kDmaFenceWaitStartFieldNumber = 417,
+    kDmaFenceWaitEndFieldNumber = 418,
+    kF2fsIostatFieldNumber = 419,
+    kF2fsIostatLatencyFieldNumber = 420,
+    kSchedCpuUtilCfsFieldNumber = 421,
+    kV4l2QbufFieldNumber = 422,
+    kV4l2DqbufFieldNumber = 423,
+    kVb2V4l2BufQueueFieldNumber = 424,
+    kVb2V4l2BufDoneFieldNumber = 425,
+    kVb2V4l2QbufFieldNumber = 426,
+    kVb2V4l2DqbufFieldNumber = 427,
+    kDsiCmdFifoStatusFieldNumber = 428,
+    kDsiRxFieldNumber = 429,
+    kDsiTxFieldNumber = 430,
+    kAndroidFsDatareadEndFieldNumber = 431,
+    kAndroidFsDatareadStartFieldNumber = 432,
+    kAndroidFsDatawriteEndFieldNumber = 433,
+    kAndroidFsDatawriteStartFieldNumber = 434,
+    kAndroidFsFsyncEndFieldNumber = 435,
+    kAndroidFsFsyncStartFieldNumber = 436,
+    kFuncgraphEntryFieldNumber = 437,
+    kFuncgraphExitFieldNumber = 438,
+    kVirtioVideoCmdFieldNumber = 439,
+    kVirtioVideoCmdDoneFieldNumber = 440,
+    kVirtioVideoResourceQueueFieldNumber = 441,
+    kVirtioVideoResourceQueueDoneFieldNumber = 442,
+    kMmShrinkSlabStartFieldNumber = 443,
+    kMmShrinkSlabEndFieldNumber = 444,
+    kTrustySmcFieldNumber = 445,
+    kTrustySmcDoneFieldNumber = 446,
+    kTrustyStdCall32FieldNumber = 447,
+    kTrustyStdCall32DoneFieldNumber = 448,
+    kTrustyShareMemoryFieldNumber = 449,
+    kTrustyShareMemoryDoneFieldNumber = 450,
+    kTrustyReclaimMemoryFieldNumber = 451,
+    kTrustyReclaimMemoryDoneFieldNumber = 452,
+    kTrustyIrqFieldNumber = 453,
+    kTrustyIpcHandleEventFieldNumber = 454,
+    kTrustyIpcConnectFieldNumber = 455,
+    kTrustyIpcConnectEndFieldNumber = 456,
+    kTrustyIpcWriteFieldNumber = 457,
+    kTrustyIpcPollFieldNumber = 458,
+    kTrustyIpcReadFieldNumber = 460,
+    kTrustyIpcReadEndFieldNumber = 461,
+    kTrustyIpcRxFieldNumber = 462,
+    kTrustyEnqueueNopFieldNumber = 464,
+    kCmaAllocStartFieldNumber = 465,
+    kCmaAllocInfoFieldNumber = 466,
+    kLwisTracingMarkWriteFieldNumber = 467,
+    kVirtioGpuCmdQueueFieldNumber = 468,
+    kVirtioGpuCmdResponseFieldNumber = 469,
+    kMaliMaliKCPUCQSSETFieldNumber = 470,
+    kMaliMaliKCPUCQSWAITSTARTFieldNumber = 471,
+    kMaliMaliKCPUCQSWAITENDFieldNumber = 472,
+    kMaliMaliKCPUFENCESIGNALFieldNumber = 473,
+    kMaliMaliKCPUFENCEWAITSTARTFieldNumber = 474,
+    kMaliMaliKCPUFENCEWAITENDFieldNumber = 475,
+    kHypEnterFieldNumber = 476,
+    kHypExitFieldNumber = 477,
+    kHostHcallFieldNumber = 478,
+    kHostSmcFieldNumber = 479,
+    kHostMemAbortFieldNumber = 480,
+    kSuspendResumeMinimalFieldNumber = 481,
+    kMaliMaliCSFINTERRUPTSTARTFieldNumber = 482,
+    kMaliMaliCSFINTERRUPTENDFieldNumber = 483,
+    kSamsungTracingMarkWriteFieldNumber = 484,
+    kBinderCommandFieldNumber = 485,
+    kBinderReturnFieldNumber = 486,
+    kSchedSwitchWithCtrsFieldNumber = 487,
+    kGpuWorkPeriodFieldNumber = 488,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceEvent"; }
+
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CommonFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CommonFlags kCommonFlags{};
+  void set_common_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CommonFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Print =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PrintFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Print kPrint{};
+  template <typename T = PrintFtraceEvent> T* set_print() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_SchedSwitch =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedSwitchFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedSwitch kSchedSwitch{};
+  template <typename T = SchedSwitchFtraceEvent> T* set_sched_switch() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_CpuFrequency =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuFrequencyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuFrequency kCpuFrequency{};
+  template <typename T = CpuFrequencyFtraceEvent> T* set_cpu_frequency() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_CpuFrequencyLimits =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuFrequencyLimitsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuFrequencyLimits kCpuFrequencyLimits{};
+  template <typename T = CpuFrequencyLimitsFtraceEvent> T* set_cpu_frequency_limits() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_CpuIdle =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuIdleFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuIdle kCpuIdle{};
+  template <typename T = CpuIdleFtraceEvent> T* set_cpu_idle() {
+    return BeginNestedMessage<T>(13);
+  }
+
+
+  using FieldMetadata_ClockEnable =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockEnableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClockEnable kClockEnable{};
+  template <typename T = ClockEnableFtraceEvent> T* set_clock_enable() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_ClockDisable =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockDisableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClockDisable kClockDisable{};
+  template <typename T = ClockDisableFtraceEvent> T* set_clock_disable() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_ClockSetRate =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClockSetRateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClockSetRate kClockSetRate{};
+  template <typename T = ClockSetRateFtraceEvent> T* set_clock_set_rate() {
+    return BeginNestedMessage<T>(16);
+  }
+
+
+  using FieldMetadata_SchedWakeup =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedWakeupFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedWakeup kSchedWakeup{};
+  template <typename T = SchedWakeupFtraceEvent> T* set_sched_wakeup() {
+    return BeginNestedMessage<T>(17);
+  }
+
+
+  using FieldMetadata_SchedBlockedReason =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedBlockedReasonFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedBlockedReason kSchedBlockedReason{};
+  template <typename T = SchedBlockedReasonFtraceEvent> T* set_sched_blocked_reason() {
+    return BeginNestedMessage<T>(18);
+  }
+
+
+  using FieldMetadata_SchedCpuHotplug =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedCpuHotplugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedCpuHotplug kSchedCpuHotplug{};
+  template <typename T = SchedCpuHotplugFtraceEvent> T* set_sched_cpu_hotplug() {
+    return BeginNestedMessage<T>(19);
+  }
+
+
+  using FieldMetadata_SchedWaking =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedWakingFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedWaking kSchedWaking{};
+  template <typename T = SchedWakingFtraceEvent> T* set_sched_waking() {
+    return BeginNestedMessage<T>(20);
+  }
+
+
+  using FieldMetadata_IpiEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IpiEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IpiEntry kIpiEntry{};
+  template <typename T = IpiEntryFtraceEvent> T* set_ipi_entry() {
+    return BeginNestedMessage<T>(21);
+  }
+
+
+  using FieldMetadata_IpiExit =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IpiExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IpiExit kIpiExit{};
+  template <typename T = IpiExitFtraceEvent> T* set_ipi_exit() {
+    return BeginNestedMessage<T>(22);
+  }
+
+
+  using FieldMetadata_IpiRaise =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IpiRaiseFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IpiRaise kIpiRaise{};
+  template <typename T = IpiRaiseFtraceEvent> T* set_ipi_raise() {
+    return BeginNestedMessage<T>(23);
+  }
+
+
+  using FieldMetadata_SoftirqEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SoftirqEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SoftirqEntry kSoftirqEntry{};
+  template <typename T = SoftirqEntryFtraceEvent> T* set_softirq_entry() {
+    return BeginNestedMessage<T>(24);
+  }
+
+
+  using FieldMetadata_SoftirqExit =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SoftirqExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SoftirqExit kSoftirqExit{};
+  template <typename T = SoftirqExitFtraceEvent> T* set_softirq_exit() {
+    return BeginNestedMessage<T>(25);
+  }
+
+
+  using FieldMetadata_SoftirqRaise =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SoftirqRaiseFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SoftirqRaise kSoftirqRaise{};
+  template <typename T = SoftirqRaiseFtraceEvent> T* set_softirq_raise() {
+    return BeginNestedMessage<T>(26);
+  }
+
+
+  using FieldMetadata_I2cRead =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      I2cReadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_I2cRead kI2cRead{};
+  template <typename T = I2cReadFtraceEvent> T* set_i2c_read() {
+    return BeginNestedMessage<T>(27);
+  }
+
+
+  using FieldMetadata_I2cWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      I2cWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_I2cWrite kI2cWrite{};
+  template <typename T = I2cWriteFtraceEvent> T* set_i2c_write() {
+    return BeginNestedMessage<T>(28);
+  }
+
+
+  using FieldMetadata_I2cResult =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      I2cResultFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_I2cResult kI2cResult{};
+  template <typename T = I2cResultFtraceEvent> T* set_i2c_result() {
+    return BeginNestedMessage<T>(29);
+  }
+
+
+  using FieldMetadata_I2cReply =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      I2cReplyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_I2cReply kI2cReply{};
+  template <typename T = I2cReplyFtraceEvent> T* set_i2c_reply() {
+    return BeginNestedMessage<T>(30);
+  }
+
+
+  using FieldMetadata_SmbusRead =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmbusReadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SmbusRead kSmbusRead{};
+  template <typename T = SmbusReadFtraceEvent> T* set_smbus_read() {
+    return BeginNestedMessage<T>(31);
+  }
+
+
+  using FieldMetadata_SmbusWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmbusWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SmbusWrite kSmbusWrite{};
+  template <typename T = SmbusWriteFtraceEvent> T* set_smbus_write() {
+    return BeginNestedMessage<T>(32);
+  }
+
+
+  using FieldMetadata_SmbusResult =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmbusResultFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SmbusResult kSmbusResult{};
+  template <typename T = SmbusResultFtraceEvent> T* set_smbus_result() {
+    return BeginNestedMessage<T>(33);
+  }
+
+
+  using FieldMetadata_SmbusReply =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmbusReplyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SmbusReply kSmbusReply{};
+  template <typename T = SmbusReplyFtraceEvent> T* set_smbus_reply() {
+    return BeginNestedMessage<T>(34);
+  }
+
+
+  using FieldMetadata_LowmemoryKill =
+    ::protozero::proto_utils::FieldMetadata<
+      35,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LowmemoryKillFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_LowmemoryKill kLowmemoryKill{};
+  template <typename T = LowmemoryKillFtraceEvent> T* set_lowmemory_kill() {
+    return BeginNestedMessage<T>(35);
+  }
+
+
+  using FieldMetadata_IrqHandlerEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IrqHandlerEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IrqHandlerEntry kIrqHandlerEntry{};
+  template <typename T = IrqHandlerEntryFtraceEvent> T* set_irq_handler_entry() {
+    return BeginNestedMessage<T>(36);
+  }
+
+
+  using FieldMetadata_IrqHandlerExit =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IrqHandlerExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IrqHandlerExit kIrqHandlerExit{};
+  template <typename T = IrqHandlerExitFtraceEvent> T* set_irq_handler_exit() {
+    return BeginNestedMessage<T>(37);
+  }
+
+
+  using FieldMetadata_SyncPt =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SyncPtFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SyncPt kSyncPt{};
+  template <typename T = SyncPtFtraceEvent> T* set_sync_pt() {
+    return BeginNestedMessage<T>(38);
+  }
+
+
+  using FieldMetadata_SyncTimeline =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SyncTimelineFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SyncTimeline kSyncTimeline{};
+  template <typename T = SyncTimelineFtraceEvent> T* set_sync_timeline() {
+    return BeginNestedMessage<T>(39);
+  }
+
+
+  using FieldMetadata_SyncWait =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SyncWaitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SyncWait kSyncWait{};
+  template <typename T = SyncWaitFtraceEvent> T* set_sync_wait() {
+    return BeginNestedMessage<T>(40);
+  }
+
+
+  using FieldMetadata_Ext4DaWriteBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaWriteBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaWriteBegin kExt4DaWriteBegin{};
+  template <typename T = Ext4DaWriteBeginFtraceEvent> T* set_ext4_da_write_begin() {
+    return BeginNestedMessage<T>(41);
+  }
+
+
+  using FieldMetadata_Ext4DaWriteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaWriteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaWriteEnd kExt4DaWriteEnd{};
+  template <typename T = Ext4DaWriteEndFtraceEvent> T* set_ext4_da_write_end() {
+    return BeginNestedMessage<T>(42);
+  }
+
+
+  using FieldMetadata_Ext4SyncFileEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      43,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4SyncFileEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4SyncFileEnter kExt4SyncFileEnter{};
+  template <typename T = Ext4SyncFileEnterFtraceEvent> T* set_ext4_sync_file_enter() {
+    return BeginNestedMessage<T>(43);
+  }
+
+
+  using FieldMetadata_Ext4SyncFileExit =
+    ::protozero::proto_utils::FieldMetadata<
+      44,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4SyncFileExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4SyncFileExit kExt4SyncFileExit{};
+  template <typename T = Ext4SyncFileExitFtraceEvent> T* set_ext4_sync_file_exit() {
+    return BeginNestedMessage<T>(44);
+  }
+
+
+  using FieldMetadata_BlockRqIssue =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqIssueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqIssue kBlockRqIssue{};
+  template <typename T = BlockRqIssueFtraceEvent> T* set_block_rq_issue() {
+    return BeginNestedMessage<T>(45);
+  }
+
+
+  using FieldMetadata_MmVmscanDirectReclaimBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      46,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmVmscanDirectReclaimBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmVmscanDirectReclaimBegin kMmVmscanDirectReclaimBegin{};
+  template <typename T = MmVmscanDirectReclaimBeginFtraceEvent> T* set_mm_vmscan_direct_reclaim_begin() {
+    return BeginNestedMessage<T>(46);
+  }
+
+
+  using FieldMetadata_MmVmscanDirectReclaimEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      47,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmVmscanDirectReclaimEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmVmscanDirectReclaimEnd kMmVmscanDirectReclaimEnd{};
+  template <typename T = MmVmscanDirectReclaimEndFtraceEvent> T* set_mm_vmscan_direct_reclaim_end() {
+    return BeginNestedMessage<T>(47);
+  }
+
+
+  using FieldMetadata_MmVmscanKswapdWake =
+    ::protozero::proto_utils::FieldMetadata<
+      48,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmVmscanKswapdWakeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmVmscanKswapdWake kMmVmscanKswapdWake{};
+  template <typename T = MmVmscanKswapdWakeFtraceEvent> T* set_mm_vmscan_kswapd_wake() {
+    return BeginNestedMessage<T>(48);
+  }
+
+
+  using FieldMetadata_MmVmscanKswapdSleep =
+    ::protozero::proto_utils::FieldMetadata<
+      49,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmVmscanKswapdSleepFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmVmscanKswapdSleep kMmVmscanKswapdSleep{};
+  template <typename T = MmVmscanKswapdSleepFtraceEvent> T* set_mm_vmscan_kswapd_sleep() {
+    return BeginNestedMessage<T>(49);
+  }
+
+
+  using FieldMetadata_BinderTransaction =
+    ::protozero::proto_utils::FieldMetadata<
+      50,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderTransactionFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderTransaction kBinderTransaction{};
+  template <typename T = BinderTransactionFtraceEvent> T* set_binder_transaction() {
+    return BeginNestedMessage<T>(50);
+  }
+
+
+  using FieldMetadata_BinderTransactionReceived =
+    ::protozero::proto_utils::FieldMetadata<
+      51,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderTransactionReceivedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderTransactionReceived kBinderTransactionReceived{};
+  template <typename T = BinderTransactionReceivedFtraceEvent> T* set_binder_transaction_received() {
+    return BeginNestedMessage<T>(51);
+  }
+
+
+  using FieldMetadata_BinderSetPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      52,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderSetPriorityFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderSetPriority kBinderSetPriority{};
+  template <typename T = BinderSetPriorityFtraceEvent> T* set_binder_set_priority() {
+    return BeginNestedMessage<T>(52);
+  }
+
+
+  using FieldMetadata_BinderLock =
+    ::protozero::proto_utils::FieldMetadata<
+      53,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderLockFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderLock kBinderLock{};
+  template <typename T = BinderLockFtraceEvent> T* set_binder_lock() {
+    return BeginNestedMessage<T>(53);
+  }
+
+
+  using FieldMetadata_BinderLocked =
+    ::protozero::proto_utils::FieldMetadata<
+      54,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderLockedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderLocked kBinderLocked{};
+  template <typename T = BinderLockedFtraceEvent> T* set_binder_locked() {
+    return BeginNestedMessage<T>(54);
+  }
+
+
+  using FieldMetadata_BinderUnlock =
+    ::protozero::proto_utils::FieldMetadata<
+      55,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderUnlockFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderUnlock kBinderUnlock{};
+  template <typename T = BinderUnlockFtraceEvent> T* set_binder_unlock() {
+    return BeginNestedMessage<T>(55);
+  }
+
+
+  using FieldMetadata_WorkqueueActivateWork =
+    ::protozero::proto_utils::FieldMetadata<
+      56,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WorkqueueActivateWorkFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WorkqueueActivateWork kWorkqueueActivateWork{};
+  template <typename T = WorkqueueActivateWorkFtraceEvent> T* set_workqueue_activate_work() {
+    return BeginNestedMessage<T>(56);
+  }
+
+
+  using FieldMetadata_WorkqueueExecuteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      57,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WorkqueueExecuteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WorkqueueExecuteEnd kWorkqueueExecuteEnd{};
+  template <typename T = WorkqueueExecuteEndFtraceEvent> T* set_workqueue_execute_end() {
+    return BeginNestedMessage<T>(57);
+  }
+
+
+  using FieldMetadata_WorkqueueExecuteStart =
+    ::protozero::proto_utils::FieldMetadata<
+      58,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WorkqueueExecuteStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WorkqueueExecuteStart kWorkqueueExecuteStart{};
+  template <typename T = WorkqueueExecuteStartFtraceEvent> T* set_workqueue_execute_start() {
+    return BeginNestedMessage<T>(58);
+  }
+
+
+  using FieldMetadata_WorkqueueQueueWork =
+    ::protozero::proto_utils::FieldMetadata<
+      59,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WorkqueueQueueWorkFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WorkqueueQueueWork kWorkqueueQueueWork{};
+  template <typename T = WorkqueueQueueWorkFtraceEvent> T* set_workqueue_queue_work() {
+    return BeginNestedMessage<T>(59);
+  }
+
+
+  using FieldMetadata_RegulatorDisable =
+    ::protozero::proto_utils::FieldMetadata<
+      60,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorDisableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorDisable kRegulatorDisable{};
+  template <typename T = RegulatorDisableFtraceEvent> T* set_regulator_disable() {
+    return BeginNestedMessage<T>(60);
+  }
+
+
+  using FieldMetadata_RegulatorDisableComplete =
+    ::protozero::proto_utils::FieldMetadata<
+      61,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorDisableCompleteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorDisableComplete kRegulatorDisableComplete{};
+  template <typename T = RegulatorDisableCompleteFtraceEvent> T* set_regulator_disable_complete() {
+    return BeginNestedMessage<T>(61);
+  }
+
+
+  using FieldMetadata_RegulatorEnable =
+    ::protozero::proto_utils::FieldMetadata<
+      62,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorEnableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorEnable kRegulatorEnable{};
+  template <typename T = RegulatorEnableFtraceEvent> T* set_regulator_enable() {
+    return BeginNestedMessage<T>(62);
+  }
+
+
+  using FieldMetadata_RegulatorEnableComplete =
+    ::protozero::proto_utils::FieldMetadata<
+      63,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorEnableCompleteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorEnableComplete kRegulatorEnableComplete{};
+  template <typename T = RegulatorEnableCompleteFtraceEvent> T* set_regulator_enable_complete() {
+    return BeginNestedMessage<T>(63);
+  }
+
+
+  using FieldMetadata_RegulatorEnableDelay =
+    ::protozero::proto_utils::FieldMetadata<
+      64,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorEnableDelayFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorEnableDelay kRegulatorEnableDelay{};
+  template <typename T = RegulatorEnableDelayFtraceEvent> T* set_regulator_enable_delay() {
+    return BeginNestedMessage<T>(64);
+  }
+
+
+  using FieldMetadata_RegulatorSetVoltage =
+    ::protozero::proto_utils::FieldMetadata<
+      65,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorSetVoltageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorSetVoltage kRegulatorSetVoltage{};
+  template <typename T = RegulatorSetVoltageFtraceEvent> T* set_regulator_set_voltage() {
+    return BeginNestedMessage<T>(65);
+  }
+
+
+  using FieldMetadata_RegulatorSetVoltageComplete =
+    ::protozero::proto_utils::FieldMetadata<
+      66,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RegulatorSetVoltageCompleteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RegulatorSetVoltageComplete kRegulatorSetVoltageComplete{};
+  template <typename T = RegulatorSetVoltageCompleteFtraceEvent> T* set_regulator_set_voltage_complete() {
+    return BeginNestedMessage<T>(66);
+  }
+
+
+  using FieldMetadata_CgroupAttachTask =
+    ::protozero::proto_utils::FieldMetadata<
+      67,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupAttachTaskFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupAttachTask kCgroupAttachTask{};
+  template <typename T = CgroupAttachTaskFtraceEvent> T* set_cgroup_attach_task() {
+    return BeginNestedMessage<T>(67);
+  }
+
+
+  using FieldMetadata_CgroupMkdir =
+    ::protozero::proto_utils::FieldMetadata<
+      68,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupMkdirFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupMkdir kCgroupMkdir{};
+  template <typename T = CgroupMkdirFtraceEvent> T* set_cgroup_mkdir() {
+    return BeginNestedMessage<T>(68);
+  }
+
+
+  using FieldMetadata_CgroupRemount =
+    ::protozero::proto_utils::FieldMetadata<
+      69,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupRemountFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupRemount kCgroupRemount{};
+  template <typename T = CgroupRemountFtraceEvent> T* set_cgroup_remount() {
+    return BeginNestedMessage<T>(69);
+  }
+
+
+  using FieldMetadata_CgroupRmdir =
+    ::protozero::proto_utils::FieldMetadata<
+      70,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupRmdirFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupRmdir kCgroupRmdir{};
+  template <typename T = CgroupRmdirFtraceEvent> T* set_cgroup_rmdir() {
+    return BeginNestedMessage<T>(70);
+  }
+
+
+  using FieldMetadata_CgroupTransferTasks =
+    ::protozero::proto_utils::FieldMetadata<
+      71,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupTransferTasksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupTransferTasks kCgroupTransferTasks{};
+  template <typename T = CgroupTransferTasksFtraceEvent> T* set_cgroup_transfer_tasks() {
+    return BeginNestedMessage<T>(71);
+  }
+
+
+  using FieldMetadata_CgroupDestroyRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      72,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupDestroyRootFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupDestroyRoot kCgroupDestroyRoot{};
+  template <typename T = CgroupDestroyRootFtraceEvent> T* set_cgroup_destroy_root() {
+    return BeginNestedMessage<T>(72);
+  }
+
+
+  using FieldMetadata_CgroupRelease =
+    ::protozero::proto_utils::FieldMetadata<
+      73,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupReleaseFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupRelease kCgroupRelease{};
+  template <typename T = CgroupReleaseFtraceEvent> T* set_cgroup_release() {
+    return BeginNestedMessage<T>(73);
+  }
+
+
+  using FieldMetadata_CgroupRename =
+    ::protozero::proto_utils::FieldMetadata<
+      74,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupRenameFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupRename kCgroupRename{};
+  template <typename T = CgroupRenameFtraceEvent> T* set_cgroup_rename() {
+    return BeginNestedMessage<T>(74);
+  }
+
+
+  using FieldMetadata_CgroupSetupRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      75,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CgroupSetupRootFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CgroupSetupRoot kCgroupSetupRoot{};
+  template <typename T = CgroupSetupRootFtraceEvent> T* set_cgroup_setup_root() {
+    return BeginNestedMessage<T>(75);
+  }
+
+
+  using FieldMetadata_MdpCmdKickoff =
+    ::protozero::proto_utils::FieldMetadata<
+      76,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCmdKickoffFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCmdKickoff kMdpCmdKickoff{};
+  template <typename T = MdpCmdKickoffFtraceEvent> T* set_mdp_cmd_kickoff() {
+    return BeginNestedMessage<T>(76);
+  }
+
+
+  using FieldMetadata_MdpCommit =
+    ::protozero::proto_utils::FieldMetadata<
+      77,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCommitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCommit kMdpCommit{};
+  template <typename T = MdpCommitFtraceEvent> T* set_mdp_commit() {
+    return BeginNestedMessage<T>(77);
+  }
+
+
+  using FieldMetadata_MdpPerfSetOt =
+    ::protozero::proto_utils::FieldMetadata<
+      78,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfSetOtFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfSetOt kMdpPerfSetOt{};
+  template <typename T = MdpPerfSetOtFtraceEvent> T* set_mdp_perf_set_ot() {
+    return BeginNestedMessage<T>(78);
+  }
+
+
+  using FieldMetadata_MdpSsppChange =
+    ::protozero::proto_utils::FieldMetadata<
+      79,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpSsppChangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpSsppChange kMdpSsppChange{};
+  template <typename T = MdpSsppChangeFtraceEvent> T* set_mdp_sspp_change() {
+    return BeginNestedMessage<T>(79);
+  }
+
+
+  using FieldMetadata_TracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      80,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TracingMarkWrite kTracingMarkWrite{};
+  template <typename T = TracingMarkWriteFtraceEvent> T* set_tracing_mark_write() {
+    return BeginNestedMessage<T>(80);
+  }
+
+
+  using FieldMetadata_MdpCmdPingpongDone =
+    ::protozero::proto_utils::FieldMetadata<
+      81,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCmdPingpongDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCmdPingpongDone kMdpCmdPingpongDone{};
+  template <typename T = MdpCmdPingpongDoneFtraceEvent> T* set_mdp_cmd_pingpong_done() {
+    return BeginNestedMessage<T>(81);
+  }
+
+
+  using FieldMetadata_MdpCompareBw =
+    ::protozero::proto_utils::FieldMetadata<
+      82,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCompareBwFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCompareBw kMdpCompareBw{};
+  template <typename T = MdpCompareBwFtraceEvent> T* set_mdp_compare_bw() {
+    return BeginNestedMessage<T>(82);
+  }
+
+
+  using FieldMetadata_MdpPerfSetPanicLuts =
+    ::protozero::proto_utils::FieldMetadata<
+      83,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfSetPanicLutsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfSetPanicLuts kMdpPerfSetPanicLuts{};
+  template <typename T = MdpPerfSetPanicLutsFtraceEvent> T* set_mdp_perf_set_panic_luts() {
+    return BeginNestedMessage<T>(83);
+  }
+
+
+  using FieldMetadata_MdpSsppSet =
+    ::protozero::proto_utils::FieldMetadata<
+      84,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpSsppSetFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpSsppSet kMdpSsppSet{};
+  template <typename T = MdpSsppSetFtraceEvent> T* set_mdp_sspp_set() {
+    return BeginNestedMessage<T>(84);
+  }
+
+
+  using FieldMetadata_MdpCmdReadptrDone =
+    ::protozero::proto_utils::FieldMetadata<
+      85,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCmdReadptrDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCmdReadptrDone kMdpCmdReadptrDone{};
+  template <typename T = MdpCmdReadptrDoneFtraceEvent> T* set_mdp_cmd_readptr_done() {
+    return BeginNestedMessage<T>(85);
+  }
+
+
+  using FieldMetadata_MdpMisrCrc =
+    ::protozero::proto_utils::FieldMetadata<
+      86,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpMisrCrcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpMisrCrc kMdpMisrCrc{};
+  template <typename T = MdpMisrCrcFtraceEvent> T* set_mdp_misr_crc() {
+    return BeginNestedMessage<T>(86);
+  }
+
+
+  using FieldMetadata_MdpPerfSetQosLuts =
+    ::protozero::proto_utils::FieldMetadata<
+      87,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfSetQosLutsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfSetQosLuts kMdpPerfSetQosLuts{};
+  template <typename T = MdpPerfSetQosLutsFtraceEvent> T* set_mdp_perf_set_qos_luts() {
+    return BeginNestedMessage<T>(87);
+  }
+
+
+  using FieldMetadata_MdpTraceCounter =
+    ::protozero::proto_utils::FieldMetadata<
+      88,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpTraceCounterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpTraceCounter kMdpTraceCounter{};
+  template <typename T = MdpTraceCounterFtraceEvent> T* set_mdp_trace_counter() {
+    return BeginNestedMessage<T>(88);
+  }
+
+
+  using FieldMetadata_MdpCmdReleaseBw =
+    ::protozero::proto_utils::FieldMetadata<
+      89,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCmdReleaseBwFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCmdReleaseBw kMdpCmdReleaseBw{};
+  template <typename T = MdpCmdReleaseBwFtraceEvent> T* set_mdp_cmd_release_bw() {
+    return BeginNestedMessage<T>(89);
+  }
+
+
+  using FieldMetadata_MdpMixerUpdate =
+    ::protozero::proto_utils::FieldMetadata<
+      90,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpMixerUpdateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpMixerUpdate kMdpMixerUpdate{};
+  template <typename T = MdpMixerUpdateFtraceEvent> T* set_mdp_mixer_update() {
+    return BeginNestedMessage<T>(90);
+  }
+
+
+  using FieldMetadata_MdpPerfSetWmLevels =
+    ::protozero::proto_utils::FieldMetadata<
+      91,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfSetWmLevelsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfSetWmLevels kMdpPerfSetWmLevels{};
+  template <typename T = MdpPerfSetWmLevelsFtraceEvent> T* set_mdp_perf_set_wm_levels() {
+    return BeginNestedMessage<T>(91);
+  }
+
+
+  using FieldMetadata_MdpVideoUnderrunDone =
+    ::protozero::proto_utils::FieldMetadata<
+      92,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpVideoUnderrunDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpVideoUnderrunDone kMdpVideoUnderrunDone{};
+  template <typename T = MdpVideoUnderrunDoneFtraceEvent> T* set_mdp_video_underrun_done() {
+    return BeginNestedMessage<T>(92);
+  }
+
+
+  using FieldMetadata_MdpCmdWaitPingpong =
+    ::protozero::proto_utils::FieldMetadata<
+      93,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpCmdWaitPingpongFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpCmdWaitPingpong kMdpCmdWaitPingpong{};
+  template <typename T = MdpCmdWaitPingpongFtraceEvent> T* set_mdp_cmd_wait_pingpong() {
+    return BeginNestedMessage<T>(93);
+  }
+
+
+  using FieldMetadata_MdpPerfPrefillCalc =
+    ::protozero::proto_utils::FieldMetadata<
+      94,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfPrefillCalcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfPrefillCalc kMdpPerfPrefillCalc{};
+  template <typename T = MdpPerfPrefillCalcFtraceEvent> T* set_mdp_perf_prefill_calc() {
+    return BeginNestedMessage<T>(94);
+  }
+
+
+  using FieldMetadata_MdpPerfUpdateBus =
+    ::protozero::proto_utils::FieldMetadata<
+      95,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MdpPerfUpdateBusFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MdpPerfUpdateBus kMdpPerfUpdateBus{};
+  template <typename T = MdpPerfUpdateBusFtraceEvent> T* set_mdp_perf_update_bus() {
+    return BeginNestedMessage<T>(95);
+  }
+
+
+  using FieldMetadata_RotatorBwAoAsContext =
+    ::protozero::proto_utils::FieldMetadata<
+      96,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RotatorBwAoAsContextFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RotatorBwAoAsContext kRotatorBwAoAsContext{};
+  template <typename T = RotatorBwAoAsContextFtraceEvent> T* set_rotator_bw_ao_as_context() {
+    return BeginNestedMessage<T>(96);
+  }
+
+
+  using FieldMetadata_MmFilemapAddToPageCache =
+    ::protozero::proto_utils::FieldMetadata<
+      97,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmFilemapAddToPageCacheFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmFilemapAddToPageCache kMmFilemapAddToPageCache{};
+  template <typename T = MmFilemapAddToPageCacheFtraceEvent> T* set_mm_filemap_add_to_page_cache() {
+    return BeginNestedMessage<T>(97);
+  }
+
+
+  using FieldMetadata_MmFilemapDeleteFromPageCache =
+    ::protozero::proto_utils::FieldMetadata<
+      98,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmFilemapDeleteFromPageCacheFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmFilemapDeleteFromPageCache kMmFilemapDeleteFromPageCache{};
+  template <typename T = MmFilemapDeleteFromPageCacheFtraceEvent> T* set_mm_filemap_delete_from_page_cache() {
+    return BeginNestedMessage<T>(98);
+  }
+
+
+  using FieldMetadata_MmCompactionBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      99,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionBegin kMmCompactionBegin{};
+  template <typename T = MmCompactionBeginFtraceEvent> T* set_mm_compaction_begin() {
+    return BeginNestedMessage<T>(99);
+  }
+
+
+  using FieldMetadata_MmCompactionDeferCompaction =
+    ::protozero::proto_utils::FieldMetadata<
+      100,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionDeferCompactionFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionDeferCompaction kMmCompactionDeferCompaction{};
+  template <typename T = MmCompactionDeferCompactionFtraceEvent> T* set_mm_compaction_defer_compaction() {
+    return BeginNestedMessage<T>(100);
+  }
+
+
+  using FieldMetadata_MmCompactionDeferred =
+    ::protozero::proto_utils::FieldMetadata<
+      101,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionDeferredFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionDeferred kMmCompactionDeferred{};
+  template <typename T = MmCompactionDeferredFtraceEvent> T* set_mm_compaction_deferred() {
+    return BeginNestedMessage<T>(101);
+  }
+
+
+  using FieldMetadata_MmCompactionDeferReset =
+    ::protozero::proto_utils::FieldMetadata<
+      102,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionDeferResetFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionDeferReset kMmCompactionDeferReset{};
+  template <typename T = MmCompactionDeferResetFtraceEvent> T* set_mm_compaction_defer_reset() {
+    return BeginNestedMessage<T>(102);
+  }
+
+
+  using FieldMetadata_MmCompactionEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      103,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionEnd kMmCompactionEnd{};
+  template <typename T = MmCompactionEndFtraceEvent> T* set_mm_compaction_end() {
+    return BeginNestedMessage<T>(103);
+  }
+
+
+  using FieldMetadata_MmCompactionFinished =
+    ::protozero::proto_utils::FieldMetadata<
+      104,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionFinishedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionFinished kMmCompactionFinished{};
+  template <typename T = MmCompactionFinishedFtraceEvent> T* set_mm_compaction_finished() {
+    return BeginNestedMessage<T>(104);
+  }
+
+
+  using FieldMetadata_MmCompactionIsolateFreepages =
+    ::protozero::proto_utils::FieldMetadata<
+      105,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionIsolateFreepagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionIsolateFreepages kMmCompactionIsolateFreepages{};
+  template <typename T = MmCompactionIsolateFreepagesFtraceEvent> T* set_mm_compaction_isolate_freepages() {
+    return BeginNestedMessage<T>(105);
+  }
+
+
+  using FieldMetadata_MmCompactionIsolateMigratepages =
+    ::protozero::proto_utils::FieldMetadata<
+      106,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionIsolateMigratepagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionIsolateMigratepages kMmCompactionIsolateMigratepages{};
+  template <typename T = MmCompactionIsolateMigratepagesFtraceEvent> T* set_mm_compaction_isolate_migratepages() {
+    return BeginNestedMessage<T>(106);
+  }
+
+
+  using FieldMetadata_MmCompactionKcompactdSleep =
+    ::protozero::proto_utils::FieldMetadata<
+      107,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionKcompactdSleepFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionKcompactdSleep kMmCompactionKcompactdSleep{};
+  template <typename T = MmCompactionKcompactdSleepFtraceEvent> T* set_mm_compaction_kcompactd_sleep() {
+    return BeginNestedMessage<T>(107);
+  }
+
+
+  using FieldMetadata_MmCompactionKcompactdWake =
+    ::protozero::proto_utils::FieldMetadata<
+      108,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionKcompactdWakeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionKcompactdWake kMmCompactionKcompactdWake{};
+  template <typename T = MmCompactionKcompactdWakeFtraceEvent> T* set_mm_compaction_kcompactd_wake() {
+    return BeginNestedMessage<T>(108);
+  }
+
+
+  using FieldMetadata_MmCompactionMigratepages =
+    ::protozero::proto_utils::FieldMetadata<
+      109,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionMigratepagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionMigratepages kMmCompactionMigratepages{};
+  template <typename T = MmCompactionMigratepagesFtraceEvent> T* set_mm_compaction_migratepages() {
+    return BeginNestedMessage<T>(109);
+  }
+
+
+  using FieldMetadata_MmCompactionSuitable =
+    ::protozero::proto_utils::FieldMetadata<
+      110,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionSuitableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionSuitable kMmCompactionSuitable{};
+  template <typename T = MmCompactionSuitableFtraceEvent> T* set_mm_compaction_suitable() {
+    return BeginNestedMessage<T>(110);
+  }
+
+
+  using FieldMetadata_MmCompactionTryToCompactPages =
+    ::protozero::proto_utils::FieldMetadata<
+      111,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionTryToCompactPagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionTryToCompactPages kMmCompactionTryToCompactPages{};
+  template <typename T = MmCompactionTryToCompactPagesFtraceEvent> T* set_mm_compaction_try_to_compact_pages() {
+    return BeginNestedMessage<T>(111);
+  }
+
+
+  using FieldMetadata_MmCompactionWakeupKcompactd =
+    ::protozero::proto_utils::FieldMetadata<
+      112,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmCompactionWakeupKcompactdFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmCompactionWakeupKcompactd kMmCompactionWakeupKcompactd{};
+  template <typename T = MmCompactionWakeupKcompactdFtraceEvent> T* set_mm_compaction_wakeup_kcompactd() {
+    return BeginNestedMessage<T>(112);
+  }
+
+
+  using FieldMetadata_SuspendResume =
+    ::protozero::proto_utils::FieldMetadata<
+      113,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SuspendResumeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SuspendResume kSuspendResume{};
+  template <typename T = SuspendResumeFtraceEvent> T* set_suspend_resume() {
+    return BeginNestedMessage<T>(113);
+  }
+
+
+  using FieldMetadata_SchedWakeupNew =
+    ::protozero::proto_utils::FieldMetadata<
+      114,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedWakeupNewFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedWakeupNew kSchedWakeupNew{};
+  template <typename T = SchedWakeupNewFtraceEvent> T* set_sched_wakeup_new() {
+    return BeginNestedMessage<T>(114);
+  }
+
+
+  using FieldMetadata_BlockBioBackmerge =
+    ::protozero::proto_utils::FieldMetadata<
+      115,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioBackmergeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioBackmerge kBlockBioBackmerge{};
+  template <typename T = BlockBioBackmergeFtraceEvent> T* set_block_bio_backmerge() {
+    return BeginNestedMessage<T>(115);
+  }
+
+
+  using FieldMetadata_BlockBioBounce =
+    ::protozero::proto_utils::FieldMetadata<
+      116,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioBounceFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioBounce kBlockBioBounce{};
+  template <typename T = BlockBioBounceFtraceEvent> T* set_block_bio_bounce() {
+    return BeginNestedMessage<T>(116);
+  }
+
+
+  using FieldMetadata_BlockBioComplete =
+    ::protozero::proto_utils::FieldMetadata<
+      117,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioCompleteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioComplete kBlockBioComplete{};
+  template <typename T = BlockBioCompleteFtraceEvent> T* set_block_bio_complete() {
+    return BeginNestedMessage<T>(117);
+  }
+
+
+  using FieldMetadata_BlockBioFrontmerge =
+    ::protozero::proto_utils::FieldMetadata<
+      118,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioFrontmergeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioFrontmerge kBlockBioFrontmerge{};
+  template <typename T = BlockBioFrontmergeFtraceEvent> T* set_block_bio_frontmerge() {
+    return BeginNestedMessage<T>(118);
+  }
+
+
+  using FieldMetadata_BlockBioQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      119,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioQueueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioQueue kBlockBioQueue{};
+  template <typename T = BlockBioQueueFtraceEvent> T* set_block_bio_queue() {
+    return BeginNestedMessage<T>(119);
+  }
+
+
+  using FieldMetadata_BlockBioRemap =
+    ::protozero::proto_utils::FieldMetadata<
+      120,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockBioRemapFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockBioRemap kBlockBioRemap{};
+  template <typename T = BlockBioRemapFtraceEvent> T* set_block_bio_remap() {
+    return BeginNestedMessage<T>(120);
+  }
+
+
+  using FieldMetadata_BlockDirtyBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      121,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockDirtyBufferFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockDirtyBuffer kBlockDirtyBuffer{};
+  template <typename T = BlockDirtyBufferFtraceEvent> T* set_block_dirty_buffer() {
+    return BeginNestedMessage<T>(121);
+  }
+
+
+  using FieldMetadata_BlockGetrq =
+    ::protozero::proto_utils::FieldMetadata<
+      122,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockGetrqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockGetrq kBlockGetrq{};
+  template <typename T = BlockGetrqFtraceEvent> T* set_block_getrq() {
+    return BeginNestedMessage<T>(122);
+  }
+
+
+  using FieldMetadata_BlockPlug =
+    ::protozero::proto_utils::FieldMetadata<
+      123,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockPlugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockPlug kBlockPlug{};
+  template <typename T = BlockPlugFtraceEvent> T* set_block_plug() {
+    return BeginNestedMessage<T>(123);
+  }
+
+
+  using FieldMetadata_BlockRqAbort =
+    ::protozero::proto_utils::FieldMetadata<
+      124,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqAbortFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqAbort kBlockRqAbort{};
+  template <typename T = BlockRqAbortFtraceEvent> T* set_block_rq_abort() {
+    return BeginNestedMessage<T>(124);
+  }
+
+
+  using FieldMetadata_BlockRqComplete =
+    ::protozero::proto_utils::FieldMetadata<
+      125,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqCompleteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqComplete kBlockRqComplete{};
+  template <typename T = BlockRqCompleteFtraceEvent> T* set_block_rq_complete() {
+    return BeginNestedMessage<T>(125);
+  }
+
+
+  using FieldMetadata_BlockRqInsert =
+    ::protozero::proto_utils::FieldMetadata<
+      126,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqInsertFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqInsert kBlockRqInsert{};
+  template <typename T = BlockRqInsertFtraceEvent> T* set_block_rq_insert() {
+    return BeginNestedMessage<T>(126);
+  }
+
+
+  using FieldMetadata_BlockRqRemap =
+    ::protozero::proto_utils::FieldMetadata<
+      128,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqRemapFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqRemap kBlockRqRemap{};
+  template <typename T = BlockRqRemapFtraceEvent> T* set_block_rq_remap() {
+    return BeginNestedMessage<T>(128);
+  }
+
+
+  using FieldMetadata_BlockRqRequeue =
+    ::protozero::proto_utils::FieldMetadata<
+      129,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockRqRequeueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockRqRequeue kBlockRqRequeue{};
+  template <typename T = BlockRqRequeueFtraceEvent> T* set_block_rq_requeue() {
+    return BeginNestedMessage<T>(129);
+  }
+
+
+  using FieldMetadata_BlockSleeprq =
+    ::protozero::proto_utils::FieldMetadata<
+      130,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockSleeprqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockSleeprq kBlockSleeprq{};
+  template <typename T = BlockSleeprqFtraceEvent> T* set_block_sleeprq() {
+    return BeginNestedMessage<T>(130);
+  }
+
+
+  using FieldMetadata_BlockSplit =
+    ::protozero::proto_utils::FieldMetadata<
+      131,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockSplitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockSplit kBlockSplit{};
+  template <typename T = BlockSplitFtraceEvent> T* set_block_split() {
+    return BeginNestedMessage<T>(131);
+  }
+
+
+  using FieldMetadata_BlockTouchBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      132,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockTouchBufferFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockTouchBuffer kBlockTouchBuffer{};
+  template <typename T = BlockTouchBufferFtraceEvent> T* set_block_touch_buffer() {
+    return BeginNestedMessage<T>(132);
+  }
+
+
+  using FieldMetadata_BlockUnplug =
+    ::protozero::proto_utils::FieldMetadata<
+      133,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BlockUnplugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BlockUnplug kBlockUnplug{};
+  template <typename T = BlockUnplugFtraceEvent> T* set_block_unplug() {
+    return BeginNestedMessage<T>(133);
+  }
+
+
+  using FieldMetadata_Ext4AllocDaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      134,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4AllocDaBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4AllocDaBlocks kExt4AllocDaBlocks{};
+  template <typename T = Ext4AllocDaBlocksFtraceEvent> T* set_ext4_alloc_da_blocks() {
+    return BeginNestedMessage<T>(134);
+  }
+
+
+  using FieldMetadata_Ext4AllocateBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      135,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4AllocateBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4AllocateBlocks kExt4AllocateBlocks{};
+  template <typename T = Ext4AllocateBlocksFtraceEvent> T* set_ext4_allocate_blocks() {
+    return BeginNestedMessage<T>(135);
+  }
+
+
+  using FieldMetadata_Ext4AllocateInode =
+    ::protozero::proto_utils::FieldMetadata<
+      136,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4AllocateInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4AllocateInode kExt4AllocateInode{};
+  template <typename T = Ext4AllocateInodeFtraceEvent> T* set_ext4_allocate_inode() {
+    return BeginNestedMessage<T>(136);
+  }
+
+
+  using FieldMetadata_Ext4BeginOrderedTruncate =
+    ::protozero::proto_utils::FieldMetadata<
+      137,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4BeginOrderedTruncateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4BeginOrderedTruncate kExt4BeginOrderedTruncate{};
+  template <typename T = Ext4BeginOrderedTruncateFtraceEvent> T* set_ext4_begin_ordered_truncate() {
+    return BeginNestedMessage<T>(137);
+  }
+
+
+  using FieldMetadata_Ext4CollapseRange =
+    ::protozero::proto_utils::FieldMetadata<
+      138,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4CollapseRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4CollapseRange kExt4CollapseRange{};
+  template <typename T = Ext4CollapseRangeFtraceEvent> T* set_ext4_collapse_range() {
+    return BeginNestedMessage<T>(138);
+  }
+
+
+  using FieldMetadata_Ext4DaReleaseSpace =
+    ::protozero::proto_utils::FieldMetadata<
+      139,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaReleaseSpaceFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaReleaseSpace kExt4DaReleaseSpace{};
+  template <typename T = Ext4DaReleaseSpaceFtraceEvent> T* set_ext4_da_release_space() {
+    return BeginNestedMessage<T>(139);
+  }
+
+
+  using FieldMetadata_Ext4DaReserveSpace =
+    ::protozero::proto_utils::FieldMetadata<
+      140,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaReserveSpaceFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaReserveSpace kExt4DaReserveSpace{};
+  template <typename T = Ext4DaReserveSpaceFtraceEvent> T* set_ext4_da_reserve_space() {
+    return BeginNestedMessage<T>(140);
+  }
+
+
+  using FieldMetadata_Ext4DaUpdateReserveSpace =
+    ::protozero::proto_utils::FieldMetadata<
+      141,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaUpdateReserveSpaceFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaUpdateReserveSpace kExt4DaUpdateReserveSpace{};
+  template <typename T = Ext4DaUpdateReserveSpaceFtraceEvent> T* set_ext4_da_update_reserve_space() {
+    return BeginNestedMessage<T>(141);
+  }
+
+
+  using FieldMetadata_Ext4DaWritePages =
+    ::protozero::proto_utils::FieldMetadata<
+      142,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaWritePagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaWritePages kExt4DaWritePages{};
+  template <typename T = Ext4DaWritePagesFtraceEvent> T* set_ext4_da_write_pages() {
+    return BeginNestedMessage<T>(142);
+  }
+
+
+  using FieldMetadata_Ext4DaWritePagesExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      143,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DaWritePagesExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DaWritePagesExtent kExt4DaWritePagesExtent{};
+  template <typename T = Ext4DaWritePagesExtentFtraceEvent> T* set_ext4_da_write_pages_extent() {
+    return BeginNestedMessage<T>(143);
+  }
+
+
+  using FieldMetadata_Ext4DirectIOEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      144,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DirectIOEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DirectIOEnter kExt4DirectIOEnter{};
+  template <typename T = Ext4DirectIOEnterFtraceEvent> T* set_ext4_direct_io_enter() {
+    return BeginNestedMessage<T>(144);
+  }
+
+
+  using FieldMetadata_Ext4DirectIOExit =
+    ::protozero::proto_utils::FieldMetadata<
+      145,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DirectIOExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DirectIOExit kExt4DirectIOExit{};
+  template <typename T = Ext4DirectIOExitFtraceEvent> T* set_ext4_direct_io_exit() {
+    return BeginNestedMessage<T>(145);
+  }
+
+
+  using FieldMetadata_Ext4DiscardBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      146,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DiscardBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DiscardBlocks kExt4DiscardBlocks{};
+  template <typename T = Ext4DiscardBlocksFtraceEvent> T* set_ext4_discard_blocks() {
+    return BeginNestedMessage<T>(146);
+  }
+
+
+  using FieldMetadata_Ext4DiscardPreallocations =
+    ::protozero::proto_utils::FieldMetadata<
+      147,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DiscardPreallocationsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DiscardPreallocations kExt4DiscardPreallocations{};
+  template <typename T = Ext4DiscardPreallocationsFtraceEvent> T* set_ext4_discard_preallocations() {
+    return BeginNestedMessage<T>(147);
+  }
+
+
+  using FieldMetadata_Ext4DropInode =
+    ::protozero::proto_utils::FieldMetadata<
+      148,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4DropInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4DropInode kExt4DropInode{};
+  template <typename T = Ext4DropInodeFtraceEvent> T* set_ext4_drop_inode() {
+    return BeginNestedMessage<T>(148);
+  }
+
+
+  using FieldMetadata_Ext4EsCacheExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      149,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsCacheExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsCacheExtent kExt4EsCacheExtent{};
+  template <typename T = Ext4EsCacheExtentFtraceEvent> T* set_ext4_es_cache_extent() {
+    return BeginNestedMessage<T>(149);
+  }
+
+
+  using FieldMetadata_Ext4EsFindDelayedExtentRangeEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      150,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsFindDelayedExtentRangeEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsFindDelayedExtentRangeEnter kExt4EsFindDelayedExtentRangeEnter{};
+  template <typename T = Ext4EsFindDelayedExtentRangeEnterFtraceEvent> T* set_ext4_es_find_delayed_extent_range_enter() {
+    return BeginNestedMessage<T>(150);
+  }
+
+
+  using FieldMetadata_Ext4EsFindDelayedExtentRangeExit =
+    ::protozero::proto_utils::FieldMetadata<
+      151,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsFindDelayedExtentRangeExit kExt4EsFindDelayedExtentRangeExit{};
+  template <typename T = Ext4EsFindDelayedExtentRangeExitFtraceEvent> T* set_ext4_es_find_delayed_extent_range_exit() {
+    return BeginNestedMessage<T>(151);
+  }
+
+
+  using FieldMetadata_Ext4EsInsertExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      152,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsInsertExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsInsertExtent kExt4EsInsertExtent{};
+  template <typename T = Ext4EsInsertExtentFtraceEvent> T* set_ext4_es_insert_extent() {
+    return BeginNestedMessage<T>(152);
+  }
+
+
+  using FieldMetadata_Ext4EsLookupExtentEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      153,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsLookupExtentEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsLookupExtentEnter kExt4EsLookupExtentEnter{};
+  template <typename T = Ext4EsLookupExtentEnterFtraceEvent> T* set_ext4_es_lookup_extent_enter() {
+    return BeginNestedMessage<T>(153);
+  }
+
+
+  using FieldMetadata_Ext4EsLookupExtentExit =
+    ::protozero::proto_utils::FieldMetadata<
+      154,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsLookupExtentExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsLookupExtentExit kExt4EsLookupExtentExit{};
+  template <typename T = Ext4EsLookupExtentExitFtraceEvent> T* set_ext4_es_lookup_extent_exit() {
+    return BeginNestedMessage<T>(154);
+  }
+
+
+  using FieldMetadata_Ext4EsRemoveExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      155,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsRemoveExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsRemoveExtent kExt4EsRemoveExtent{};
+  template <typename T = Ext4EsRemoveExtentFtraceEvent> T* set_ext4_es_remove_extent() {
+    return BeginNestedMessage<T>(155);
+  }
+
+
+  using FieldMetadata_Ext4EsShrink =
+    ::protozero::proto_utils::FieldMetadata<
+      156,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsShrinkFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsShrink kExt4EsShrink{};
+  template <typename T = Ext4EsShrinkFtraceEvent> T* set_ext4_es_shrink() {
+    return BeginNestedMessage<T>(156);
+  }
+
+
+  using FieldMetadata_Ext4EsShrinkCount =
+    ::protozero::proto_utils::FieldMetadata<
+      157,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsShrinkCountFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsShrinkCount kExt4EsShrinkCount{};
+  template <typename T = Ext4EsShrinkCountFtraceEvent> T* set_ext4_es_shrink_count() {
+    return BeginNestedMessage<T>(157);
+  }
+
+
+  using FieldMetadata_Ext4EsShrinkScanEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      158,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsShrinkScanEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsShrinkScanEnter kExt4EsShrinkScanEnter{};
+  template <typename T = Ext4EsShrinkScanEnterFtraceEvent> T* set_ext4_es_shrink_scan_enter() {
+    return BeginNestedMessage<T>(158);
+  }
+
+
+  using FieldMetadata_Ext4EsShrinkScanExit =
+    ::protozero::proto_utils::FieldMetadata<
+      159,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EsShrinkScanExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EsShrinkScanExit kExt4EsShrinkScanExit{};
+  template <typename T = Ext4EsShrinkScanExitFtraceEvent> T* set_ext4_es_shrink_scan_exit() {
+    return BeginNestedMessage<T>(159);
+  }
+
+
+  using FieldMetadata_Ext4EvictInode =
+    ::protozero::proto_utils::FieldMetadata<
+      160,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4EvictInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4EvictInode kExt4EvictInode{};
+  template <typename T = Ext4EvictInodeFtraceEvent> T* set_ext4_evict_inode() {
+    return BeginNestedMessage<T>(160);
+  }
+
+
+  using FieldMetadata_Ext4ExtConvertToInitializedEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      161,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtConvertToInitializedEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtConvertToInitializedEnter kExt4ExtConvertToInitializedEnter{};
+  template <typename T = Ext4ExtConvertToInitializedEnterFtraceEvent> T* set_ext4_ext_convert_to_initialized_enter() {
+    return BeginNestedMessage<T>(161);
+  }
+
+
+  using FieldMetadata_Ext4ExtConvertToInitializedFastpath =
+    ::protozero::proto_utils::FieldMetadata<
+      162,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtConvertToInitializedFastpath kExt4ExtConvertToInitializedFastpath{};
+  template <typename T = Ext4ExtConvertToInitializedFastpathFtraceEvent> T* set_ext4_ext_convert_to_initialized_fastpath() {
+    return BeginNestedMessage<T>(162);
+  }
+
+
+  using FieldMetadata_Ext4ExtHandleUnwrittenExtents =
+    ::protozero::proto_utils::FieldMetadata<
+      163,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtHandleUnwrittenExtents kExt4ExtHandleUnwrittenExtents{};
+  template <typename T = Ext4ExtHandleUnwrittenExtentsFtraceEvent> T* set_ext4_ext_handle_unwritten_extents() {
+    return BeginNestedMessage<T>(163);
+  }
+
+
+  using FieldMetadata_Ext4ExtInCache =
+    ::protozero::proto_utils::FieldMetadata<
+      164,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtInCacheFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtInCache kExt4ExtInCache{};
+  template <typename T = Ext4ExtInCacheFtraceEvent> T* set_ext4_ext_in_cache() {
+    return BeginNestedMessage<T>(164);
+  }
+
+
+  using FieldMetadata_Ext4ExtLoadExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      165,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtLoadExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtLoadExtent kExt4ExtLoadExtent{};
+  template <typename T = Ext4ExtLoadExtentFtraceEvent> T* set_ext4_ext_load_extent() {
+    return BeginNestedMessage<T>(165);
+  }
+
+
+  using FieldMetadata_Ext4ExtMapBlocksEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      166,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtMapBlocksEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtMapBlocksEnter kExt4ExtMapBlocksEnter{};
+  template <typename T = Ext4ExtMapBlocksEnterFtraceEvent> T* set_ext4_ext_map_blocks_enter() {
+    return BeginNestedMessage<T>(166);
+  }
+
+
+  using FieldMetadata_Ext4ExtMapBlocksExit =
+    ::protozero::proto_utils::FieldMetadata<
+      167,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtMapBlocksExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtMapBlocksExit kExt4ExtMapBlocksExit{};
+  template <typename T = Ext4ExtMapBlocksExitFtraceEvent> T* set_ext4_ext_map_blocks_exit() {
+    return BeginNestedMessage<T>(167);
+  }
+
+
+  using FieldMetadata_Ext4ExtPutInCache =
+    ::protozero::proto_utils::FieldMetadata<
+      168,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtPutInCacheFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtPutInCache kExt4ExtPutInCache{};
+  template <typename T = Ext4ExtPutInCacheFtraceEvent> T* set_ext4_ext_put_in_cache() {
+    return BeginNestedMessage<T>(168);
+  }
+
+
+  using FieldMetadata_Ext4ExtRemoveSpace =
+    ::protozero::proto_utils::FieldMetadata<
+      169,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtRemoveSpaceFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtRemoveSpace kExt4ExtRemoveSpace{};
+  template <typename T = Ext4ExtRemoveSpaceFtraceEvent> T* set_ext4_ext_remove_space() {
+    return BeginNestedMessage<T>(169);
+  }
+
+
+  using FieldMetadata_Ext4ExtRemoveSpaceDone =
+    ::protozero::proto_utils::FieldMetadata<
+      170,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtRemoveSpaceDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtRemoveSpaceDone kExt4ExtRemoveSpaceDone{};
+  template <typename T = Ext4ExtRemoveSpaceDoneFtraceEvent> T* set_ext4_ext_remove_space_done() {
+    return BeginNestedMessage<T>(170);
+  }
+
+
+  using FieldMetadata_Ext4ExtRmIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      171,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtRmIdxFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtRmIdx kExt4ExtRmIdx{};
+  template <typename T = Ext4ExtRmIdxFtraceEvent> T* set_ext4_ext_rm_idx() {
+    return BeginNestedMessage<T>(171);
+  }
+
+
+  using FieldMetadata_Ext4ExtRmLeaf =
+    ::protozero::proto_utils::FieldMetadata<
+      172,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtRmLeafFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtRmLeaf kExt4ExtRmLeaf{};
+  template <typename T = Ext4ExtRmLeafFtraceEvent> T* set_ext4_ext_rm_leaf() {
+    return BeginNestedMessage<T>(172);
+  }
+
+
+  using FieldMetadata_Ext4ExtShowExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      173,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ExtShowExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ExtShowExtent kExt4ExtShowExtent{};
+  template <typename T = Ext4ExtShowExtentFtraceEvent> T* set_ext4_ext_show_extent() {
+    return BeginNestedMessage<T>(173);
+  }
+
+
+  using FieldMetadata_Ext4FallocateEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      174,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4FallocateEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4FallocateEnter kExt4FallocateEnter{};
+  template <typename T = Ext4FallocateEnterFtraceEvent> T* set_ext4_fallocate_enter() {
+    return BeginNestedMessage<T>(174);
+  }
+
+
+  using FieldMetadata_Ext4FallocateExit =
+    ::protozero::proto_utils::FieldMetadata<
+      175,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4FallocateExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4FallocateExit kExt4FallocateExit{};
+  template <typename T = Ext4FallocateExitFtraceEvent> T* set_ext4_fallocate_exit() {
+    return BeginNestedMessage<T>(175);
+  }
+
+
+  using FieldMetadata_Ext4FindDelallocRange =
+    ::protozero::proto_utils::FieldMetadata<
+      176,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4FindDelallocRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4FindDelallocRange kExt4FindDelallocRange{};
+  template <typename T = Ext4FindDelallocRangeFtraceEvent> T* set_ext4_find_delalloc_range() {
+    return BeginNestedMessage<T>(176);
+  }
+
+
+  using FieldMetadata_Ext4Forget =
+    ::protozero::proto_utils::FieldMetadata<
+      177,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ForgetFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Forget kExt4Forget{};
+  template <typename T = Ext4ForgetFtraceEvent> T* set_ext4_forget() {
+    return BeginNestedMessage<T>(177);
+  }
+
+
+  using FieldMetadata_Ext4FreeBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      178,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4FreeBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4FreeBlocks kExt4FreeBlocks{};
+  template <typename T = Ext4FreeBlocksFtraceEvent> T* set_ext4_free_blocks() {
+    return BeginNestedMessage<T>(178);
+  }
+
+
+  using FieldMetadata_Ext4FreeInode =
+    ::protozero::proto_utils::FieldMetadata<
+      179,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4FreeInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4FreeInode kExt4FreeInode{};
+  template <typename T = Ext4FreeInodeFtraceEvent> T* set_ext4_free_inode() {
+    return BeginNestedMessage<T>(179);
+  }
+
+
+  using FieldMetadata_Ext4GetImpliedClusterAllocExit =
+    ::protozero::proto_utils::FieldMetadata<
+      180,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4GetImpliedClusterAllocExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4GetImpliedClusterAllocExit kExt4GetImpliedClusterAllocExit{};
+  template <typename T = Ext4GetImpliedClusterAllocExitFtraceEvent> T* set_ext4_get_implied_cluster_alloc_exit() {
+    return BeginNestedMessage<T>(180);
+  }
+
+
+  using FieldMetadata_Ext4GetReservedClusterAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      181,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4GetReservedClusterAllocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4GetReservedClusterAlloc kExt4GetReservedClusterAlloc{};
+  template <typename T = Ext4GetReservedClusterAllocFtraceEvent> T* set_ext4_get_reserved_cluster_alloc() {
+    return BeginNestedMessage<T>(181);
+  }
+
+
+  using FieldMetadata_Ext4IndMapBlocksEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      182,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4IndMapBlocksEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4IndMapBlocksEnter kExt4IndMapBlocksEnter{};
+  template <typename T = Ext4IndMapBlocksEnterFtraceEvent> T* set_ext4_ind_map_blocks_enter() {
+    return BeginNestedMessage<T>(182);
+  }
+
+
+  using FieldMetadata_Ext4IndMapBlocksExit =
+    ::protozero::proto_utils::FieldMetadata<
+      183,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4IndMapBlocksExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4IndMapBlocksExit kExt4IndMapBlocksExit{};
+  template <typename T = Ext4IndMapBlocksExitFtraceEvent> T* set_ext4_ind_map_blocks_exit() {
+    return BeginNestedMessage<T>(183);
+  }
+
+
+  using FieldMetadata_Ext4InsertRange =
+    ::protozero::proto_utils::FieldMetadata<
+      184,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4InsertRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4InsertRange kExt4InsertRange{};
+  template <typename T = Ext4InsertRangeFtraceEvent> T* set_ext4_insert_range() {
+    return BeginNestedMessage<T>(184);
+  }
+
+
+  using FieldMetadata_Ext4Invalidatepage =
+    ::protozero::proto_utils::FieldMetadata<
+      185,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4InvalidatepageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Invalidatepage kExt4Invalidatepage{};
+  template <typename T = Ext4InvalidatepageFtraceEvent> T* set_ext4_invalidatepage() {
+    return BeginNestedMessage<T>(185);
+  }
+
+
+  using FieldMetadata_Ext4JournalStart =
+    ::protozero::proto_utils::FieldMetadata<
+      186,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4JournalStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4JournalStart kExt4JournalStart{};
+  template <typename T = Ext4JournalStartFtraceEvent> T* set_ext4_journal_start() {
+    return BeginNestedMessage<T>(186);
+  }
+
+
+  using FieldMetadata_Ext4JournalStartReserved =
+    ::protozero::proto_utils::FieldMetadata<
+      187,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4JournalStartReservedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4JournalStartReserved kExt4JournalStartReserved{};
+  template <typename T = Ext4JournalStartReservedFtraceEvent> T* set_ext4_journal_start_reserved() {
+    return BeginNestedMessage<T>(187);
+  }
+
+
+  using FieldMetadata_Ext4JournalledInvalidatepage =
+    ::protozero::proto_utils::FieldMetadata<
+      188,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4JournalledInvalidatepageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4JournalledInvalidatepage kExt4JournalledInvalidatepage{};
+  template <typename T = Ext4JournalledInvalidatepageFtraceEvent> T* set_ext4_journalled_invalidatepage() {
+    return BeginNestedMessage<T>(188);
+  }
+
+
+  using FieldMetadata_Ext4JournalledWriteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      189,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4JournalledWriteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4JournalledWriteEnd kExt4JournalledWriteEnd{};
+  template <typename T = Ext4JournalledWriteEndFtraceEvent> T* set_ext4_journalled_write_end() {
+    return BeginNestedMessage<T>(189);
+  }
+
+
+  using FieldMetadata_Ext4LoadInode =
+    ::protozero::proto_utils::FieldMetadata<
+      190,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4LoadInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4LoadInode kExt4LoadInode{};
+  template <typename T = Ext4LoadInodeFtraceEvent> T* set_ext4_load_inode() {
+    return BeginNestedMessage<T>(190);
+  }
+
+
+  using FieldMetadata_Ext4LoadInodeBitmap =
+    ::protozero::proto_utils::FieldMetadata<
+      191,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4LoadInodeBitmapFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4LoadInodeBitmap kExt4LoadInodeBitmap{};
+  template <typename T = Ext4LoadInodeBitmapFtraceEvent> T* set_ext4_load_inode_bitmap() {
+    return BeginNestedMessage<T>(191);
+  }
+
+
+  using FieldMetadata_Ext4MarkInodeDirty =
+    ::protozero::proto_utils::FieldMetadata<
+      192,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MarkInodeDirtyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MarkInodeDirty kExt4MarkInodeDirty{};
+  template <typename T = Ext4MarkInodeDirtyFtraceEvent> T* set_ext4_mark_inode_dirty() {
+    return BeginNestedMessage<T>(192);
+  }
+
+
+  using FieldMetadata_Ext4MbBitmapLoad =
+    ::protozero::proto_utils::FieldMetadata<
+      193,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbBitmapLoadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbBitmapLoad kExt4MbBitmapLoad{};
+  template <typename T = Ext4MbBitmapLoadFtraceEvent> T* set_ext4_mb_bitmap_load() {
+    return BeginNestedMessage<T>(193);
+  }
+
+
+  using FieldMetadata_Ext4MbBuddyBitmapLoad =
+    ::protozero::proto_utils::FieldMetadata<
+      194,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbBuddyBitmapLoadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbBuddyBitmapLoad kExt4MbBuddyBitmapLoad{};
+  template <typename T = Ext4MbBuddyBitmapLoadFtraceEvent> T* set_ext4_mb_buddy_bitmap_load() {
+    return BeginNestedMessage<T>(194);
+  }
+
+
+  using FieldMetadata_Ext4MbDiscardPreallocations =
+    ::protozero::proto_utils::FieldMetadata<
+      195,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbDiscardPreallocationsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbDiscardPreallocations kExt4MbDiscardPreallocations{};
+  template <typename T = Ext4MbDiscardPreallocationsFtraceEvent> T* set_ext4_mb_discard_preallocations() {
+    return BeginNestedMessage<T>(195);
+  }
+
+
+  using FieldMetadata_Ext4MbNewGroupPa =
+    ::protozero::proto_utils::FieldMetadata<
+      196,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbNewGroupPaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbNewGroupPa kExt4MbNewGroupPa{};
+  template <typename T = Ext4MbNewGroupPaFtraceEvent> T* set_ext4_mb_new_group_pa() {
+    return BeginNestedMessage<T>(196);
+  }
+
+
+  using FieldMetadata_Ext4MbNewInodePa =
+    ::protozero::proto_utils::FieldMetadata<
+      197,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbNewInodePaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbNewInodePa kExt4MbNewInodePa{};
+  template <typename T = Ext4MbNewInodePaFtraceEvent> T* set_ext4_mb_new_inode_pa() {
+    return BeginNestedMessage<T>(197);
+  }
+
+
+  using FieldMetadata_Ext4MbReleaseGroupPa =
+    ::protozero::proto_utils::FieldMetadata<
+      198,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbReleaseGroupPaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbReleaseGroupPa kExt4MbReleaseGroupPa{};
+  template <typename T = Ext4MbReleaseGroupPaFtraceEvent> T* set_ext4_mb_release_group_pa() {
+    return BeginNestedMessage<T>(198);
+  }
+
+
+  using FieldMetadata_Ext4MbReleaseInodePa =
+    ::protozero::proto_utils::FieldMetadata<
+      199,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MbReleaseInodePaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MbReleaseInodePa kExt4MbReleaseInodePa{};
+  template <typename T = Ext4MbReleaseInodePaFtraceEvent> T* set_ext4_mb_release_inode_pa() {
+    return BeginNestedMessage<T>(199);
+  }
+
+
+  using FieldMetadata_Ext4MballocAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      200,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MballocAllocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MballocAlloc kExt4MballocAlloc{};
+  template <typename T = Ext4MballocAllocFtraceEvent> T* set_ext4_mballoc_alloc() {
+    return BeginNestedMessage<T>(200);
+  }
+
+
+  using FieldMetadata_Ext4MballocDiscard =
+    ::protozero::proto_utils::FieldMetadata<
+      201,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MballocDiscardFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MballocDiscard kExt4MballocDiscard{};
+  template <typename T = Ext4MballocDiscardFtraceEvent> T* set_ext4_mballoc_discard() {
+    return BeginNestedMessage<T>(201);
+  }
+
+
+  using FieldMetadata_Ext4MballocFree =
+    ::protozero::proto_utils::FieldMetadata<
+      202,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MballocFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MballocFree kExt4MballocFree{};
+  template <typename T = Ext4MballocFreeFtraceEvent> T* set_ext4_mballoc_free() {
+    return BeginNestedMessage<T>(202);
+  }
+
+
+  using FieldMetadata_Ext4MballocPrealloc =
+    ::protozero::proto_utils::FieldMetadata<
+      203,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4MballocPreallocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4MballocPrealloc kExt4MballocPrealloc{};
+  template <typename T = Ext4MballocPreallocFtraceEvent> T* set_ext4_mballoc_prealloc() {
+    return BeginNestedMessage<T>(203);
+  }
+
+
+  using FieldMetadata_Ext4OtherInodeUpdateTime =
+    ::protozero::proto_utils::FieldMetadata<
+      204,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4OtherInodeUpdateTimeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4OtherInodeUpdateTime kExt4OtherInodeUpdateTime{};
+  template <typename T = Ext4OtherInodeUpdateTimeFtraceEvent> T* set_ext4_other_inode_update_time() {
+    return BeginNestedMessage<T>(204);
+  }
+
+
+  using FieldMetadata_Ext4PunchHole =
+    ::protozero::proto_utils::FieldMetadata<
+      205,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4PunchHoleFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4PunchHole kExt4PunchHole{};
+  template <typename T = Ext4PunchHoleFtraceEvent> T* set_ext4_punch_hole() {
+    return BeginNestedMessage<T>(205);
+  }
+
+
+  using FieldMetadata_Ext4ReadBlockBitmapLoad =
+    ::protozero::proto_utils::FieldMetadata<
+      206,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ReadBlockBitmapLoadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ReadBlockBitmapLoad kExt4ReadBlockBitmapLoad{};
+  template <typename T = Ext4ReadBlockBitmapLoadFtraceEvent> T* set_ext4_read_block_bitmap_load() {
+    return BeginNestedMessage<T>(206);
+  }
+
+
+  using FieldMetadata_Ext4Readpage =
+    ::protozero::proto_utils::FieldMetadata<
+      207,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ReadpageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Readpage kExt4Readpage{};
+  template <typename T = Ext4ReadpageFtraceEvent> T* set_ext4_readpage() {
+    return BeginNestedMessage<T>(207);
+  }
+
+
+  using FieldMetadata_Ext4Releasepage =
+    ::protozero::proto_utils::FieldMetadata<
+      208,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ReleasepageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Releasepage kExt4Releasepage{};
+  template <typename T = Ext4ReleasepageFtraceEvent> T* set_ext4_releasepage() {
+    return BeginNestedMessage<T>(208);
+  }
+
+
+  using FieldMetadata_Ext4RemoveBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      209,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4RemoveBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4RemoveBlocks kExt4RemoveBlocks{};
+  template <typename T = Ext4RemoveBlocksFtraceEvent> T* set_ext4_remove_blocks() {
+    return BeginNestedMessage<T>(209);
+  }
+
+
+  using FieldMetadata_Ext4RequestBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      210,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4RequestBlocksFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4RequestBlocks kExt4RequestBlocks{};
+  template <typename T = Ext4RequestBlocksFtraceEvent> T* set_ext4_request_blocks() {
+    return BeginNestedMessage<T>(210);
+  }
+
+
+  using FieldMetadata_Ext4RequestInode =
+    ::protozero::proto_utils::FieldMetadata<
+      211,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4RequestInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4RequestInode kExt4RequestInode{};
+  template <typename T = Ext4RequestInodeFtraceEvent> T* set_ext4_request_inode() {
+    return BeginNestedMessage<T>(211);
+  }
+
+
+  using FieldMetadata_Ext4SyncFs =
+    ::protozero::proto_utils::FieldMetadata<
+      212,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4SyncFsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4SyncFs kExt4SyncFs{};
+  template <typename T = Ext4SyncFsFtraceEvent> T* set_ext4_sync_fs() {
+    return BeginNestedMessage<T>(212);
+  }
+
+
+  using FieldMetadata_Ext4TrimAllFree =
+    ::protozero::proto_utils::FieldMetadata<
+      213,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4TrimAllFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4TrimAllFree kExt4TrimAllFree{};
+  template <typename T = Ext4TrimAllFreeFtraceEvent> T* set_ext4_trim_all_free() {
+    return BeginNestedMessage<T>(213);
+  }
+
+
+  using FieldMetadata_Ext4TrimExtent =
+    ::protozero::proto_utils::FieldMetadata<
+      214,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4TrimExtentFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4TrimExtent kExt4TrimExtent{};
+  template <typename T = Ext4TrimExtentFtraceEvent> T* set_ext4_trim_extent() {
+    return BeginNestedMessage<T>(214);
+  }
+
+
+  using FieldMetadata_Ext4TruncateEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      215,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4TruncateEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4TruncateEnter kExt4TruncateEnter{};
+  template <typename T = Ext4TruncateEnterFtraceEvent> T* set_ext4_truncate_enter() {
+    return BeginNestedMessage<T>(215);
+  }
+
+
+  using FieldMetadata_Ext4TruncateExit =
+    ::protozero::proto_utils::FieldMetadata<
+      216,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4TruncateExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4TruncateExit kExt4TruncateExit{};
+  template <typename T = Ext4TruncateExitFtraceEvent> T* set_ext4_truncate_exit() {
+    return BeginNestedMessage<T>(216);
+  }
+
+
+  using FieldMetadata_Ext4UnlinkEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      217,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4UnlinkEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4UnlinkEnter kExt4UnlinkEnter{};
+  template <typename T = Ext4UnlinkEnterFtraceEvent> T* set_ext4_unlink_enter() {
+    return BeginNestedMessage<T>(217);
+  }
+
+
+  using FieldMetadata_Ext4UnlinkExit =
+    ::protozero::proto_utils::FieldMetadata<
+      218,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4UnlinkExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4UnlinkExit kExt4UnlinkExit{};
+  template <typename T = Ext4UnlinkExitFtraceEvent> T* set_ext4_unlink_exit() {
+    return BeginNestedMessage<T>(218);
+  }
+
+
+  using FieldMetadata_Ext4WriteBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      219,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4WriteBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4WriteBegin kExt4WriteBegin{};
+  template <typename T = Ext4WriteBeginFtraceEvent> T* set_ext4_write_begin() {
+    return BeginNestedMessage<T>(219);
+  }
+
+
+  using FieldMetadata_Ext4WriteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      230,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4WriteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4WriteEnd kExt4WriteEnd{};
+  template <typename T = Ext4WriteEndFtraceEvent> T* set_ext4_write_end() {
+    return BeginNestedMessage<T>(230);
+  }
+
+
+  using FieldMetadata_Ext4Writepage =
+    ::protozero::proto_utils::FieldMetadata<
+      231,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4WritepageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Writepage kExt4Writepage{};
+  template <typename T = Ext4WritepageFtraceEvent> T* set_ext4_writepage() {
+    return BeginNestedMessage<T>(231);
+  }
+
+
+  using FieldMetadata_Ext4Writepages =
+    ::protozero::proto_utils::FieldMetadata<
+      232,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4WritepagesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4Writepages kExt4Writepages{};
+  template <typename T = Ext4WritepagesFtraceEvent> T* set_ext4_writepages() {
+    return BeginNestedMessage<T>(232);
+  }
+
+
+  using FieldMetadata_Ext4WritepagesResult =
+    ::protozero::proto_utils::FieldMetadata<
+      233,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4WritepagesResultFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4WritepagesResult kExt4WritepagesResult{};
+  template <typename T = Ext4WritepagesResultFtraceEvent> T* set_ext4_writepages_result() {
+    return BeginNestedMessage<T>(233);
+  }
+
+
+  using FieldMetadata_Ext4ZeroRange =
+    ::protozero::proto_utils::FieldMetadata<
+      234,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Ext4ZeroRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Ext4ZeroRange kExt4ZeroRange{};
+  template <typename T = Ext4ZeroRangeFtraceEvent> T* set_ext4_zero_range() {
+    return BeginNestedMessage<T>(234);
+  }
+
+
+  using FieldMetadata_TaskNewtask =
+    ::protozero::proto_utils::FieldMetadata<
+      235,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TaskNewtaskFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TaskNewtask kTaskNewtask{};
+  template <typename T = TaskNewtaskFtraceEvent> T* set_task_newtask() {
+    return BeginNestedMessage<T>(235);
+  }
+
+
+  using FieldMetadata_TaskRename =
+    ::protozero::proto_utils::FieldMetadata<
+      236,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TaskRenameFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TaskRename kTaskRename{};
+  template <typename T = TaskRenameFtraceEvent> T* set_task_rename() {
+    return BeginNestedMessage<T>(236);
+  }
+
+
+  using FieldMetadata_SchedProcessExec =
+    ::protozero::proto_utils::FieldMetadata<
+      237,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessExecFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessExec kSchedProcessExec{};
+  template <typename T = SchedProcessExecFtraceEvent> T* set_sched_process_exec() {
+    return BeginNestedMessage<T>(237);
+  }
+
+
+  using FieldMetadata_SchedProcessExit =
+    ::protozero::proto_utils::FieldMetadata<
+      238,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessExit kSchedProcessExit{};
+  template <typename T = SchedProcessExitFtraceEvent> T* set_sched_process_exit() {
+    return BeginNestedMessage<T>(238);
+  }
+
+
+  using FieldMetadata_SchedProcessFork =
+    ::protozero::proto_utils::FieldMetadata<
+      239,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessForkFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessFork kSchedProcessFork{};
+  template <typename T = SchedProcessForkFtraceEvent> T* set_sched_process_fork() {
+    return BeginNestedMessage<T>(239);
+  }
+
+
+  using FieldMetadata_SchedProcessFree =
+    ::protozero::proto_utils::FieldMetadata<
+      240,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessFree kSchedProcessFree{};
+  template <typename T = SchedProcessFreeFtraceEvent> T* set_sched_process_free() {
+    return BeginNestedMessage<T>(240);
+  }
+
+
+  using FieldMetadata_SchedProcessHang =
+    ::protozero::proto_utils::FieldMetadata<
+      241,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessHangFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessHang kSchedProcessHang{};
+  template <typename T = SchedProcessHangFtraceEvent> T* set_sched_process_hang() {
+    return BeginNestedMessage<T>(241);
+  }
+
+
+  using FieldMetadata_SchedProcessWait =
+    ::protozero::proto_utils::FieldMetadata<
+      242,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedProcessWaitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedProcessWait kSchedProcessWait{};
+  template <typename T = SchedProcessWaitFtraceEvent> T* set_sched_process_wait() {
+    return BeginNestedMessage<T>(242);
+  }
+
+
+  using FieldMetadata_F2fsDoSubmitBio =
+    ::protozero::proto_utils::FieldMetadata<
+      243,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsDoSubmitBioFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsDoSubmitBio kF2fsDoSubmitBio{};
+  template <typename T = F2fsDoSubmitBioFtraceEvent> T* set_f2fs_do_submit_bio() {
+    return BeginNestedMessage<T>(243);
+  }
+
+
+  using FieldMetadata_F2fsEvictInode =
+    ::protozero::proto_utils::FieldMetadata<
+      244,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsEvictInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsEvictInode kF2fsEvictInode{};
+  template <typename T = F2fsEvictInodeFtraceEvent> T* set_f2fs_evict_inode() {
+    return BeginNestedMessage<T>(244);
+  }
+
+
+  using FieldMetadata_F2fsFallocate =
+    ::protozero::proto_utils::FieldMetadata<
+      245,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsFallocateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsFallocate kF2fsFallocate{};
+  template <typename T = F2fsFallocateFtraceEvent> T* set_f2fs_fallocate() {
+    return BeginNestedMessage<T>(245);
+  }
+
+
+  using FieldMetadata_F2fsGetDataBlock =
+    ::protozero::proto_utils::FieldMetadata<
+      246,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsGetDataBlockFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsGetDataBlock kF2fsGetDataBlock{};
+  template <typename T = F2fsGetDataBlockFtraceEvent> T* set_f2fs_get_data_block() {
+    return BeginNestedMessage<T>(246);
+  }
+
+
+  using FieldMetadata_F2fsGetVictim =
+    ::protozero::proto_utils::FieldMetadata<
+      247,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsGetVictimFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsGetVictim kF2fsGetVictim{};
+  template <typename T = F2fsGetVictimFtraceEvent> T* set_f2fs_get_victim() {
+    return BeginNestedMessage<T>(247);
+  }
+
+
+  using FieldMetadata_F2fsIget =
+    ::protozero::proto_utils::FieldMetadata<
+      248,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsIgetFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsIget kF2fsIget{};
+  template <typename T = F2fsIgetFtraceEvent> T* set_f2fs_iget() {
+    return BeginNestedMessage<T>(248);
+  }
+
+
+  using FieldMetadata_F2fsIgetExit =
+    ::protozero::proto_utils::FieldMetadata<
+      249,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsIgetExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsIgetExit kF2fsIgetExit{};
+  template <typename T = F2fsIgetExitFtraceEvent> T* set_f2fs_iget_exit() {
+    return BeginNestedMessage<T>(249);
+  }
+
+
+  using FieldMetadata_F2fsNewInode =
+    ::protozero::proto_utils::FieldMetadata<
+      250,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsNewInodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsNewInode kF2fsNewInode{};
+  template <typename T = F2fsNewInodeFtraceEvent> T* set_f2fs_new_inode() {
+    return BeginNestedMessage<T>(250);
+  }
+
+
+  using FieldMetadata_F2fsReadpage =
+    ::protozero::proto_utils::FieldMetadata<
+      251,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsReadpageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsReadpage kF2fsReadpage{};
+  template <typename T = F2fsReadpageFtraceEvent> T* set_f2fs_readpage() {
+    return BeginNestedMessage<T>(251);
+  }
+
+
+  using FieldMetadata_F2fsReserveNewBlock =
+    ::protozero::proto_utils::FieldMetadata<
+      252,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsReserveNewBlockFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsReserveNewBlock kF2fsReserveNewBlock{};
+  template <typename T = F2fsReserveNewBlockFtraceEvent> T* set_f2fs_reserve_new_block() {
+    return BeginNestedMessage<T>(252);
+  }
+
+
+  using FieldMetadata_F2fsSetPageDirty =
+    ::protozero::proto_utils::FieldMetadata<
+      253,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsSetPageDirtyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsSetPageDirty kF2fsSetPageDirty{};
+  template <typename T = F2fsSetPageDirtyFtraceEvent> T* set_f2fs_set_page_dirty() {
+    return BeginNestedMessage<T>(253);
+  }
+
+
+  using FieldMetadata_F2fsSubmitWritePage =
+    ::protozero::proto_utils::FieldMetadata<
+      254,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsSubmitWritePageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsSubmitWritePage kF2fsSubmitWritePage{};
+  template <typename T = F2fsSubmitWritePageFtraceEvent> T* set_f2fs_submit_write_page() {
+    return BeginNestedMessage<T>(254);
+  }
+
+
+  using FieldMetadata_F2fsSyncFileEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      255,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsSyncFileEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsSyncFileEnter kF2fsSyncFileEnter{};
+  template <typename T = F2fsSyncFileEnterFtraceEvent> T* set_f2fs_sync_file_enter() {
+    return BeginNestedMessage<T>(255);
+  }
+
+
+  using FieldMetadata_F2fsSyncFileExit =
+    ::protozero::proto_utils::FieldMetadata<
+      256,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsSyncFileExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsSyncFileExit kF2fsSyncFileExit{};
+  template <typename T = F2fsSyncFileExitFtraceEvent> T* set_f2fs_sync_file_exit() {
+    return BeginNestedMessage<T>(256);
+  }
+
+
+  using FieldMetadata_F2fsSyncFs =
+    ::protozero::proto_utils::FieldMetadata<
+      257,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsSyncFsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsSyncFs kF2fsSyncFs{};
+  template <typename T = F2fsSyncFsFtraceEvent> T* set_f2fs_sync_fs() {
+    return BeginNestedMessage<T>(257);
+  }
+
+
+  using FieldMetadata_F2fsTruncate =
+    ::protozero::proto_utils::FieldMetadata<
+      258,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncate kF2fsTruncate{};
+  template <typename T = F2fsTruncateFtraceEvent> T* set_f2fs_truncate() {
+    return BeginNestedMessage<T>(258);
+  }
+
+
+  using FieldMetadata_F2fsTruncateBlocksEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      259,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateBlocksEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateBlocksEnter kF2fsTruncateBlocksEnter{};
+  template <typename T = F2fsTruncateBlocksEnterFtraceEvent> T* set_f2fs_truncate_blocks_enter() {
+    return BeginNestedMessage<T>(259);
+  }
+
+
+  using FieldMetadata_F2fsTruncateBlocksExit =
+    ::protozero::proto_utils::FieldMetadata<
+      260,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateBlocksExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateBlocksExit kF2fsTruncateBlocksExit{};
+  template <typename T = F2fsTruncateBlocksExitFtraceEvent> T* set_f2fs_truncate_blocks_exit() {
+    return BeginNestedMessage<T>(260);
+  }
+
+
+  using FieldMetadata_F2fsTruncateDataBlocksRange =
+    ::protozero::proto_utils::FieldMetadata<
+      261,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateDataBlocksRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateDataBlocksRange kF2fsTruncateDataBlocksRange{};
+  template <typename T = F2fsTruncateDataBlocksRangeFtraceEvent> T* set_f2fs_truncate_data_blocks_range() {
+    return BeginNestedMessage<T>(261);
+  }
+
+
+  using FieldMetadata_F2fsTruncateInodeBlocksEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      262,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateInodeBlocksEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateInodeBlocksEnter kF2fsTruncateInodeBlocksEnter{};
+  template <typename T = F2fsTruncateInodeBlocksEnterFtraceEvent> T* set_f2fs_truncate_inode_blocks_enter() {
+    return BeginNestedMessage<T>(262);
+  }
+
+
+  using FieldMetadata_F2fsTruncateInodeBlocksExit =
+    ::protozero::proto_utils::FieldMetadata<
+      263,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateInodeBlocksExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateInodeBlocksExit kF2fsTruncateInodeBlocksExit{};
+  template <typename T = F2fsTruncateInodeBlocksExitFtraceEvent> T* set_f2fs_truncate_inode_blocks_exit() {
+    return BeginNestedMessage<T>(263);
+  }
+
+
+  using FieldMetadata_F2fsTruncateNode =
+    ::protozero::proto_utils::FieldMetadata<
+      264,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateNodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateNode kF2fsTruncateNode{};
+  template <typename T = F2fsTruncateNodeFtraceEvent> T* set_f2fs_truncate_node() {
+    return BeginNestedMessage<T>(264);
+  }
+
+
+  using FieldMetadata_F2fsTruncateNodesEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      265,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateNodesEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateNodesEnter kF2fsTruncateNodesEnter{};
+  template <typename T = F2fsTruncateNodesEnterFtraceEvent> T* set_f2fs_truncate_nodes_enter() {
+    return BeginNestedMessage<T>(265);
+  }
+
+
+  using FieldMetadata_F2fsTruncateNodesExit =
+    ::protozero::proto_utils::FieldMetadata<
+      266,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncateNodesExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncateNodesExit kF2fsTruncateNodesExit{};
+  template <typename T = F2fsTruncateNodesExitFtraceEvent> T* set_f2fs_truncate_nodes_exit() {
+    return BeginNestedMessage<T>(266);
+  }
+
+
+  using FieldMetadata_F2fsTruncatePartialNodes =
+    ::protozero::proto_utils::FieldMetadata<
+      267,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsTruncatePartialNodesFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsTruncatePartialNodes kF2fsTruncatePartialNodes{};
+  template <typename T = F2fsTruncatePartialNodesFtraceEvent> T* set_f2fs_truncate_partial_nodes() {
+    return BeginNestedMessage<T>(267);
+  }
+
+
+  using FieldMetadata_F2fsUnlinkEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      268,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsUnlinkEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsUnlinkEnter kF2fsUnlinkEnter{};
+  template <typename T = F2fsUnlinkEnterFtraceEvent> T* set_f2fs_unlink_enter() {
+    return BeginNestedMessage<T>(268);
+  }
+
+
+  using FieldMetadata_F2fsUnlinkExit =
+    ::protozero::proto_utils::FieldMetadata<
+      269,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsUnlinkExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsUnlinkExit kF2fsUnlinkExit{};
+  template <typename T = F2fsUnlinkExitFtraceEvent> T* set_f2fs_unlink_exit() {
+    return BeginNestedMessage<T>(269);
+  }
+
+
+  using FieldMetadata_F2fsVmPageMkwrite =
+    ::protozero::proto_utils::FieldMetadata<
+      270,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsVmPageMkwriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsVmPageMkwrite kF2fsVmPageMkwrite{};
+  template <typename T = F2fsVmPageMkwriteFtraceEvent> T* set_f2fs_vm_page_mkwrite() {
+    return BeginNestedMessage<T>(270);
+  }
+
+
+  using FieldMetadata_F2fsWriteBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      271,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsWriteBeginFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsWriteBegin kF2fsWriteBegin{};
+  template <typename T = F2fsWriteBeginFtraceEvent> T* set_f2fs_write_begin() {
+    return BeginNestedMessage<T>(271);
+  }
+
+
+  using FieldMetadata_F2fsWriteCheckpoint =
+    ::protozero::proto_utils::FieldMetadata<
+      272,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsWriteCheckpointFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsWriteCheckpoint kF2fsWriteCheckpoint{};
+  template <typename T = F2fsWriteCheckpointFtraceEvent> T* set_f2fs_write_checkpoint() {
+    return BeginNestedMessage<T>(272);
+  }
+
+
+  using FieldMetadata_F2fsWriteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      273,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsWriteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsWriteEnd kF2fsWriteEnd{};
+  template <typename T = F2fsWriteEndFtraceEvent> T* set_f2fs_write_end() {
+    return BeginNestedMessage<T>(273);
+  }
+
+
+  using FieldMetadata_AllocPagesIommuEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      274,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesIommuEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesIommuEnd kAllocPagesIommuEnd{};
+  template <typename T = AllocPagesIommuEndFtraceEvent> T* set_alloc_pages_iommu_end() {
+    return BeginNestedMessage<T>(274);
+  }
+
+
+  using FieldMetadata_AllocPagesIommuFail =
+    ::protozero::proto_utils::FieldMetadata<
+      275,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesIommuFailFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesIommuFail kAllocPagesIommuFail{};
+  template <typename T = AllocPagesIommuFailFtraceEvent> T* set_alloc_pages_iommu_fail() {
+    return BeginNestedMessage<T>(275);
+  }
+
+
+  using FieldMetadata_AllocPagesIommuStart =
+    ::protozero::proto_utils::FieldMetadata<
+      276,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesIommuStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesIommuStart kAllocPagesIommuStart{};
+  template <typename T = AllocPagesIommuStartFtraceEvent> T* set_alloc_pages_iommu_start() {
+    return BeginNestedMessage<T>(276);
+  }
+
+
+  using FieldMetadata_AllocPagesSysEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      277,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesSysEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesSysEnd kAllocPagesSysEnd{};
+  template <typename T = AllocPagesSysEndFtraceEvent> T* set_alloc_pages_sys_end() {
+    return BeginNestedMessage<T>(277);
+  }
+
+
+  using FieldMetadata_AllocPagesSysFail =
+    ::protozero::proto_utils::FieldMetadata<
+      278,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesSysFailFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesSysFail kAllocPagesSysFail{};
+  template <typename T = AllocPagesSysFailFtraceEvent> T* set_alloc_pages_sys_fail() {
+    return BeginNestedMessage<T>(278);
+  }
+
+
+  using FieldMetadata_AllocPagesSysStart =
+    ::protozero::proto_utils::FieldMetadata<
+      279,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AllocPagesSysStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AllocPagesSysStart kAllocPagesSysStart{};
+  template <typename T = AllocPagesSysStartFtraceEvent> T* set_alloc_pages_sys_start() {
+    return BeginNestedMessage<T>(279);
+  }
+
+
+  using FieldMetadata_DmaAllocContiguousRetry =
+    ::protozero::proto_utils::FieldMetadata<
+      280,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaAllocContiguousRetryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaAllocContiguousRetry kDmaAllocContiguousRetry{};
+  template <typename T = DmaAllocContiguousRetryFtraceEvent> T* set_dma_alloc_contiguous_retry() {
+    return BeginNestedMessage<T>(280);
+  }
+
+
+  using FieldMetadata_IommuMapRange =
+    ::protozero::proto_utils::FieldMetadata<
+      281,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IommuMapRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IommuMapRange kIommuMapRange{};
+  template <typename T = IommuMapRangeFtraceEvent> T* set_iommu_map_range() {
+    return BeginNestedMessage<T>(281);
+  }
+
+
+  using FieldMetadata_IommuSecPtblMapRangeEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      282,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IommuSecPtblMapRangeEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IommuSecPtblMapRangeEnd kIommuSecPtblMapRangeEnd{};
+  template <typename T = IommuSecPtblMapRangeEndFtraceEvent> T* set_iommu_sec_ptbl_map_range_end() {
+    return BeginNestedMessage<T>(282);
+  }
+
+
+  using FieldMetadata_IommuSecPtblMapRangeStart =
+    ::protozero::proto_utils::FieldMetadata<
+      283,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IommuSecPtblMapRangeStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IommuSecPtblMapRangeStart kIommuSecPtblMapRangeStart{};
+  template <typename T = IommuSecPtblMapRangeStartFtraceEvent> T* set_iommu_sec_ptbl_map_range_start() {
+    return BeginNestedMessage<T>(283);
+  }
+
+
+  using FieldMetadata_IonAllocBufferEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      284,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonAllocBufferEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonAllocBufferEnd kIonAllocBufferEnd{};
+  template <typename T = IonAllocBufferEndFtraceEvent> T* set_ion_alloc_buffer_end() {
+    return BeginNestedMessage<T>(284);
+  }
+
+
+  using FieldMetadata_IonAllocBufferFail =
+    ::protozero::proto_utils::FieldMetadata<
+      285,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonAllocBufferFailFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonAllocBufferFail kIonAllocBufferFail{};
+  template <typename T = IonAllocBufferFailFtraceEvent> T* set_ion_alloc_buffer_fail() {
+    return BeginNestedMessage<T>(285);
+  }
+
+
+  using FieldMetadata_IonAllocBufferFallback =
+    ::protozero::proto_utils::FieldMetadata<
+      286,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonAllocBufferFallbackFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonAllocBufferFallback kIonAllocBufferFallback{};
+  template <typename T = IonAllocBufferFallbackFtraceEvent> T* set_ion_alloc_buffer_fallback() {
+    return BeginNestedMessage<T>(286);
+  }
+
+
+  using FieldMetadata_IonAllocBufferStart =
+    ::protozero::proto_utils::FieldMetadata<
+      287,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonAllocBufferStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonAllocBufferStart kIonAllocBufferStart{};
+  template <typename T = IonAllocBufferStartFtraceEvent> T* set_ion_alloc_buffer_start() {
+    return BeginNestedMessage<T>(287);
+  }
+
+
+  using FieldMetadata_IonCpAllocRetry =
+    ::protozero::proto_utils::FieldMetadata<
+      288,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonCpAllocRetryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonCpAllocRetry kIonCpAllocRetry{};
+  template <typename T = IonCpAllocRetryFtraceEvent> T* set_ion_cp_alloc_retry() {
+    return BeginNestedMessage<T>(288);
+  }
+
+
+  using FieldMetadata_IonCpSecureBufferEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      289,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonCpSecureBufferEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonCpSecureBufferEnd kIonCpSecureBufferEnd{};
+  template <typename T = IonCpSecureBufferEndFtraceEvent> T* set_ion_cp_secure_buffer_end() {
+    return BeginNestedMessage<T>(289);
+  }
+
+
+  using FieldMetadata_IonCpSecureBufferStart =
+    ::protozero::proto_utils::FieldMetadata<
+      290,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonCpSecureBufferStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonCpSecureBufferStart kIonCpSecureBufferStart{};
+  template <typename T = IonCpSecureBufferStartFtraceEvent> T* set_ion_cp_secure_buffer_start() {
+    return BeginNestedMessage<T>(290);
+  }
+
+
+  using FieldMetadata_IonPrefetching =
+    ::protozero::proto_utils::FieldMetadata<
+      291,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonPrefetchingFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonPrefetching kIonPrefetching{};
+  template <typename T = IonPrefetchingFtraceEvent> T* set_ion_prefetching() {
+    return BeginNestedMessage<T>(291);
+  }
+
+
+  using FieldMetadata_IonSecureCmaAddToPoolEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      292,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaAddToPoolEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaAddToPoolEnd kIonSecureCmaAddToPoolEnd{};
+  template <typename T = IonSecureCmaAddToPoolEndFtraceEvent> T* set_ion_secure_cma_add_to_pool_end() {
+    return BeginNestedMessage<T>(292);
+  }
+
+
+  using FieldMetadata_IonSecureCmaAddToPoolStart =
+    ::protozero::proto_utils::FieldMetadata<
+      293,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaAddToPoolStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaAddToPoolStart kIonSecureCmaAddToPoolStart{};
+  template <typename T = IonSecureCmaAddToPoolStartFtraceEvent> T* set_ion_secure_cma_add_to_pool_start() {
+    return BeginNestedMessage<T>(293);
+  }
+
+
+  using FieldMetadata_IonSecureCmaAllocateEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      294,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaAllocateEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaAllocateEnd kIonSecureCmaAllocateEnd{};
+  template <typename T = IonSecureCmaAllocateEndFtraceEvent> T* set_ion_secure_cma_allocate_end() {
+    return BeginNestedMessage<T>(294);
+  }
+
+
+  using FieldMetadata_IonSecureCmaAllocateStart =
+    ::protozero::proto_utils::FieldMetadata<
+      295,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaAllocateStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaAllocateStart kIonSecureCmaAllocateStart{};
+  template <typename T = IonSecureCmaAllocateStartFtraceEvent> T* set_ion_secure_cma_allocate_start() {
+    return BeginNestedMessage<T>(295);
+  }
+
+
+  using FieldMetadata_IonSecureCmaShrinkPoolEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      296,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaShrinkPoolEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaShrinkPoolEnd kIonSecureCmaShrinkPoolEnd{};
+  template <typename T = IonSecureCmaShrinkPoolEndFtraceEvent> T* set_ion_secure_cma_shrink_pool_end() {
+    return BeginNestedMessage<T>(296);
+  }
+
+
+  using FieldMetadata_IonSecureCmaShrinkPoolStart =
+    ::protozero::proto_utils::FieldMetadata<
+      297,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonSecureCmaShrinkPoolStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonSecureCmaShrinkPoolStart kIonSecureCmaShrinkPoolStart{};
+  template <typename T = IonSecureCmaShrinkPoolStartFtraceEvent> T* set_ion_secure_cma_shrink_pool_start() {
+    return BeginNestedMessage<T>(297);
+  }
+
+
+  using FieldMetadata_Kfree =
+    ::protozero::proto_utils::FieldMetadata<
+      298,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KfreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Kfree kKfree{};
+  template <typename T = KfreeFtraceEvent> T* set_kfree() {
+    return BeginNestedMessage<T>(298);
+  }
+
+
+  using FieldMetadata_Kmalloc =
+    ::protozero::proto_utils::FieldMetadata<
+      299,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KmallocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Kmalloc kKmalloc{};
+  template <typename T = KmallocFtraceEvent> T* set_kmalloc() {
+    return BeginNestedMessage<T>(299);
+  }
+
+
+  using FieldMetadata_KmallocNode =
+    ::protozero::proto_utils::FieldMetadata<
+      300,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KmallocNodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KmallocNode kKmallocNode{};
+  template <typename T = KmallocNodeFtraceEvent> T* set_kmalloc_node() {
+    return BeginNestedMessage<T>(300);
+  }
+
+
+  using FieldMetadata_KmemCacheAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      301,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KmemCacheAllocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KmemCacheAlloc kKmemCacheAlloc{};
+  template <typename T = KmemCacheAllocFtraceEvent> T* set_kmem_cache_alloc() {
+    return BeginNestedMessage<T>(301);
+  }
+
+
+  using FieldMetadata_KmemCacheAllocNode =
+    ::protozero::proto_utils::FieldMetadata<
+      302,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KmemCacheAllocNodeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KmemCacheAllocNode kKmemCacheAllocNode{};
+  template <typename T = KmemCacheAllocNodeFtraceEvent> T* set_kmem_cache_alloc_node() {
+    return BeginNestedMessage<T>(302);
+  }
+
+
+  using FieldMetadata_KmemCacheFree =
+    ::protozero::proto_utils::FieldMetadata<
+      303,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KmemCacheFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KmemCacheFree kKmemCacheFree{};
+  template <typename T = KmemCacheFreeFtraceEvent> T* set_kmem_cache_free() {
+    return BeginNestedMessage<T>(303);
+  }
+
+
+  using FieldMetadata_MigratePagesEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      304,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MigratePagesEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MigratePagesEnd kMigratePagesEnd{};
+  template <typename T = MigratePagesEndFtraceEvent> T* set_migrate_pages_end() {
+    return BeginNestedMessage<T>(304);
+  }
+
+
+  using FieldMetadata_MigratePagesStart =
+    ::protozero::proto_utils::FieldMetadata<
+      305,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MigratePagesStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MigratePagesStart kMigratePagesStart{};
+  template <typename T = MigratePagesStartFtraceEvent> T* set_migrate_pages_start() {
+    return BeginNestedMessage<T>(305);
+  }
+
+
+  using FieldMetadata_MigrateRetry =
+    ::protozero::proto_utils::FieldMetadata<
+      306,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MigrateRetryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MigrateRetry kMigrateRetry{};
+  template <typename T = MigrateRetryFtraceEvent> T* set_migrate_retry() {
+    return BeginNestedMessage<T>(306);
+  }
+
+
+  using FieldMetadata_MmPageAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      307,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPageAllocFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPageAlloc kMmPageAlloc{};
+  template <typename T = MmPageAllocFtraceEvent> T* set_mm_page_alloc() {
+    return BeginNestedMessage<T>(307);
+  }
+
+
+  using FieldMetadata_MmPageAllocExtfrag =
+    ::protozero::proto_utils::FieldMetadata<
+      308,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPageAllocExtfragFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPageAllocExtfrag kMmPageAllocExtfrag{};
+  template <typename T = MmPageAllocExtfragFtraceEvent> T* set_mm_page_alloc_extfrag() {
+    return BeginNestedMessage<T>(308);
+  }
+
+
+  using FieldMetadata_MmPageAllocZoneLocked =
+    ::protozero::proto_utils::FieldMetadata<
+      309,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPageAllocZoneLockedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPageAllocZoneLocked kMmPageAllocZoneLocked{};
+  template <typename T = MmPageAllocZoneLockedFtraceEvent> T* set_mm_page_alloc_zone_locked() {
+    return BeginNestedMessage<T>(309);
+  }
+
+
+  using FieldMetadata_MmPageFree =
+    ::protozero::proto_utils::FieldMetadata<
+      310,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPageFreeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPageFree kMmPageFree{};
+  template <typename T = MmPageFreeFtraceEvent> T* set_mm_page_free() {
+    return BeginNestedMessage<T>(310);
+  }
+
+
+  using FieldMetadata_MmPageFreeBatched =
+    ::protozero::proto_utils::FieldMetadata<
+      311,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPageFreeBatchedFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPageFreeBatched kMmPageFreeBatched{};
+  template <typename T = MmPageFreeBatchedFtraceEvent> T* set_mm_page_free_batched() {
+    return BeginNestedMessage<T>(311);
+  }
+
+
+  using FieldMetadata_MmPagePcpuDrain =
+    ::protozero::proto_utils::FieldMetadata<
+      312,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmPagePcpuDrainFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmPagePcpuDrain kMmPagePcpuDrain{};
+  template <typename T = MmPagePcpuDrainFtraceEvent> T* set_mm_page_pcpu_drain() {
+    return BeginNestedMessage<T>(312);
+  }
+
+
+  using FieldMetadata_RssStat =
+    ::protozero::proto_utils::FieldMetadata<
+      313,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RssStatFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RssStat kRssStat{};
+  template <typename T = RssStatFtraceEvent> T* set_rss_stat() {
+    return BeginNestedMessage<T>(313);
+  }
+
+
+  using FieldMetadata_IonHeapShrink =
+    ::protozero::proto_utils::FieldMetadata<
+      314,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonHeapShrinkFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonHeapShrink kIonHeapShrink{};
+  template <typename T = IonHeapShrinkFtraceEvent> T* set_ion_heap_shrink() {
+    return BeginNestedMessage<T>(314);
+  }
+
+
+  using FieldMetadata_IonHeapGrow =
+    ::protozero::proto_utils::FieldMetadata<
+      315,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonHeapGrowFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonHeapGrow kIonHeapGrow{};
+  template <typename T = IonHeapGrowFtraceEvent> T* set_ion_heap_grow() {
+    return BeginNestedMessage<T>(315);
+  }
+
+
+  using FieldMetadata_FenceInit =
+    ::protozero::proto_utils::FieldMetadata<
+      316,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FenceInitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FenceInit kFenceInit{};
+  template <typename T = FenceInitFtraceEvent> T* set_fence_init() {
+    return BeginNestedMessage<T>(316);
+  }
+
+
+  using FieldMetadata_FenceDestroy =
+    ::protozero::proto_utils::FieldMetadata<
+      317,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FenceDestroyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FenceDestroy kFenceDestroy{};
+  template <typename T = FenceDestroyFtraceEvent> T* set_fence_destroy() {
+    return BeginNestedMessage<T>(317);
+  }
+
+
+  using FieldMetadata_FenceEnableSignal =
+    ::protozero::proto_utils::FieldMetadata<
+      318,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FenceEnableSignalFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FenceEnableSignal kFenceEnableSignal{};
+  template <typename T = FenceEnableSignalFtraceEvent> T* set_fence_enable_signal() {
+    return BeginNestedMessage<T>(318);
+  }
+
+
+  using FieldMetadata_FenceSignaled =
+    ::protozero::proto_utils::FieldMetadata<
+      319,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FenceSignaledFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FenceSignaled kFenceSignaled{};
+  template <typename T = FenceSignaledFtraceEvent> T* set_fence_signaled() {
+    return BeginNestedMessage<T>(319);
+  }
+
+
+  using FieldMetadata_ClkEnable =
+    ::protozero::proto_utils::FieldMetadata<
+      320,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClkEnableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClkEnable kClkEnable{};
+  template <typename T = ClkEnableFtraceEvent> T* set_clk_enable() {
+    return BeginNestedMessage<T>(320);
+  }
+
+
+  using FieldMetadata_ClkDisable =
+    ::protozero::proto_utils::FieldMetadata<
+      321,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClkDisableFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClkDisable kClkDisable{};
+  template <typename T = ClkDisableFtraceEvent> T* set_clk_disable() {
+    return BeginNestedMessage<T>(321);
+  }
+
+
+  using FieldMetadata_ClkSetRate =
+    ::protozero::proto_utils::FieldMetadata<
+      322,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ClkSetRateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ClkSetRate kClkSetRate{};
+  template <typename T = ClkSetRateFtraceEvent> T* set_clk_set_rate() {
+    return BeginNestedMessage<T>(322);
+  }
+
+
+  using FieldMetadata_BinderTransactionAllocBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      323,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderTransactionAllocBufFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderTransactionAllocBuf kBinderTransactionAllocBuf{};
+  template <typename T = BinderTransactionAllocBufFtraceEvent> T* set_binder_transaction_alloc_buf() {
+    return BeginNestedMessage<T>(323);
+  }
+
+
+  using FieldMetadata_SignalDeliver =
+    ::protozero::proto_utils::FieldMetadata<
+      324,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SignalDeliverFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SignalDeliver kSignalDeliver{};
+  template <typename T = SignalDeliverFtraceEvent> T* set_signal_deliver() {
+    return BeginNestedMessage<T>(324);
+  }
+
+
+  using FieldMetadata_SignalGenerate =
+    ::protozero::proto_utils::FieldMetadata<
+      325,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SignalGenerateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SignalGenerate kSignalGenerate{};
+  template <typename T = SignalGenerateFtraceEvent> T* set_signal_generate() {
+    return BeginNestedMessage<T>(325);
+  }
+
+
+  using FieldMetadata_OomScoreAdjUpdate =
+    ::protozero::proto_utils::FieldMetadata<
+      326,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      OomScoreAdjUpdateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_OomScoreAdjUpdate kOomScoreAdjUpdate{};
+  template <typename T = OomScoreAdjUpdateFtraceEvent> T* set_oom_score_adj_update() {
+    return BeginNestedMessage<T>(326);
+  }
+
+
+  using FieldMetadata_Generic =
+    ::protozero::proto_utils::FieldMetadata<
+      327,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GenericFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Generic kGeneric{};
+  template <typename T = GenericFtraceEvent> T* set_generic() {
+    return BeginNestedMessage<T>(327);
+  }
+
+
+  using FieldMetadata_MmEventRecord =
+    ::protozero::proto_utils::FieldMetadata<
+      328,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmEventRecordFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmEventRecord kMmEventRecord{};
+  template <typename T = MmEventRecordFtraceEvent> T* set_mm_event_record() {
+    return BeginNestedMessage<T>(328);
+  }
+
+
+  using FieldMetadata_SysEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      329,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SysEnter kSysEnter{};
+  template <typename T = SysEnterFtraceEvent> T* set_sys_enter() {
+    return BeginNestedMessage<T>(329);
+  }
+
+
+  using FieldMetadata_SysExit =
+    ::protozero::proto_utils::FieldMetadata<
+      330,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SysExit kSysExit{};
+  template <typename T = SysExitFtraceEvent> T* set_sys_exit() {
+    return BeginNestedMessage<T>(330);
+  }
+
+
+  using FieldMetadata_Zero =
+    ::protozero::proto_utils::FieldMetadata<
+      331,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ZeroFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Zero kZero{};
+  template <typename T = ZeroFtraceEvent> T* set_zero() {
+    return BeginNestedMessage<T>(331);
+  }
+
+
+  using FieldMetadata_GpuFrequency =
+    ::protozero::proto_utils::FieldMetadata<
+      332,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuFrequencyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_GpuFrequency kGpuFrequency{};
+  template <typename T = GpuFrequencyFtraceEvent> T* set_gpu_frequency() {
+    return BeginNestedMessage<T>(332);
+  }
+
+
+  using FieldMetadata_SdeTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      333,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeTracingMarkWrite kSdeTracingMarkWrite{};
+  template <typename T = SdeTracingMarkWriteFtraceEvent> T* set_sde_tracing_mark_write() {
+    return BeginNestedMessage<T>(333);
+  }
+
+
+  using FieldMetadata_MarkVictim =
+    ::protozero::proto_utils::FieldMetadata<
+      334,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MarkVictimFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MarkVictim kMarkVictim{};
+  template <typename T = MarkVictimFtraceEvent> T* set_mark_victim() {
+    return BeginNestedMessage<T>(334);
+  }
+
+
+  using FieldMetadata_IonStat =
+    ::protozero::proto_utils::FieldMetadata<
+      335,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonStatFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonStat kIonStat{};
+  template <typename T = IonStatFtraceEvent> T* set_ion_stat() {
+    return BeginNestedMessage<T>(335);
+  }
+
+
+  using FieldMetadata_IonBufferCreate =
+    ::protozero::proto_utils::FieldMetadata<
+      336,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonBufferCreateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonBufferCreate kIonBufferCreate{};
+  template <typename T = IonBufferCreateFtraceEvent> T* set_ion_buffer_create() {
+    return BeginNestedMessage<T>(336);
+  }
+
+
+  using FieldMetadata_IonBufferDestroy =
+    ::protozero::proto_utils::FieldMetadata<
+      337,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      IonBufferDestroyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_IonBufferDestroy kIonBufferDestroy{};
+  template <typename T = IonBufferDestroyFtraceEvent> T* set_ion_buffer_destroy() {
+    return BeginNestedMessage<T>(337);
+  }
+
+
+  using FieldMetadata_ScmCallStart =
+    ::protozero::proto_utils::FieldMetadata<
+      338,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ScmCallStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ScmCallStart kScmCallStart{};
+  template <typename T = ScmCallStartFtraceEvent> T* set_scm_call_start() {
+    return BeginNestedMessage<T>(338);
+  }
+
+
+  using FieldMetadata_ScmCallEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      339,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ScmCallEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ScmCallEnd kScmCallEnd{};
+  template <typename T = ScmCallEndFtraceEvent> T* set_scm_call_end() {
+    return BeginNestedMessage<T>(339);
+  }
+
+
+  using FieldMetadata_GpuMemTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      340,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuMemTotalFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_GpuMemTotal kGpuMemTotal{};
+  template <typename T = GpuMemTotalFtraceEvent> T* set_gpu_mem_total() {
+    return BeginNestedMessage<T>(340);
+  }
+
+
+  using FieldMetadata_ThermalTemperature =
+    ::protozero::proto_utils::FieldMetadata<
+      341,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ThermalTemperatureFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_ThermalTemperature kThermalTemperature{};
+  template <typename T = ThermalTemperatureFtraceEvent> T* set_thermal_temperature() {
+    return BeginNestedMessage<T>(341);
+  }
+
+
+  using FieldMetadata_CdevUpdate =
+    ::protozero::proto_utils::FieldMetadata<
+      342,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CdevUpdateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CdevUpdate kCdevUpdate{};
+  template <typename T = CdevUpdateFtraceEvent> T* set_cdev_update() {
+    return BeginNestedMessage<T>(342);
+  }
+
+
+  using FieldMetadata_CpuhpExit =
+    ::protozero::proto_utils::FieldMetadata<
+      343,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuhpExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuhpExit kCpuhpExit{};
+  template <typename T = CpuhpExitFtraceEvent> T* set_cpuhp_exit() {
+    return BeginNestedMessage<T>(343);
+  }
+
+
+  using FieldMetadata_CpuhpMultiEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      344,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuhpMultiEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuhpMultiEnter kCpuhpMultiEnter{};
+  template <typename T = CpuhpMultiEnterFtraceEvent> T* set_cpuhp_multi_enter() {
+    return BeginNestedMessage<T>(344);
+  }
+
+
+  using FieldMetadata_CpuhpEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      345,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuhpEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuhpEnter kCpuhpEnter{};
+  template <typename T = CpuhpEnterFtraceEvent> T* set_cpuhp_enter() {
+    return BeginNestedMessage<T>(345);
+  }
+
+
+  using FieldMetadata_CpuhpLatency =
+    ::protozero::proto_utils::FieldMetadata<
+      346,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuhpLatencyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuhpLatency kCpuhpLatency{};
+  template <typename T = CpuhpLatencyFtraceEvent> T* set_cpuhp_latency() {
+    return BeginNestedMessage<T>(346);
+  }
+
+
+  using FieldMetadata_FastrpcDmaStat =
+    ::protozero::proto_utils::FieldMetadata<
+      347,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FastrpcDmaStatFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FastrpcDmaStat kFastrpcDmaStat{};
+  template <typename T = FastrpcDmaStatFtraceEvent> T* set_fastrpc_dma_stat() {
+    return BeginNestedMessage<T>(347);
+  }
+
+
+  using FieldMetadata_DpuTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      348,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DpuTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DpuTracingMarkWrite kDpuTracingMarkWrite{};
+  template <typename T = DpuTracingMarkWriteFtraceEvent> T* set_dpu_tracing_mark_write() {
+    return BeginNestedMessage<T>(348);
+  }
+
+
+  using FieldMetadata_G2dTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      349,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      G2dTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_G2dTracingMarkWrite kG2dTracingMarkWrite{};
+  template <typename T = G2dTracingMarkWriteFtraceEvent> T* set_g2d_tracing_mark_write() {
+    return BeginNestedMessage<T>(349);
+  }
+
+
+  using FieldMetadata_MaliTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      350,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliTracingMarkWrite kMaliTracingMarkWrite{};
+  template <typename T = MaliTracingMarkWriteFtraceEvent> T* set_mali_tracing_mark_write() {
+    return BeginNestedMessage<T>(350);
+  }
+
+
+  using FieldMetadata_DmaHeapStat =
+    ::protozero::proto_utils::FieldMetadata<
+      351,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaHeapStatFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaHeapStat kDmaHeapStat{};
+  template <typename T = DmaHeapStatFtraceEvent> T* set_dma_heap_stat() {
+    return BeginNestedMessage<T>(351);
+  }
+
+
+  using FieldMetadata_CpuhpPause =
+    ::protozero::proto_utils::FieldMetadata<
+      352,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuhpPauseFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CpuhpPause kCpuhpPause{};
+  template <typename T = CpuhpPauseFtraceEvent> T* set_cpuhp_pause() {
+    return BeginNestedMessage<T>(352);
+  }
+
+
+  using FieldMetadata_SchedPiSetprio =
+    ::protozero::proto_utils::FieldMetadata<
+      353,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedPiSetprioFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedPiSetprio kSchedPiSetprio{};
+  template <typename T = SchedPiSetprioFtraceEvent> T* set_sched_pi_setprio() {
+    return BeginNestedMessage<T>(353);
+  }
+
+
+  using FieldMetadata_SdeSdeEvtlog =
+    ::protozero::proto_utils::FieldMetadata<
+      354,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeSdeEvtlogFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeSdeEvtlog kSdeSdeEvtlog{};
+  template <typename T = SdeSdeEvtlogFtraceEvent> T* set_sde_sde_evtlog() {
+    return BeginNestedMessage<T>(354);
+  }
+
+
+  using FieldMetadata_SdeSdePerfCalcCrtc =
+    ::protozero::proto_utils::FieldMetadata<
+      355,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeSdePerfCalcCrtcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeSdePerfCalcCrtc kSdeSdePerfCalcCrtc{};
+  template <typename T = SdeSdePerfCalcCrtcFtraceEvent> T* set_sde_sde_perf_calc_crtc() {
+    return BeginNestedMessage<T>(355);
+  }
+
+
+  using FieldMetadata_SdeSdePerfCrtcUpdate =
+    ::protozero::proto_utils::FieldMetadata<
+      356,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeSdePerfCrtcUpdateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeSdePerfCrtcUpdate kSdeSdePerfCrtcUpdate{};
+  template <typename T = SdeSdePerfCrtcUpdateFtraceEvent> T* set_sde_sde_perf_crtc_update() {
+    return BeginNestedMessage<T>(356);
+  }
+
+
+  using FieldMetadata_SdeSdePerfSetQosLuts =
+    ::protozero::proto_utils::FieldMetadata<
+      357,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeSdePerfSetQosLutsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeSdePerfSetQosLuts kSdeSdePerfSetQosLuts{};
+  template <typename T = SdeSdePerfSetQosLutsFtraceEvent> T* set_sde_sde_perf_set_qos_luts() {
+    return BeginNestedMessage<T>(357);
+  }
+
+
+  using FieldMetadata_SdeSdePerfUpdateBus =
+    ::protozero::proto_utils::FieldMetadata<
+      358,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SdeSdePerfUpdateBusFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SdeSdePerfUpdateBus kSdeSdePerfUpdateBus{};
+  template <typename T = SdeSdePerfUpdateBusFtraceEvent> T* set_sde_sde_perf_update_bus() {
+    return BeginNestedMessage<T>(358);
+  }
+
+
+  using FieldMetadata_RssStatThrottled =
+    ::protozero::proto_utils::FieldMetadata<
+      359,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      RssStatThrottledFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_RssStatThrottled kRssStatThrottled{};
+  template <typename T = RssStatThrottledFtraceEvent> T* set_rss_stat_throttled() {
+    return BeginNestedMessage<T>(359);
+  }
+
+
+  using FieldMetadata_NetifReceiveSkb =
+    ::protozero::proto_utils::FieldMetadata<
+      360,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetifReceiveSkbFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_NetifReceiveSkb kNetifReceiveSkb{};
+  template <typename T = NetifReceiveSkbFtraceEvent> T* set_netif_receive_skb() {
+    return BeginNestedMessage<T>(360);
+  }
+
+
+  using FieldMetadata_NetDevXmit =
+    ::protozero::proto_utils::FieldMetadata<
+      361,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NetDevXmitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_NetDevXmit kNetDevXmit{};
+  template <typename T = NetDevXmitFtraceEvent> T* set_net_dev_xmit() {
+    return BeginNestedMessage<T>(361);
+  }
+
+
+  using FieldMetadata_InetSockSetState =
+    ::protozero::proto_utils::FieldMetadata<
+      362,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InetSockSetStateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_InetSockSetState kInetSockSetState{};
+  template <typename T = InetSockSetStateFtraceEvent> T* set_inet_sock_set_state() {
+    return BeginNestedMessage<T>(362);
+  }
+
+
+  using FieldMetadata_TcpRetransmitSkb =
+    ::protozero::proto_utils::FieldMetadata<
+      363,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TcpRetransmitSkbFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TcpRetransmitSkb kTcpRetransmitSkb{};
+  template <typename T = TcpRetransmitSkbFtraceEvent> T* set_tcp_retransmit_skb() {
+    return BeginNestedMessage<T>(363);
+  }
+
+
+  using FieldMetadata_CrosEcSensorhubData =
+    ::protozero::proto_utils::FieldMetadata<
+      364,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CrosEcSensorhubDataFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CrosEcSensorhubData kCrosEcSensorhubData{};
+  template <typename T = CrosEcSensorhubDataFtraceEvent> T* set_cros_ec_sensorhub_data() {
+    return BeginNestedMessage<T>(364);
+  }
+
+
+  using FieldMetadata_NapiGroReceiveEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      365,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NapiGroReceiveEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_NapiGroReceiveEntry kNapiGroReceiveEntry{};
+  template <typename T = NapiGroReceiveEntryFtraceEvent> T* set_napi_gro_receive_entry() {
+    return BeginNestedMessage<T>(365);
+  }
+
+
+  using FieldMetadata_NapiGroReceiveExit =
+    ::protozero::proto_utils::FieldMetadata<
+      366,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      NapiGroReceiveExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_NapiGroReceiveExit kNapiGroReceiveExit{};
+  template <typename T = NapiGroReceiveExitFtraceEvent> T* set_napi_gro_receive_exit() {
+    return BeginNestedMessage<T>(366);
+  }
+
+
+  using FieldMetadata_KfreeSkb =
+    ::protozero::proto_utils::FieldMetadata<
+      367,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KfreeSkbFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KfreeSkb kKfreeSkb{};
+  template <typename T = KfreeSkbFtraceEvent> T* set_kfree_skb() {
+    return BeginNestedMessage<T>(367);
+  }
+
+
+  using FieldMetadata_KvmAccessFault =
+    ::protozero::proto_utils::FieldMetadata<
+      368,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmAccessFaultFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmAccessFault kKvmAccessFault{};
+  template <typename T = KvmAccessFaultFtraceEvent> T* set_kvm_access_fault() {
+    return BeginNestedMessage<T>(368);
+  }
+
+
+  using FieldMetadata_KvmAckIrq =
+    ::protozero::proto_utils::FieldMetadata<
+      369,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmAckIrqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmAckIrq kKvmAckIrq{};
+  template <typename T = KvmAckIrqFtraceEvent> T* set_kvm_ack_irq() {
+    return BeginNestedMessage<T>(369);
+  }
+
+
+  using FieldMetadata_KvmAgeHva =
+    ::protozero::proto_utils::FieldMetadata<
+      370,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmAgeHvaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmAgeHva kKvmAgeHva{};
+  template <typename T = KvmAgeHvaFtraceEvent> T* set_kvm_age_hva() {
+    return BeginNestedMessage<T>(370);
+  }
+
+
+  using FieldMetadata_KvmAgePage =
+    ::protozero::proto_utils::FieldMetadata<
+      371,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmAgePageFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmAgePage kKvmAgePage{};
+  template <typename T = KvmAgePageFtraceEvent> T* set_kvm_age_page() {
+    return BeginNestedMessage<T>(371);
+  }
+
+
+  using FieldMetadata_KvmArmClearDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      372,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmArmClearDebugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmArmClearDebug kKvmArmClearDebug{};
+  template <typename T = KvmArmClearDebugFtraceEvent> T* set_kvm_arm_clear_debug() {
+    return BeginNestedMessage<T>(372);
+  }
+
+
+  using FieldMetadata_KvmArmSetDreg32 =
+    ::protozero::proto_utils::FieldMetadata<
+      373,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmArmSetDreg32FtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmArmSetDreg32 kKvmArmSetDreg32{};
+  template <typename T = KvmArmSetDreg32FtraceEvent> T* set_kvm_arm_set_dreg32() {
+    return BeginNestedMessage<T>(373);
+  }
+
+
+  using FieldMetadata_KvmArmSetRegset =
+    ::protozero::proto_utils::FieldMetadata<
+      374,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmArmSetRegsetFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmArmSetRegset kKvmArmSetRegset{};
+  template <typename T = KvmArmSetRegsetFtraceEvent> T* set_kvm_arm_set_regset() {
+    return BeginNestedMessage<T>(374);
+  }
+
+
+  using FieldMetadata_KvmArmSetupDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      375,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmArmSetupDebugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmArmSetupDebug kKvmArmSetupDebug{};
+  template <typename T = KvmArmSetupDebugFtraceEvent> T* set_kvm_arm_setup_debug() {
+    return BeginNestedMessage<T>(375);
+  }
+
+
+  using FieldMetadata_KvmEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      376,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmEntry kKvmEntry{};
+  template <typename T = KvmEntryFtraceEvent> T* set_kvm_entry() {
+    return BeginNestedMessage<T>(376);
+  }
+
+
+  using FieldMetadata_KvmExit =
+    ::protozero::proto_utils::FieldMetadata<
+      377,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmExit kKvmExit{};
+  template <typename T = KvmExitFtraceEvent> T* set_kvm_exit() {
+    return BeginNestedMessage<T>(377);
+  }
+
+
+  using FieldMetadata_KvmFpu =
+    ::protozero::proto_utils::FieldMetadata<
+      378,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmFpuFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmFpu kKvmFpu{};
+  template <typename T = KvmFpuFtraceEvent> T* set_kvm_fpu() {
+    return BeginNestedMessage<T>(378);
+  }
+
+
+  using FieldMetadata_KvmGetTimerMap =
+    ::protozero::proto_utils::FieldMetadata<
+      379,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmGetTimerMapFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmGetTimerMap kKvmGetTimerMap{};
+  template <typename T = KvmGetTimerMapFtraceEvent> T* set_kvm_get_timer_map() {
+    return BeginNestedMessage<T>(379);
+  }
+
+
+  using FieldMetadata_KvmGuestFault =
+    ::protozero::proto_utils::FieldMetadata<
+      380,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmGuestFaultFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmGuestFault kKvmGuestFault{};
+  template <typename T = KvmGuestFaultFtraceEvent> T* set_kvm_guest_fault() {
+    return BeginNestedMessage<T>(380);
+  }
+
+
+  using FieldMetadata_KvmHandleSysReg =
+    ::protozero::proto_utils::FieldMetadata<
+      381,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmHandleSysRegFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmHandleSysReg kKvmHandleSysReg{};
+  template <typename T = KvmHandleSysRegFtraceEvent> T* set_kvm_handle_sys_reg() {
+    return BeginNestedMessage<T>(381);
+  }
+
+
+  using FieldMetadata_KvmHvcArm64 =
+    ::protozero::proto_utils::FieldMetadata<
+      382,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmHvcArm64FtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmHvcArm64 kKvmHvcArm64{};
+  template <typename T = KvmHvcArm64FtraceEvent> T* set_kvm_hvc_arm64() {
+    return BeginNestedMessage<T>(382);
+  }
+
+
+  using FieldMetadata_KvmIrqLine =
+    ::protozero::proto_utils::FieldMetadata<
+      383,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmIrqLineFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmIrqLine kKvmIrqLine{};
+  template <typename T = KvmIrqLineFtraceEvent> T* set_kvm_irq_line() {
+    return BeginNestedMessage<T>(383);
+  }
+
+
+  using FieldMetadata_KvmMmio =
+    ::protozero::proto_utils::FieldMetadata<
+      384,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmMmioFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmMmio kKvmMmio{};
+  template <typename T = KvmMmioFtraceEvent> T* set_kvm_mmio() {
+    return BeginNestedMessage<T>(384);
+  }
+
+
+  using FieldMetadata_KvmMmioEmulate =
+    ::protozero::proto_utils::FieldMetadata<
+      385,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmMmioEmulateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmMmioEmulate kKvmMmioEmulate{};
+  template <typename T = KvmMmioEmulateFtraceEvent> T* set_kvm_mmio_emulate() {
+    return BeginNestedMessage<T>(385);
+  }
+
+
+  using FieldMetadata_KvmSetGuestDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      386,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmSetGuestDebugFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmSetGuestDebug kKvmSetGuestDebug{};
+  template <typename T = KvmSetGuestDebugFtraceEvent> T* set_kvm_set_guest_debug() {
+    return BeginNestedMessage<T>(386);
+  }
+
+
+  using FieldMetadata_KvmSetIrq =
+    ::protozero::proto_utils::FieldMetadata<
+      387,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmSetIrqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmSetIrq kKvmSetIrq{};
+  template <typename T = KvmSetIrqFtraceEvent> T* set_kvm_set_irq() {
+    return BeginNestedMessage<T>(387);
+  }
+
+
+  using FieldMetadata_KvmSetSpteHva =
+    ::protozero::proto_utils::FieldMetadata<
+      388,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmSetSpteHvaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmSetSpteHva kKvmSetSpteHva{};
+  template <typename T = KvmSetSpteHvaFtraceEvent> T* set_kvm_set_spte_hva() {
+    return BeginNestedMessage<T>(388);
+  }
+
+
+  using FieldMetadata_KvmSetWayFlush =
+    ::protozero::proto_utils::FieldMetadata<
+      389,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmSetWayFlushFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmSetWayFlush kKvmSetWayFlush{};
+  template <typename T = KvmSetWayFlushFtraceEvent> T* set_kvm_set_way_flush() {
+    return BeginNestedMessage<T>(389);
+  }
+
+
+  using FieldMetadata_KvmSysAccess =
+    ::protozero::proto_utils::FieldMetadata<
+      390,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmSysAccessFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmSysAccess kKvmSysAccess{};
+  template <typename T = KvmSysAccessFtraceEvent> T* set_kvm_sys_access() {
+    return BeginNestedMessage<T>(390);
+  }
+
+
+  using FieldMetadata_KvmTestAgeHva =
+    ::protozero::proto_utils::FieldMetadata<
+      391,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTestAgeHvaFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTestAgeHva kKvmTestAgeHva{};
+  template <typename T = KvmTestAgeHvaFtraceEvent> T* set_kvm_test_age_hva() {
+    return BeginNestedMessage<T>(391);
+  }
+
+
+  using FieldMetadata_KvmTimerEmulate =
+    ::protozero::proto_utils::FieldMetadata<
+      392,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTimerEmulateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTimerEmulate kKvmTimerEmulate{};
+  template <typename T = KvmTimerEmulateFtraceEvent> T* set_kvm_timer_emulate() {
+    return BeginNestedMessage<T>(392);
+  }
+
+
+  using FieldMetadata_KvmTimerHrtimerExpire =
+    ::protozero::proto_utils::FieldMetadata<
+      393,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTimerHrtimerExpireFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTimerHrtimerExpire kKvmTimerHrtimerExpire{};
+  template <typename T = KvmTimerHrtimerExpireFtraceEvent> T* set_kvm_timer_hrtimer_expire() {
+    return BeginNestedMessage<T>(393);
+  }
+
+
+  using FieldMetadata_KvmTimerRestoreState =
+    ::protozero::proto_utils::FieldMetadata<
+      394,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTimerRestoreStateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTimerRestoreState kKvmTimerRestoreState{};
+  template <typename T = KvmTimerRestoreStateFtraceEvent> T* set_kvm_timer_restore_state() {
+    return BeginNestedMessage<T>(394);
+  }
+
+
+  using FieldMetadata_KvmTimerSaveState =
+    ::protozero::proto_utils::FieldMetadata<
+      395,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTimerSaveStateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTimerSaveState kKvmTimerSaveState{};
+  template <typename T = KvmTimerSaveStateFtraceEvent> T* set_kvm_timer_save_state() {
+    return BeginNestedMessage<T>(395);
+  }
+
+
+  using FieldMetadata_KvmTimerUpdateIrq =
+    ::protozero::proto_utils::FieldMetadata<
+      396,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmTimerUpdateIrqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmTimerUpdateIrq kKvmTimerUpdateIrq{};
+  template <typename T = KvmTimerUpdateIrqFtraceEvent> T* set_kvm_timer_update_irq() {
+    return BeginNestedMessage<T>(396);
+  }
+
+
+  using FieldMetadata_KvmToggleCache =
+    ::protozero::proto_utils::FieldMetadata<
+      397,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmToggleCacheFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmToggleCache kKvmToggleCache{};
+  template <typename T = KvmToggleCacheFtraceEvent> T* set_kvm_toggle_cache() {
+    return BeginNestedMessage<T>(397);
+  }
+
+
+  using FieldMetadata_KvmUnmapHvaRange =
+    ::protozero::proto_utils::FieldMetadata<
+      398,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmUnmapHvaRangeFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmUnmapHvaRange kKvmUnmapHvaRange{};
+  template <typename T = KvmUnmapHvaRangeFtraceEvent> T* set_kvm_unmap_hva_range() {
+    return BeginNestedMessage<T>(398);
+  }
+
+
+  using FieldMetadata_KvmUserspaceExit =
+    ::protozero::proto_utils::FieldMetadata<
+      399,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmUserspaceExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmUserspaceExit kKvmUserspaceExit{};
+  template <typename T = KvmUserspaceExitFtraceEvent> T* set_kvm_userspace_exit() {
+    return BeginNestedMessage<T>(399);
+  }
+
+
+  using FieldMetadata_KvmVcpuWakeup =
+    ::protozero::proto_utils::FieldMetadata<
+      400,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmVcpuWakeupFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmVcpuWakeup kKvmVcpuWakeup{};
+  template <typename T = KvmVcpuWakeupFtraceEvent> T* set_kvm_vcpu_wakeup() {
+    return BeginNestedMessage<T>(400);
+  }
+
+
+  using FieldMetadata_KvmWfxArm64 =
+    ::protozero::proto_utils::FieldMetadata<
+      401,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      KvmWfxArm64FtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_KvmWfxArm64 kKvmWfxArm64{};
+  template <typename T = KvmWfxArm64FtraceEvent> T* set_kvm_wfx_arm64() {
+    return BeginNestedMessage<T>(401);
+  }
+
+
+  using FieldMetadata_TrapReg =
+    ::protozero::proto_utils::FieldMetadata<
+      402,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrapRegFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrapReg kTrapReg{};
+  template <typename T = TrapRegFtraceEvent> T* set_trap_reg() {
+    return BeginNestedMessage<T>(402);
+  }
+
+
+  using FieldMetadata_VgicUpdateIrqPending =
+    ::protozero::proto_utils::FieldMetadata<
+      403,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VgicUpdateIrqPendingFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VgicUpdateIrqPending kVgicUpdateIrqPending{};
+  template <typename T = VgicUpdateIrqPendingFtraceEvent> T* set_vgic_update_irq_pending() {
+    return BeginNestedMessage<T>(403);
+  }
+
+
+  using FieldMetadata_WakeupSourceActivate =
+    ::protozero::proto_utils::FieldMetadata<
+      404,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WakeupSourceActivateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WakeupSourceActivate kWakeupSourceActivate{};
+  template <typename T = WakeupSourceActivateFtraceEvent> T* set_wakeup_source_activate() {
+    return BeginNestedMessage<T>(404);
+  }
+
+
+  using FieldMetadata_WakeupSourceDeactivate =
+    ::protozero::proto_utils::FieldMetadata<
+      405,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      WakeupSourceDeactivateFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_WakeupSourceDeactivate kWakeupSourceDeactivate{};
+  template <typename T = WakeupSourceDeactivateFtraceEvent> T* set_wakeup_source_deactivate() {
+    return BeginNestedMessage<T>(405);
+  }
+
+
+  using FieldMetadata_UfshcdCommand =
+    ::protozero::proto_utils::FieldMetadata<
+      406,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UfshcdCommandFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_UfshcdCommand kUfshcdCommand{};
+  template <typename T = UfshcdCommandFtraceEvent> T* set_ufshcd_command() {
+    return BeginNestedMessage<T>(406);
+  }
+
+
+  using FieldMetadata_UfshcdClkGating =
+    ::protozero::proto_utils::FieldMetadata<
+      407,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UfshcdClkGatingFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_UfshcdClkGating kUfshcdClkGating{};
+  template <typename T = UfshcdClkGatingFtraceEvent> T* set_ufshcd_clk_gating() {
+    return BeginNestedMessage<T>(407);
+  }
+
+
+  using FieldMetadata_Console =
+    ::protozero::proto_utils::FieldMetadata<
+      408,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ConsoleFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Console kConsole{};
+  template <typename T = ConsoleFtraceEvent> T* set_console() {
+    return BeginNestedMessage<T>(408);
+  }
+
+
+  using FieldMetadata_DrmVblankEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      409,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DrmVblankEventFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DrmVblankEvent kDrmVblankEvent{};
+  template <typename T = DrmVblankEventFtraceEvent> T* set_drm_vblank_event() {
+    return BeginNestedMessage<T>(409);
+  }
+
+
+  using FieldMetadata_DrmVblankEventDelivered =
+    ::protozero::proto_utils::FieldMetadata<
+      410,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DrmVblankEventDeliveredFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DrmVblankEventDelivered kDrmVblankEventDelivered{};
+  template <typename T = DrmVblankEventDeliveredFtraceEvent> T* set_drm_vblank_event_delivered() {
+    return BeginNestedMessage<T>(410);
+  }
+
+
+  using FieldMetadata_DrmSchedJob =
+    ::protozero::proto_utils::FieldMetadata<
+      411,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DrmSchedJobFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DrmSchedJob kDrmSchedJob{};
+  template <typename T = DrmSchedJobFtraceEvent> T* set_drm_sched_job() {
+    return BeginNestedMessage<T>(411);
+  }
+
+
+  using FieldMetadata_DrmRunJob =
+    ::protozero::proto_utils::FieldMetadata<
+      412,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DrmRunJobFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DrmRunJob kDrmRunJob{};
+  template <typename T = DrmRunJobFtraceEvent> T* set_drm_run_job() {
+    return BeginNestedMessage<T>(412);
+  }
+
+
+  using FieldMetadata_DrmSchedProcessJob =
+    ::protozero::proto_utils::FieldMetadata<
+      413,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DrmSchedProcessJobFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DrmSchedProcessJob kDrmSchedProcessJob{};
+  template <typename T = DrmSchedProcessJobFtraceEvent> T* set_drm_sched_process_job() {
+    return BeginNestedMessage<T>(413);
+  }
+
+
+  using FieldMetadata_DmaFenceInit =
+    ::protozero::proto_utils::FieldMetadata<
+      414,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaFenceInitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaFenceInit kDmaFenceInit{};
+  template <typename T = DmaFenceInitFtraceEvent> T* set_dma_fence_init() {
+    return BeginNestedMessage<T>(414);
+  }
+
+
+  using FieldMetadata_DmaFenceEmit =
+    ::protozero::proto_utils::FieldMetadata<
+      415,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaFenceEmitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaFenceEmit kDmaFenceEmit{};
+  template <typename T = DmaFenceEmitFtraceEvent> T* set_dma_fence_emit() {
+    return BeginNestedMessage<T>(415);
+  }
+
+
+  using FieldMetadata_DmaFenceSignaled =
+    ::protozero::proto_utils::FieldMetadata<
+      416,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaFenceSignaledFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaFenceSignaled kDmaFenceSignaled{};
+  template <typename T = DmaFenceSignaledFtraceEvent> T* set_dma_fence_signaled() {
+    return BeginNestedMessage<T>(416);
+  }
+
+
+  using FieldMetadata_DmaFenceWaitStart =
+    ::protozero::proto_utils::FieldMetadata<
+      417,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaFenceWaitStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaFenceWaitStart kDmaFenceWaitStart{};
+  template <typename T = DmaFenceWaitStartFtraceEvent> T* set_dma_fence_wait_start() {
+    return BeginNestedMessage<T>(417);
+  }
+
+
+  using FieldMetadata_DmaFenceWaitEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      418,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DmaFenceWaitEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DmaFenceWaitEnd kDmaFenceWaitEnd{};
+  template <typename T = DmaFenceWaitEndFtraceEvent> T* set_dma_fence_wait_end() {
+    return BeginNestedMessage<T>(418);
+  }
+
+
+  using FieldMetadata_F2fsIostat =
+    ::protozero::proto_utils::FieldMetadata<
+      419,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsIostatFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsIostat kF2fsIostat{};
+  template <typename T = F2fsIostatFtraceEvent> T* set_f2fs_iostat() {
+    return BeginNestedMessage<T>(419);
+  }
+
+
+  using FieldMetadata_F2fsIostatLatency =
+    ::protozero::proto_utils::FieldMetadata<
+      420,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      F2fsIostatLatencyFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_F2fsIostatLatency kF2fsIostatLatency{};
+  template <typename T = F2fsIostatLatencyFtraceEvent> T* set_f2fs_iostat_latency() {
+    return BeginNestedMessage<T>(420);
+  }
+
+
+  using FieldMetadata_SchedCpuUtilCfs =
+    ::protozero::proto_utils::FieldMetadata<
+      421,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedCpuUtilCfsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedCpuUtilCfs kSchedCpuUtilCfs{};
+  template <typename T = SchedCpuUtilCfsFtraceEvent> T* set_sched_cpu_util_cfs() {
+    return BeginNestedMessage<T>(421);
+  }
+
+
+  using FieldMetadata_V4l2Qbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      422,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V4l2QbufFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_V4l2Qbuf kV4l2Qbuf{};
+  template <typename T = V4l2QbufFtraceEvent> T* set_v4l2_qbuf() {
+    return BeginNestedMessage<T>(422);
+  }
+
+
+  using FieldMetadata_V4l2Dqbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      423,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      V4l2DqbufFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_V4l2Dqbuf kV4l2Dqbuf{};
+  template <typename T = V4l2DqbufFtraceEvent> T* set_v4l2_dqbuf() {
+    return BeginNestedMessage<T>(423);
+  }
+
+
+  using FieldMetadata_Vb2V4l2BufQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      424,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Vb2V4l2BufQueueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Vb2V4l2BufQueue kVb2V4l2BufQueue{};
+  template <typename T = Vb2V4l2BufQueueFtraceEvent> T* set_vb2_v4l2_buf_queue() {
+    return BeginNestedMessage<T>(424);
+  }
+
+
+  using FieldMetadata_Vb2V4l2BufDone =
+    ::protozero::proto_utils::FieldMetadata<
+      425,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Vb2V4l2BufDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Vb2V4l2BufDone kVb2V4l2BufDone{};
+  template <typename T = Vb2V4l2BufDoneFtraceEvent> T* set_vb2_v4l2_buf_done() {
+    return BeginNestedMessage<T>(425);
+  }
+
+
+  using FieldMetadata_Vb2V4l2Qbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      426,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Vb2V4l2QbufFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Vb2V4l2Qbuf kVb2V4l2Qbuf{};
+  template <typename T = Vb2V4l2QbufFtraceEvent> T* set_vb2_v4l2_qbuf() {
+    return BeginNestedMessage<T>(426);
+  }
+
+
+  using FieldMetadata_Vb2V4l2Dqbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      427,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Vb2V4l2DqbufFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_Vb2V4l2Dqbuf kVb2V4l2Dqbuf{};
+  template <typename T = Vb2V4l2DqbufFtraceEvent> T* set_vb2_v4l2_dqbuf() {
+    return BeginNestedMessage<T>(427);
+  }
+
+
+  using FieldMetadata_DsiCmdFifoStatus =
+    ::protozero::proto_utils::FieldMetadata<
+      428,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DsiCmdFifoStatusFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DsiCmdFifoStatus kDsiCmdFifoStatus{};
+  template <typename T = DsiCmdFifoStatusFtraceEvent> T* set_dsi_cmd_fifo_status() {
+    return BeginNestedMessage<T>(428);
+  }
+
+
+  using FieldMetadata_DsiRx =
+    ::protozero::proto_utils::FieldMetadata<
+      429,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DsiRxFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DsiRx kDsiRx{};
+  template <typename T = DsiRxFtraceEvent> T* set_dsi_rx() {
+    return BeginNestedMessage<T>(429);
+  }
+
+
+  using FieldMetadata_DsiTx =
+    ::protozero::proto_utils::FieldMetadata<
+      430,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DsiTxFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_DsiTx kDsiTx{};
+  template <typename T = DsiTxFtraceEvent> T* set_dsi_tx() {
+    return BeginNestedMessage<T>(430);
+  }
+
+
+  using FieldMetadata_AndroidFsDatareadEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      431,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsDatareadEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsDatareadEnd kAndroidFsDatareadEnd{};
+  template <typename T = AndroidFsDatareadEndFtraceEvent> T* set_android_fs_dataread_end() {
+    return BeginNestedMessage<T>(431);
+  }
+
+
+  using FieldMetadata_AndroidFsDatareadStart =
+    ::protozero::proto_utils::FieldMetadata<
+      432,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsDatareadStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsDatareadStart kAndroidFsDatareadStart{};
+  template <typename T = AndroidFsDatareadStartFtraceEvent> T* set_android_fs_dataread_start() {
+    return BeginNestedMessage<T>(432);
+  }
+
+
+  using FieldMetadata_AndroidFsDatawriteEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      433,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsDatawriteEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsDatawriteEnd kAndroidFsDatawriteEnd{};
+  template <typename T = AndroidFsDatawriteEndFtraceEvent> T* set_android_fs_datawrite_end() {
+    return BeginNestedMessage<T>(433);
+  }
+
+
+  using FieldMetadata_AndroidFsDatawriteStart =
+    ::protozero::proto_utils::FieldMetadata<
+      434,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsDatawriteStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsDatawriteStart kAndroidFsDatawriteStart{};
+  template <typename T = AndroidFsDatawriteStartFtraceEvent> T* set_android_fs_datawrite_start() {
+    return BeginNestedMessage<T>(434);
+  }
+
+
+  using FieldMetadata_AndroidFsFsyncEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      435,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsFsyncEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsFsyncEnd kAndroidFsFsyncEnd{};
+  template <typename T = AndroidFsFsyncEndFtraceEvent> T* set_android_fs_fsync_end() {
+    return BeginNestedMessage<T>(435);
+  }
+
+
+  using FieldMetadata_AndroidFsFsyncStart =
+    ::protozero::proto_utils::FieldMetadata<
+      436,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidFsFsyncStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_AndroidFsFsyncStart kAndroidFsFsyncStart{};
+  template <typename T = AndroidFsFsyncStartFtraceEvent> T* set_android_fs_fsync_start() {
+    return BeginNestedMessage<T>(436);
+  }
+
+
+  using FieldMetadata_FuncgraphEntry =
+    ::protozero::proto_utils::FieldMetadata<
+      437,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FuncgraphEntryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FuncgraphEntry kFuncgraphEntry{};
+  template <typename T = FuncgraphEntryFtraceEvent> T* set_funcgraph_entry() {
+    return BeginNestedMessage<T>(437);
+  }
+
+
+  using FieldMetadata_FuncgraphExit =
+    ::protozero::proto_utils::FieldMetadata<
+      438,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FuncgraphExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_FuncgraphExit kFuncgraphExit{};
+  template <typename T = FuncgraphExitFtraceEvent> T* set_funcgraph_exit() {
+    return BeginNestedMessage<T>(438);
+  }
+
+
+  using FieldMetadata_VirtioVideoCmd =
+    ::protozero::proto_utils::FieldMetadata<
+      439,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioVideoCmdFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioVideoCmd kVirtioVideoCmd{};
+  template <typename T = VirtioVideoCmdFtraceEvent> T* set_virtio_video_cmd() {
+    return BeginNestedMessage<T>(439);
+  }
+
+
+  using FieldMetadata_VirtioVideoCmdDone =
+    ::protozero::proto_utils::FieldMetadata<
+      440,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioVideoCmdDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioVideoCmdDone kVirtioVideoCmdDone{};
+  template <typename T = VirtioVideoCmdDoneFtraceEvent> T* set_virtio_video_cmd_done() {
+    return BeginNestedMessage<T>(440);
+  }
+
+
+  using FieldMetadata_VirtioVideoResourceQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      441,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioVideoResourceQueueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioVideoResourceQueue kVirtioVideoResourceQueue{};
+  template <typename T = VirtioVideoResourceQueueFtraceEvent> T* set_virtio_video_resource_queue() {
+    return BeginNestedMessage<T>(441);
+  }
+
+
+  using FieldMetadata_VirtioVideoResourceQueueDone =
+    ::protozero::proto_utils::FieldMetadata<
+      442,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioVideoResourceQueueDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioVideoResourceQueueDone kVirtioVideoResourceQueueDone{};
+  template <typename T = VirtioVideoResourceQueueDoneFtraceEvent> T* set_virtio_video_resource_queue_done() {
+    return BeginNestedMessage<T>(442);
+  }
+
+
+  using FieldMetadata_MmShrinkSlabStart =
+    ::protozero::proto_utils::FieldMetadata<
+      443,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmShrinkSlabStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmShrinkSlabStart kMmShrinkSlabStart{};
+  template <typename T = MmShrinkSlabStartFtraceEvent> T* set_mm_shrink_slab_start() {
+    return BeginNestedMessage<T>(443);
+  }
+
+
+  using FieldMetadata_MmShrinkSlabEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      444,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MmShrinkSlabEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MmShrinkSlabEnd kMmShrinkSlabEnd{};
+  template <typename T = MmShrinkSlabEndFtraceEvent> T* set_mm_shrink_slab_end() {
+    return BeginNestedMessage<T>(444);
+  }
+
+
+  using FieldMetadata_TrustySmc =
+    ::protozero::proto_utils::FieldMetadata<
+      445,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustySmcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustySmc kTrustySmc{};
+  template <typename T = TrustySmcFtraceEvent> T* set_trusty_smc() {
+    return BeginNestedMessage<T>(445);
+  }
+
+
+  using FieldMetadata_TrustySmcDone =
+    ::protozero::proto_utils::FieldMetadata<
+      446,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustySmcDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustySmcDone kTrustySmcDone{};
+  template <typename T = TrustySmcDoneFtraceEvent> T* set_trusty_smc_done() {
+    return BeginNestedMessage<T>(446);
+  }
+
+
+  using FieldMetadata_TrustyStdCall32 =
+    ::protozero::proto_utils::FieldMetadata<
+      447,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyStdCall32FtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyStdCall32 kTrustyStdCall32{};
+  template <typename T = TrustyStdCall32FtraceEvent> T* set_trusty_std_call32() {
+    return BeginNestedMessage<T>(447);
+  }
+
+
+  using FieldMetadata_TrustyStdCall32Done =
+    ::protozero::proto_utils::FieldMetadata<
+      448,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyStdCall32DoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyStdCall32Done kTrustyStdCall32Done{};
+  template <typename T = TrustyStdCall32DoneFtraceEvent> T* set_trusty_std_call32_done() {
+    return BeginNestedMessage<T>(448);
+  }
+
+
+  using FieldMetadata_TrustyShareMemory =
+    ::protozero::proto_utils::FieldMetadata<
+      449,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyShareMemoryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyShareMemory kTrustyShareMemory{};
+  template <typename T = TrustyShareMemoryFtraceEvent> T* set_trusty_share_memory() {
+    return BeginNestedMessage<T>(449);
+  }
+
+
+  using FieldMetadata_TrustyShareMemoryDone =
+    ::protozero::proto_utils::FieldMetadata<
+      450,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyShareMemoryDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyShareMemoryDone kTrustyShareMemoryDone{};
+  template <typename T = TrustyShareMemoryDoneFtraceEvent> T* set_trusty_share_memory_done() {
+    return BeginNestedMessage<T>(450);
+  }
+
+
+  using FieldMetadata_TrustyReclaimMemory =
+    ::protozero::proto_utils::FieldMetadata<
+      451,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyReclaimMemoryFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyReclaimMemory kTrustyReclaimMemory{};
+  template <typename T = TrustyReclaimMemoryFtraceEvent> T* set_trusty_reclaim_memory() {
+    return BeginNestedMessage<T>(451);
+  }
+
+
+  using FieldMetadata_TrustyReclaimMemoryDone =
+    ::protozero::proto_utils::FieldMetadata<
+      452,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyReclaimMemoryDoneFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyReclaimMemoryDone kTrustyReclaimMemoryDone{};
+  template <typename T = TrustyReclaimMemoryDoneFtraceEvent> T* set_trusty_reclaim_memory_done() {
+    return BeginNestedMessage<T>(452);
+  }
+
+
+  using FieldMetadata_TrustyIrq =
+    ::protozero::proto_utils::FieldMetadata<
+      453,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIrqFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIrq kTrustyIrq{};
+  template <typename T = TrustyIrqFtraceEvent> T* set_trusty_irq() {
+    return BeginNestedMessage<T>(453);
+  }
+
+
+  using FieldMetadata_TrustyIpcHandleEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      454,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcHandleEventFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcHandleEvent kTrustyIpcHandleEvent{};
+  template <typename T = TrustyIpcHandleEventFtraceEvent> T* set_trusty_ipc_handle_event() {
+    return BeginNestedMessage<T>(454);
+  }
+
+
+  using FieldMetadata_TrustyIpcConnect =
+    ::protozero::proto_utils::FieldMetadata<
+      455,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcConnectFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcConnect kTrustyIpcConnect{};
+  template <typename T = TrustyIpcConnectFtraceEvent> T* set_trusty_ipc_connect() {
+    return BeginNestedMessage<T>(455);
+  }
+
+
+  using FieldMetadata_TrustyIpcConnectEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      456,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcConnectEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcConnectEnd kTrustyIpcConnectEnd{};
+  template <typename T = TrustyIpcConnectEndFtraceEvent> T* set_trusty_ipc_connect_end() {
+    return BeginNestedMessage<T>(456);
+  }
+
+
+  using FieldMetadata_TrustyIpcWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      457,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcWrite kTrustyIpcWrite{};
+  template <typename T = TrustyIpcWriteFtraceEvent> T* set_trusty_ipc_write() {
+    return BeginNestedMessage<T>(457);
+  }
+
+
+  using FieldMetadata_TrustyIpcPoll =
+    ::protozero::proto_utils::FieldMetadata<
+      458,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcPollFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcPoll kTrustyIpcPoll{};
+  template <typename T = TrustyIpcPollFtraceEvent> T* set_trusty_ipc_poll() {
+    return BeginNestedMessage<T>(458);
+  }
+
+
+  using FieldMetadata_TrustyIpcRead =
+    ::protozero::proto_utils::FieldMetadata<
+      460,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcReadFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcRead kTrustyIpcRead{};
+  template <typename T = TrustyIpcReadFtraceEvent> T* set_trusty_ipc_read() {
+    return BeginNestedMessage<T>(460);
+  }
+
+
+  using FieldMetadata_TrustyIpcReadEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      461,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcReadEndFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcReadEnd kTrustyIpcReadEnd{};
+  template <typename T = TrustyIpcReadEndFtraceEvent> T* set_trusty_ipc_read_end() {
+    return BeginNestedMessage<T>(461);
+  }
+
+
+  using FieldMetadata_TrustyIpcRx =
+    ::protozero::proto_utils::FieldMetadata<
+      462,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyIpcRxFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyIpcRx kTrustyIpcRx{};
+  template <typename T = TrustyIpcRxFtraceEvent> T* set_trusty_ipc_rx() {
+    return BeginNestedMessage<T>(462);
+  }
+
+
+  using FieldMetadata_TrustyEnqueueNop =
+    ::protozero::proto_utils::FieldMetadata<
+      464,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrustyEnqueueNopFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_TrustyEnqueueNop kTrustyEnqueueNop{};
+  template <typename T = TrustyEnqueueNopFtraceEvent> T* set_trusty_enqueue_nop() {
+    return BeginNestedMessage<T>(464);
+  }
+
+
+  using FieldMetadata_CmaAllocStart =
+    ::protozero::proto_utils::FieldMetadata<
+      465,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CmaAllocStartFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CmaAllocStart kCmaAllocStart{};
+  template <typename T = CmaAllocStartFtraceEvent> T* set_cma_alloc_start() {
+    return BeginNestedMessage<T>(465);
+  }
+
+
+  using FieldMetadata_CmaAllocInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      466,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CmaAllocInfoFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_CmaAllocInfo kCmaAllocInfo{};
+  template <typename T = CmaAllocInfoFtraceEvent> T* set_cma_alloc_info() {
+    return BeginNestedMessage<T>(466);
+  }
+
+
+  using FieldMetadata_LwisTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      467,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      LwisTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_LwisTracingMarkWrite kLwisTracingMarkWrite{};
+  template <typename T = LwisTracingMarkWriteFtraceEvent> T* set_lwis_tracing_mark_write() {
+    return BeginNestedMessage<T>(467);
+  }
+
+
+  using FieldMetadata_VirtioGpuCmdQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      468,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioGpuCmdQueueFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioGpuCmdQueue kVirtioGpuCmdQueue{};
+  template <typename T = VirtioGpuCmdQueueFtraceEvent> T* set_virtio_gpu_cmd_queue() {
+    return BeginNestedMessage<T>(468);
+  }
+
+
+  using FieldMetadata_VirtioGpuCmdResponse =
+    ::protozero::proto_utils::FieldMetadata<
+      469,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VirtioGpuCmdResponseFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_VirtioGpuCmdResponse kVirtioGpuCmdResponse{};
+  template <typename T = VirtioGpuCmdResponseFtraceEvent> T* set_virtio_gpu_cmd_response() {
+    return BeginNestedMessage<T>(469);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUCQSSET =
+    ::protozero::proto_utils::FieldMetadata<
+      470,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUCQSSETFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUCQSSET kMaliMaliKCPUCQSSET{};
+  template <typename T = MaliMaliKCPUCQSSETFtraceEvent> T* set_mali_mali_kcpu_cqs_set() {
+    return BeginNestedMessage<T>(470);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUCQSWAITSTART =
+    ::protozero::proto_utils::FieldMetadata<
+      471,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUCQSWAITSTART kMaliMaliKCPUCQSWAITSTART{};
+  template <typename T = MaliMaliKCPUCQSWAITSTARTFtraceEvent> T* set_mali_mali_kcpu_cqs_wait_start() {
+    return BeginNestedMessage<T>(471);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUCQSWAITEND =
+    ::protozero::proto_utils::FieldMetadata<
+      472,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUCQSWAITENDFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUCQSWAITEND kMaliMaliKCPUCQSWAITEND{};
+  template <typename T = MaliMaliKCPUCQSWAITENDFtraceEvent> T* set_mali_mali_kcpu_cqs_wait_end() {
+    return BeginNestedMessage<T>(472);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUFENCESIGNAL =
+    ::protozero::proto_utils::FieldMetadata<
+      473,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUFENCESIGNALFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUFENCESIGNAL kMaliMaliKCPUFENCESIGNAL{};
+  template <typename T = MaliMaliKCPUFENCESIGNALFtraceEvent> T* set_mali_mali_kcpu_fence_signal() {
+    return BeginNestedMessage<T>(473);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUFENCEWAITSTART =
+    ::protozero::proto_utils::FieldMetadata<
+      474,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUFENCEWAITSTART kMaliMaliKCPUFENCEWAITSTART{};
+  template <typename T = MaliMaliKCPUFENCEWAITSTARTFtraceEvent> T* set_mali_mali_kcpu_fence_wait_start() {
+    return BeginNestedMessage<T>(474);
+  }
+
+
+  using FieldMetadata_MaliMaliKCPUFENCEWAITEND =
+    ::protozero::proto_utils::FieldMetadata<
+      475,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliKCPUFENCEWAITEND kMaliMaliKCPUFENCEWAITEND{};
+  template <typename T = MaliMaliKCPUFENCEWAITENDFtraceEvent> T* set_mali_mali_kcpu_fence_wait_end() {
+    return BeginNestedMessage<T>(475);
+  }
+
+
+  using FieldMetadata_HypEnter =
+    ::protozero::proto_utils::FieldMetadata<
+      476,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HypEnterFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_HypEnter kHypEnter{};
+  template <typename T = HypEnterFtraceEvent> T* set_hyp_enter() {
+    return BeginNestedMessage<T>(476);
+  }
+
+
+  using FieldMetadata_HypExit =
+    ::protozero::proto_utils::FieldMetadata<
+      477,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HypExitFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_HypExit kHypExit{};
+  template <typename T = HypExitFtraceEvent> T* set_hyp_exit() {
+    return BeginNestedMessage<T>(477);
+  }
+
+
+  using FieldMetadata_HostHcall =
+    ::protozero::proto_utils::FieldMetadata<
+      478,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HostHcallFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_HostHcall kHostHcall{};
+  template <typename T = HostHcallFtraceEvent> T* set_host_hcall() {
+    return BeginNestedMessage<T>(478);
+  }
+
+
+  using FieldMetadata_HostSmc =
+    ::protozero::proto_utils::FieldMetadata<
+      479,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HostSmcFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_HostSmc kHostSmc{};
+  template <typename T = HostSmcFtraceEvent> T* set_host_smc() {
+    return BeginNestedMessage<T>(479);
+  }
+
+
+  using FieldMetadata_HostMemAbort =
+    ::protozero::proto_utils::FieldMetadata<
+      480,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HostMemAbortFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_HostMemAbort kHostMemAbort{};
+  template <typename T = HostMemAbortFtraceEvent> T* set_host_mem_abort() {
+    return BeginNestedMessage<T>(480);
+  }
+
+
+  using FieldMetadata_SuspendResumeMinimal =
+    ::protozero::proto_utils::FieldMetadata<
+      481,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SuspendResumeMinimalFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SuspendResumeMinimal kSuspendResumeMinimal{};
+  template <typename T = SuspendResumeMinimalFtraceEvent> T* set_suspend_resume_minimal() {
+    return BeginNestedMessage<T>(481);
+  }
+
+
+  using FieldMetadata_MaliMaliCSFINTERRUPTSTART =
+    ::protozero::proto_utils::FieldMetadata<
+      482,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliCSFINTERRUPTSTARTFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliCSFINTERRUPTSTART kMaliMaliCSFINTERRUPTSTART{};
+  template <typename T = MaliMaliCSFINTERRUPTSTARTFtraceEvent> T* set_mali_mali_csf_interrupt_start() {
+    return BeginNestedMessage<T>(482);
+  }
+
+
+  using FieldMetadata_MaliMaliCSFINTERRUPTEND =
+    ::protozero::proto_utils::FieldMetadata<
+      483,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MaliMaliCSFINTERRUPTENDFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_MaliMaliCSFINTERRUPTEND kMaliMaliCSFINTERRUPTEND{};
+  template <typename T = MaliMaliCSFINTERRUPTENDFtraceEvent> T* set_mali_mali_csf_interrupt_end() {
+    return BeginNestedMessage<T>(483);
+  }
+
+
+  using FieldMetadata_SamsungTracingMarkWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      484,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SamsungTracingMarkWriteFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SamsungTracingMarkWrite kSamsungTracingMarkWrite{};
+  template <typename T = SamsungTracingMarkWriteFtraceEvent> T* set_samsung_tracing_mark_write() {
+    return BeginNestedMessage<T>(484);
+  }
+
+
+  using FieldMetadata_BinderCommand =
+    ::protozero::proto_utils::FieldMetadata<
+      485,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderCommandFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderCommand kBinderCommand{};
+  template <typename T = BinderCommandFtraceEvent> T* set_binder_command() {
+    return BeginNestedMessage<T>(485);
+  }
+
+
+  using FieldMetadata_BinderReturn =
+    ::protozero::proto_utils::FieldMetadata<
+      486,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BinderReturnFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_BinderReturn kBinderReturn{};
+  template <typename T = BinderReturnFtraceEvent> T* set_binder_return() {
+    return BeginNestedMessage<T>(486);
+  }
+
+
+  using FieldMetadata_SchedSwitchWithCtrs =
+    ::protozero::proto_utils::FieldMetadata<
+      487,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SchedSwitchWithCtrsFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_SchedSwitchWithCtrs kSchedSwitchWithCtrs{};
+  template <typename T = SchedSwitchWithCtrsFtraceEvent> T* set_sched_switch_with_ctrs() {
+    return BeginNestedMessage<T>(487);
+  }
+
+
+  using FieldMetadata_GpuWorkPeriod =
+    ::protozero::proto_utils::FieldMetadata<
+      488,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuWorkPeriodFtraceEvent,
+      FtraceEvent>;
+
+  static constexpr FieldMetadata_GpuWorkPeriod kGpuWorkPeriod{};
+  template <typename T = GpuWorkPeriodFtraceEvent> T* set_gpu_work_period() {
+    return BeginNestedMessage<T>(488);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_EVENT_BUNDLE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_EVENT_BUNDLE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FtraceEvent;
+class FtraceEventBundle_CompactSched;
+enum FtraceClock : int32_t;
+
+enum FtraceClock : int32_t {
+  FTRACE_CLOCK_UNSPECIFIED = 0,
+  FTRACE_CLOCK_UNKNOWN = 1,
+  FTRACE_CLOCK_GLOBAL = 2,
+  FTRACE_CLOCK_LOCAL = 3,
+  FTRACE_CLOCK_MONO_RAW = 4,
+};
+
+constexpr FtraceClock FtraceClock_MIN = FtraceClock::FTRACE_CLOCK_UNSPECIFIED;
+constexpr FtraceClock FtraceClock_MAX = FtraceClock::FTRACE_CLOCK_MONO_RAW;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FtraceClock_Name(::perfetto::protos::pbzero::FtraceClock value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FtraceClock::FTRACE_CLOCK_UNSPECIFIED:
+    return "FTRACE_CLOCK_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FtraceClock::FTRACE_CLOCK_UNKNOWN:
+    return "FTRACE_CLOCK_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::FtraceClock::FTRACE_CLOCK_GLOBAL:
+    return "FTRACE_CLOCK_GLOBAL";
+
+  case ::perfetto::protos::pbzero::FtraceClock::FTRACE_CLOCK_LOCAL:
+    return "FTRACE_CLOCK_LOCAL";
+
+  case ::perfetto::protos::pbzero::FtraceClock::FTRACE_CLOCK_MONO_RAW:
+    return "FTRACE_CLOCK_MONO_RAW";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class FtraceEventBundle_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceEventBundle_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceEventBundle_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceEventBundle_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_event() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> event() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_lost_events() const { return at<3>().valid(); }
+  bool lost_events() const { return at<3>().as_bool(); }
+  bool has_compact_sched() const { return at<4>().valid(); }
+  ::protozero::ConstBytes compact_sched() const { return at<4>().as_bytes(); }
+  bool has_ftrace_clock() const { return at<5>().valid(); }
+  int32_t ftrace_clock() const { return at<5>().as_int32(); }
+  bool has_ftrace_timestamp() const { return at<6>().valid(); }
+  int64_t ftrace_timestamp() const { return at<6>().as_int64(); }
+  bool has_boot_timestamp() const { return at<7>().valid(); }
+  int64_t boot_timestamp() const { return at<7>().as_int64(); }
+};
+
+class FtraceEventBundle : public ::protozero::Message {
+ public:
+  using Decoder = FtraceEventBundle_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kEventFieldNumber = 2,
+    kLostEventsFieldNumber = 3,
+    kCompactSchedFieldNumber = 4,
+    kFtraceClockFieldNumber = 5,
+    kFtraceTimestampFieldNumber = 6,
+    kBootTimestampFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceEventBundle"; }
+
+  using CompactSched = ::perfetto::protos::pbzero::FtraceEventBundle_CompactSched;
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Event =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceEvent,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_Event kEvent{};
+  template <typename T = FtraceEvent> T* add_event() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_LostEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_LostEvents kLostEvents{};
+  void set_lost_events(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_LostEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CompactSched =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceEventBundle_CompactSched,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_CompactSched kCompactSched{};
+  template <typename T = FtraceEventBundle_CompactSched> T* set_compact_sched() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_FtraceClock =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FtraceClock,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_FtraceClock kFtraceClock{};
+  void set_ftrace_clock(::perfetto::protos::pbzero::FtraceClock value) {
+    static constexpr uint32_t field_id = FieldMetadata_FtraceClock::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FtraceTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_FtraceTimestamp kFtraceTimestamp{};
+  void set_ftrace_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FtraceTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BootTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FtraceEventBundle>;
+
+  static constexpr FieldMetadata_BootTimestamp kBootTimestamp{};
+  void set_boot_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BootTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FtraceEventBundle_CompactSched_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceEventBundle_CompactSched_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceEventBundle_CompactSched_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceEventBundle_CompactSched_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_intern_table() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> intern_table() const { return GetRepeated<::protozero::ConstChars>(5); }
+  bool has_switch_timestamp() const { return at<1>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> switch_timestamp(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(1, parse_error_ptr); }
+  bool has_switch_prev_state() const { return at<2>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t> switch_prev_state(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t>(2, parse_error_ptr); }
+  bool has_switch_next_pid() const { return at<3>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> switch_next_pid(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(3, parse_error_ptr); }
+  bool has_switch_next_prio() const { return at<4>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> switch_next_prio(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(4, parse_error_ptr); }
+  bool has_switch_next_comm_index() const { return at<6>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t> switch_next_comm_index(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t>(6, parse_error_ptr); }
+  bool has_waking_timestamp() const { return at<7>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> waking_timestamp(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(7, parse_error_ptr); }
+  bool has_waking_pid() const { return at<8>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> waking_pid(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(8, parse_error_ptr); }
+  bool has_waking_target_cpu() const { return at<9>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> waking_target_cpu(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(9, parse_error_ptr); }
+  bool has_waking_prio() const { return at<10>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t> waking_prio(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int32_t>(10, parse_error_ptr); }
+  bool has_waking_comm_index() const { return at<11>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t> waking_comm_index(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t>(11, parse_error_ptr); }
+  bool has_waking_common_flags() const { return at<12>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t> waking_common_flags(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint32_t>(12, parse_error_ptr); }
+};
+
+class FtraceEventBundle_CompactSched : public ::protozero::Message {
+ public:
+  using Decoder = FtraceEventBundle_CompactSched_Decoder;
+  enum : int32_t {
+    kInternTableFieldNumber = 5,
+    kSwitchTimestampFieldNumber = 1,
+    kSwitchPrevStateFieldNumber = 2,
+    kSwitchNextPidFieldNumber = 3,
+    kSwitchNextPrioFieldNumber = 4,
+    kSwitchNextCommIndexFieldNumber = 6,
+    kWakingTimestampFieldNumber = 7,
+    kWakingPidFieldNumber = 8,
+    kWakingTargetCpuFieldNumber = 9,
+    kWakingPrioFieldNumber = 10,
+    kWakingCommIndexFieldNumber = 11,
+    kWakingCommonFlagsFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceEventBundle.CompactSched"; }
+
+
+  using FieldMetadata_InternTable =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_InternTable kInternTable{};
+  void add_intern_table(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_InternTable::kFieldId, data, size);
+  }
+  void add_intern_table(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_InternTable::kFieldId, chars.data, chars.size);
+  }
+  void add_intern_table(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_InternTable::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SwitchTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_SwitchTimestamp kSwitchTimestamp{};
+  void set_switch_timestamp(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_SwitchTimestamp::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_SwitchPrevState =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_SwitchPrevState kSwitchPrevState{};
+  void set_switch_prev_state(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_SwitchPrevState::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_SwitchNextPid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_SwitchNextPid kSwitchNextPid{};
+  void set_switch_next_pid(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_SwitchNextPid::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_SwitchNextPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_SwitchNextPrio kSwitchNextPrio{};
+  void set_switch_next_prio(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_SwitchNextPrio::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_SwitchNextCommIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_SwitchNextCommIndex kSwitchNextCommIndex{};
+  void set_switch_next_comm_index(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_SwitchNextCommIndex::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingTimestamp kWakingTimestamp{};
+  void set_waking_timestamp(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingTimestamp::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingPid =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingPid kWakingPid{};
+  void set_waking_pid(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingPid::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingTargetCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingTargetCpu kWakingTargetCpu{};
+  void set_waking_target_cpu(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingTargetCpu::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingPrio kWakingPrio{};
+  void set_waking_prio(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingPrio::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingCommIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingCommIndex kWakingCommIndex{};
+  void set_waking_comm_index(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingCommIndex::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_WakingCommonFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceEventBundle_CompactSched>;
+
+  static constexpr FieldMetadata_WakingCommonFlags kWakingCommonFlags{};
+  void set_waking_common_flags(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_WakingCommonFlags::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_STATS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_STATS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FtraceCpuStats;
+namespace perfetto_pbzero_enum_FtraceStats {
+enum Phase : int32_t;
+}  // namespace perfetto_pbzero_enum_FtraceStats
+using FtraceStats_Phase = perfetto_pbzero_enum_FtraceStats::Phase;
+
+namespace perfetto_pbzero_enum_FtraceStats {
+enum Phase : int32_t {
+  UNSPECIFIED = 0,
+  START_OF_TRACE = 1,
+  END_OF_TRACE = 2,
+};
+} // namespace perfetto_pbzero_enum_FtraceStats
+using FtraceStats_Phase = perfetto_pbzero_enum_FtraceStats::Phase;
+
+
+constexpr FtraceStats_Phase FtraceStats_Phase_MIN = FtraceStats_Phase::UNSPECIFIED;
+constexpr FtraceStats_Phase FtraceStats_Phase_MAX = FtraceStats_Phase::END_OF_TRACE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* FtraceStats_Phase_Name(::perfetto::protos::pbzero::FtraceStats_Phase value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::FtraceStats_Phase::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::FtraceStats_Phase::START_OF_TRACE:
+    return "START_OF_TRACE";
+
+  case ::perfetto::protos::pbzero::FtraceStats_Phase::END_OF_TRACE:
+    return "END_OF_TRACE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class FtraceStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  FtraceStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_phase() const { return at<1>().valid(); }
+  int32_t phase() const { return at<1>().as_int32(); }
+  bool has_cpu_stats() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> cpu_stats() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_kernel_symbols_parsed() const { return at<3>().valid(); }
+  uint32_t kernel_symbols_parsed() const { return at<3>().as_uint32(); }
+  bool has_kernel_symbols_mem_kb() const { return at<4>().valid(); }
+  uint32_t kernel_symbols_mem_kb() const { return at<4>().as_uint32(); }
+  bool has_atrace_errors() const { return at<5>().valid(); }
+  ::protozero::ConstChars atrace_errors() const { return at<5>().as_string(); }
+  bool has_unknown_ftrace_events() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> unknown_ftrace_events() const { return GetRepeated<::protozero::ConstChars>(6); }
+  bool has_failed_ftrace_events() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> failed_ftrace_events() const { return GetRepeated<::protozero::ConstChars>(7); }
+  bool has_preserve_ftrace_buffer() const { return at<8>().valid(); }
+  bool preserve_ftrace_buffer() const { return at<8>().as_bool(); }
+};
+
+class FtraceStats : public ::protozero::Message {
+ public:
+  using Decoder = FtraceStats_Decoder;
+  enum : int32_t {
+    kPhaseFieldNumber = 1,
+    kCpuStatsFieldNumber = 2,
+    kKernelSymbolsParsedFieldNumber = 3,
+    kKernelSymbolsMemKbFieldNumber = 4,
+    kAtraceErrorsFieldNumber = 5,
+    kUnknownFtraceEventsFieldNumber = 6,
+    kFailedFtraceEventsFieldNumber = 7,
+    kPreserveFtraceBufferFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceStats"; }
+
+
+  using Phase = ::perfetto::protos::pbzero::FtraceStats_Phase;
+  static inline const char* Phase_Name(Phase value) {
+    return ::perfetto::protos::pbzero::FtraceStats_Phase_Name(value);
+  }
+  static inline const Phase UNSPECIFIED = Phase::UNSPECIFIED;
+  static inline const Phase START_OF_TRACE = Phase::START_OF_TRACE;
+  static inline const Phase END_OF_TRACE = Phase::END_OF_TRACE;
+
+  using FieldMetadata_Phase =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::FtraceStats_Phase,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_Phase kPhase{};
+  void set_phase(::perfetto::protos::pbzero::FtraceStats_Phase value) {
+    static constexpr uint32_t field_id = FieldMetadata_Phase::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuStats =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceCpuStats,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_CpuStats kCpuStats{};
+  template <typename T = FtraceCpuStats> T* add_cpu_stats() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_KernelSymbolsParsed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_KernelSymbolsParsed kKernelSymbolsParsed{};
+  void set_kernel_symbols_parsed(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelSymbolsParsed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KernelSymbolsMemKb =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_KernelSymbolsMemKb kKernelSymbolsMemKb{};
+  void set_kernel_symbols_mem_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelSymbolsMemKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AtraceErrors =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_AtraceErrors kAtraceErrors{};
+  void set_atrace_errors(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AtraceErrors::kFieldId, data, size);
+  }
+  void set_atrace_errors(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AtraceErrors::kFieldId, chars.data, chars.size);
+  }
+  void set_atrace_errors(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AtraceErrors::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UnknownFtraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_UnknownFtraceEvents kUnknownFtraceEvents{};
+  void add_unknown_ftrace_events(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_UnknownFtraceEvents::kFieldId, data, size);
+  }
+  void add_unknown_ftrace_events(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_UnknownFtraceEvents::kFieldId, chars.data, chars.size);
+  }
+  void add_unknown_ftrace_events(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnknownFtraceEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FailedFtraceEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_FailedFtraceEvents kFailedFtraceEvents{};
+  void add_failed_ftrace_events(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FailedFtraceEvents::kFieldId, data, size);
+  }
+  void add_failed_ftrace_events(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FailedFtraceEvents::kFieldId, chars.data, chars.size);
+  }
+  void add_failed_ftrace_events(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FailedFtraceEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PreserveFtraceBuffer =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      FtraceStats>;
+
+  static constexpr FieldMetadata_PreserveFtraceBuffer kPreserveFtraceBuffer{};
+  void set_preserve_ftrace_buffer(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreserveFtraceBuffer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FtraceCpuStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FtraceCpuStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FtraceCpuStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FtraceCpuStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint64_t cpu() const { return at<1>().as_uint64(); }
+  bool has_entries() const { return at<2>().valid(); }
+  uint64_t entries() const { return at<2>().as_uint64(); }
+  bool has_overrun() const { return at<3>().valid(); }
+  uint64_t overrun() const { return at<3>().as_uint64(); }
+  bool has_commit_overrun() const { return at<4>().valid(); }
+  uint64_t commit_overrun() const { return at<4>().as_uint64(); }
+  bool has_bytes_read() const { return at<5>().valid(); }
+  uint64_t bytes_read() const { return at<5>().as_uint64(); }
+  bool has_oldest_event_ts() const { return at<6>().valid(); }
+  double oldest_event_ts() const { return at<6>().as_double(); }
+  bool has_now_ts() const { return at<7>().valid(); }
+  double now_ts() const { return at<7>().as_double(); }
+  bool has_dropped_events() const { return at<8>().valid(); }
+  uint64_t dropped_events() const { return at<8>().as_uint64(); }
+  bool has_read_events() const { return at<9>().valid(); }
+  uint64_t read_events() const { return at<9>().as_uint64(); }
+};
+
+class FtraceCpuStats : public ::protozero::Message {
+ public:
+  using Decoder = FtraceCpuStats_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kEntriesFieldNumber = 2,
+    kOverrunFieldNumber = 3,
+    kCommitOverrunFieldNumber = 4,
+    kBytesReadFieldNumber = 5,
+    kOldestEventTsFieldNumber = 6,
+    kNowTsFieldNumber = 7,
+    kDroppedEventsFieldNumber = 8,
+    kReadEventsFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FtraceCpuStats"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Entries =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_Entries kEntries{};
+  void set_entries(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Entries::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Overrun =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_Overrun kOverrun{};
+  void set_overrun(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Overrun::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CommitOverrun =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_CommitOverrun kCommitOverrun{};
+  void set_commit_overrun(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CommitOverrun::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BytesRead =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_BytesRead kBytesRead{};
+  void set_bytes_read(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesRead::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldestEventTs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_OldestEventTs kOldestEventTs{};
+  void set_oldest_event_ts(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldestEventTs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NowTs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_NowTs kNowTs{};
+  void set_now_ts(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_NowTs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DroppedEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_DroppedEvents kDroppedEvents{};
+  void set_dropped_events(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DroppedEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReadEvents =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FtraceCpuStats>;
+
+  static constexpr FieldMetadata_ReadEvents kReadEvents{};
+  void set_read_events(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadEvents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TEST_BUNDLE_WRAPPER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TEST_BUNDLE_WRAPPER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FtraceEventBundle;
+
+class TestBundleWrapper_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TestBundleWrapper_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestBundleWrapper_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestBundleWrapper_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_before() const { return at<1>().valid(); }
+  ::protozero::ConstChars before() const { return at<1>().as_string(); }
+  bool has_bundle() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> bundle() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_after() const { return at<3>().valid(); }
+  ::protozero::ConstChars after() const { return at<3>().as_string(); }
+};
+
+class TestBundleWrapper : public ::protozero::Message {
+ public:
+  using Decoder = TestBundleWrapper_Decoder;
+  enum : int32_t {
+    kBeforeFieldNumber = 1,
+    kBundleFieldNumber = 2,
+    kAfterFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestBundleWrapper"; }
+
+
+  using FieldMetadata_Before =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestBundleWrapper>;
+
+  static constexpr FieldMetadata_Before kBefore{};
+  void set_before(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Before::kFieldId, data, size);
+  }
+  void set_before(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Before::kFieldId, chars.data, chars.size);
+  }
+  void set_before(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Before::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Bundle =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FtraceEventBundle,
+      TestBundleWrapper>;
+
+  static constexpr FieldMetadata_Bundle kBundle{};
+  template <typename T = FtraceEventBundle> T* add_bundle() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_After =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestBundleWrapper>;
+
+  static constexpr FieldMetadata_After kAfter{};
+  void set_after(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_After::kFieldId, data, size);
+  }
+  void set_after(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_After::kFieldId, chars.data, chars.size);
+  }
+  void set_after(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_After::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/generic.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GENERIC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GENERIC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GenericFtraceEvent_Field;
+
+class GenericFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GenericFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GenericFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GenericFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars event_name() const { return at<1>().as_string(); }
+  bool has_field() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> field() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class GenericFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = GenericFtraceEvent_Decoder;
+  enum : int32_t {
+    kEventNameFieldNumber = 1,
+    kFieldFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GenericFtraceEvent"; }
+
+  using Field = ::perfetto::protos::pbzero::GenericFtraceEvent_Field;
+
+  using FieldMetadata_EventName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GenericFtraceEvent>;
+
+  static constexpr FieldMetadata_EventName kEventName{};
+  void set_event_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, data, size);
+  }
+  void set_event_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, chars.data, chars.size);
+  }
+  void set_event_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GenericFtraceEvent_Field,
+      GenericFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  template <typename T = GenericFtraceEvent_Field> T* add_field() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class GenericFtraceEvent_Field_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GenericFtraceEvent_Field_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GenericFtraceEvent_Field_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GenericFtraceEvent_Field_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_str_value() const { return at<3>().valid(); }
+  ::protozero::ConstChars str_value() const { return at<3>().as_string(); }
+  bool has_int_value() const { return at<4>().valid(); }
+  int64_t int_value() const { return at<4>().as_int64(); }
+  bool has_uint_value() const { return at<5>().valid(); }
+  uint64_t uint_value() const { return at<5>().as_uint64(); }
+};
+
+class GenericFtraceEvent_Field : public ::protozero::Message {
+ public:
+  using Decoder = GenericFtraceEvent_Field_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStrValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kUintValueFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GenericFtraceEvent.Field"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GenericFtraceEvent_Field>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StrValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GenericFtraceEvent_Field>;
+
+  static constexpr FieldMetadata_StrValue kStrValue{};
+  void set_str_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StrValue::kFieldId, data, size);
+  }
+  void set_str_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StrValue::kFieldId, chars.data, chars.size);
+  }
+  void set_str_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StrValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      GenericFtraceEvent_Field>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UintValue =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GenericFtraceEvent_Field>;
+
+  static constexpr FieldMetadata_UintValue kUintValue{};
+  void set_uint_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UintValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/android_fs.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_ANDROID_FS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_ANDROID_FS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class AndroidFsFsyncStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsFsyncStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsFsyncStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsFsyncStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cmdline() const { return at<1>().valid(); }
+  ::protozero::ConstChars cmdline() const { return at<1>().as_string(); }
+  bool has_i_size() const { return at<2>().valid(); }
+  int64_t i_size() const { return at<2>().as_int64(); }
+  bool has_ino() const { return at<3>().valid(); }
+  uint64_t ino() const { return at<3>().as_uint64(); }
+  bool has_pathbuf() const { return at<4>().valid(); }
+  ::protozero::ConstChars pathbuf() const { return at<4>().as_string(); }
+  bool has_pid() const { return at<5>().valid(); }
+  int32_t pid() const { return at<5>().as_int32(); }
+};
+
+class AndroidFsFsyncStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsFsyncStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kCmdlineFieldNumber = 1,
+    kISizeFieldNumber = 2,
+    kInoFieldNumber = 3,
+    kPathbufFieldNumber = 4,
+    kPidFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsFsyncStartFtraceEvent"; }
+
+
+  using FieldMetadata_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsFsyncStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void set_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void set_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void set_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ISize =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsFsyncStartFtraceEvent>;
+
+  static constexpr FieldMetadata_ISize kISize{};
+  void set_i_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ISize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsFsyncStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pathbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsFsyncStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pathbuf kPathbuf{};
+  void set_pathbuf(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, data, size);
+  }
+  void set_pathbuf(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, chars.data, chars.size);
+  }
+  void set_pathbuf(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pathbuf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsFsyncStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidFsFsyncEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsFsyncEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsFsyncEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsFsyncEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes() const { return at<1>().valid(); }
+  int32_t bytes() const { return at<1>().as_int32(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+};
+
+class AndroidFsFsyncEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsFsyncEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsFsyncEndFtraceEvent"; }
+
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsFsyncEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsFsyncEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsFsyncEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidFsDatawriteStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsDatawriteStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsDatawriteStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsDatawriteStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes() const { return at<1>().valid(); }
+  int32_t bytes() const { return at<1>().as_int32(); }
+  bool has_cmdline() const { return at<2>().valid(); }
+  ::protozero::ConstChars cmdline() const { return at<2>().as_string(); }
+  bool has_i_size() const { return at<3>().valid(); }
+  int64_t i_size() const { return at<3>().as_int64(); }
+  bool has_ino() const { return at<4>().valid(); }
+  uint64_t ino() const { return at<4>().as_uint64(); }
+  bool has_offset() const { return at<5>().valid(); }
+  int64_t offset() const { return at<5>().as_int64(); }
+  bool has_pathbuf() const { return at<6>().valid(); }
+  ::protozero::ConstChars pathbuf() const { return at<6>().as_string(); }
+  bool has_pid() const { return at<7>().valid(); }
+  int32_t pid() const { return at<7>().as_int32(); }
+};
+
+class AndroidFsDatawriteStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsDatawriteStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesFieldNumber = 1,
+    kCmdlineFieldNumber = 2,
+    kISizeFieldNumber = 3,
+    kInoFieldNumber = 4,
+    kOffsetFieldNumber = 5,
+    kPathbufFieldNumber = 6,
+    kPidFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsDatawriteStartFtraceEvent"; }
+
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void set_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void set_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void set_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ISize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_ISize kISize{};
+  void set_i_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ISize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pathbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pathbuf kPathbuf{};
+  void set_pathbuf(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, data, size);
+  }
+  void set_pathbuf(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, chars.data, chars.size);
+  }
+  void set_pathbuf(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pathbuf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatawriteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidFsDatawriteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsDatawriteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsDatawriteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsDatawriteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes() const { return at<1>().valid(); }
+  int32_t bytes() const { return at<1>().as_int32(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+};
+
+class AndroidFsDatawriteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsDatawriteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsDatawriteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatawriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsDatawriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatawriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidFsDatareadStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsDatareadStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsDatareadStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsDatareadStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes() const { return at<1>().valid(); }
+  int32_t bytes() const { return at<1>().as_int32(); }
+  bool has_cmdline() const { return at<2>().valid(); }
+  ::protozero::ConstChars cmdline() const { return at<2>().as_string(); }
+  bool has_i_size() const { return at<3>().valid(); }
+  int64_t i_size() const { return at<3>().as_int64(); }
+  bool has_ino() const { return at<4>().valid(); }
+  uint64_t ino() const { return at<4>().as_uint64(); }
+  bool has_offset() const { return at<5>().valid(); }
+  int64_t offset() const { return at<5>().as_int64(); }
+  bool has_pathbuf() const { return at<6>().valid(); }
+  ::protozero::ConstChars pathbuf() const { return at<6>().as_string(); }
+  bool has_pid() const { return at<7>().valid(); }
+  int32_t pid() const { return at<7>().as_int32(); }
+};
+
+class AndroidFsDatareadStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsDatareadStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesFieldNumber = 1,
+    kCmdlineFieldNumber = 2,
+    kISizeFieldNumber = 3,
+    kInoFieldNumber = 4,
+    kOffsetFieldNumber = 5,
+    kPathbufFieldNumber = 6,
+    kPidFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsDatareadStartFtraceEvent"; }
+
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void set_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void set_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void set_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ISize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_ISize kISize{};
+  void set_i_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ISize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pathbuf =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pathbuf kPathbuf{};
+  void set_pathbuf(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, data, size);
+  }
+  void set_pathbuf(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Pathbuf::kFieldId, chars.data, chars.size);
+  }
+  void set_pathbuf(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pathbuf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatareadStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AndroidFsDatareadEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidFsDatareadEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidFsDatareadEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidFsDatareadEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes() const { return at<1>().valid(); }
+  int32_t bytes() const { return at<1>().as_int32(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+};
+
+class AndroidFsDatareadEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AndroidFsDatareadEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidFsDatareadEndFtraceEvent"; }
+
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidFsDatareadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AndroidFsDatareadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidFsDatareadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/binder.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_BINDER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_BINDER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class BinderReturnFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderReturnFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderReturnFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderReturnFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cmd() const { return at<1>().valid(); }
+  uint32_t cmd() const { return at<1>().as_uint32(); }
+};
+
+class BinderReturnFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderReturnFtraceEvent_Decoder;
+  enum : int32_t {
+    kCmdFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderReturnFtraceEvent"; }
+
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderReturnFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BinderCommandFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderCommandFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderCommandFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderCommandFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cmd() const { return at<1>().valid(); }
+  uint32_t cmd() const { return at<1>().as_uint32(); }
+};
+
+class BinderCommandFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderCommandFtraceEvent_Decoder;
+  enum : int32_t {
+    kCmdFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderCommandFtraceEvent"; }
+
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BinderTransactionAllocBufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderTransactionAllocBufFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderTransactionAllocBufFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderTransactionAllocBufFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_data_size() const { return at<1>().valid(); }
+  uint64_t data_size() const { return at<1>().as_uint64(); }
+  bool has_debug_id() const { return at<2>().valid(); }
+  int32_t debug_id() const { return at<2>().as_int32(); }
+  bool has_offsets_size() const { return at<3>().valid(); }
+  uint64_t offsets_size() const { return at<3>().as_uint64(); }
+  bool has_extra_buffers_size() const { return at<4>().valid(); }
+  uint64_t extra_buffers_size() const { return at<4>().as_uint64(); }
+};
+
+class BinderTransactionAllocBufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderTransactionAllocBufFtraceEvent_Decoder;
+  enum : int32_t {
+    kDataSizeFieldNumber = 1,
+    kDebugIdFieldNumber = 2,
+    kOffsetsSizeFieldNumber = 3,
+    kExtraBuffersSizeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderTransactionAllocBufFtraceEvent"; }
+
+
+  using FieldMetadata_DataSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BinderTransactionAllocBufFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize kDataSize{};
+  void set_data_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DebugId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionAllocBufFtraceEvent>;
+
+  static constexpr FieldMetadata_DebugId kDebugId{};
+  void set_debug_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DebugId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OffsetsSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BinderTransactionAllocBufFtraceEvent>;
+
+  static constexpr FieldMetadata_OffsetsSize kOffsetsSize{};
+  void set_offsets_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OffsetsSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExtraBuffersSize =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BinderTransactionAllocBufFtraceEvent>;
+
+  static constexpr FieldMetadata_ExtraBuffersSize kExtraBuffersSize{};
+  void set_extra_buffers_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExtraBuffersSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BinderUnlockFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderUnlockFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderUnlockFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderUnlockFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tag() const { return at<1>().valid(); }
+  ::protozero::ConstChars tag() const { return at<1>().as_string(); }
+};
+
+class BinderUnlockFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderUnlockFtraceEvent_Decoder;
+  enum : int32_t {
+    kTagFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderUnlockFtraceEvent"; }
+
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BinderUnlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BinderLockedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderLockedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderLockedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderLockedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tag() const { return at<1>().valid(); }
+  ::protozero::ConstChars tag() const { return at<1>().as_string(); }
+};
+
+class BinderLockedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderLockedFtraceEvent_Decoder;
+  enum : int32_t {
+    kTagFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderLockedFtraceEvent"; }
+
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BinderLockedFtraceEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BinderLockFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderLockFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderLockFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderLockFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tag() const { return at<1>().valid(); }
+  ::protozero::ConstChars tag() const { return at<1>().as_string(); }
+};
+
+class BinderLockFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderLockFtraceEvent_Decoder;
+  enum : int32_t {
+    kTagFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderLockFtraceEvent"; }
+
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BinderLockFtraceEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BinderSetPriorityFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderSetPriorityFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderSetPriorityFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderSetPriorityFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_proc() const { return at<1>().valid(); }
+  int32_t proc() const { return at<1>().as_int32(); }
+  bool has_thread() const { return at<2>().valid(); }
+  int32_t thread() const { return at<2>().as_int32(); }
+  bool has_old_prio() const { return at<3>().valid(); }
+  uint32_t old_prio() const { return at<3>().as_uint32(); }
+  bool has_new_prio() const { return at<4>().valid(); }
+  uint32_t new_prio() const { return at<4>().as_uint32(); }
+  bool has_desired_prio() const { return at<5>().valid(); }
+  uint32_t desired_prio() const { return at<5>().as_uint32(); }
+};
+
+class BinderSetPriorityFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderSetPriorityFtraceEvent_Decoder;
+  enum : int32_t {
+    kProcFieldNumber = 1,
+    kThreadFieldNumber = 2,
+    kOldPrioFieldNumber = 3,
+    kNewPrioFieldNumber = 4,
+    kDesiredPrioFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderSetPriorityFtraceEvent"; }
+
+
+  using FieldMetadata_Proc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  static constexpr FieldMetadata_Proc kProc{};
+  void set_proc(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Proc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Thread =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  static constexpr FieldMetadata_Thread kThread{};
+  void set_thread(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Thread::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  static constexpr FieldMetadata_OldPrio kOldPrio{};
+  void set_old_prio(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldPrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NewPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  static constexpr FieldMetadata_NewPrio kNewPrio{};
+  void set_new_prio(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewPrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DesiredPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderSetPriorityFtraceEvent>;
+
+  static constexpr FieldMetadata_DesiredPrio kDesiredPrio{};
+  void set_desired_prio(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DesiredPrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BinderTransactionReceivedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderTransactionReceivedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderTransactionReceivedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderTransactionReceivedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_debug_id() const { return at<1>().valid(); }
+  int32_t debug_id() const { return at<1>().as_int32(); }
+};
+
+class BinderTransactionReceivedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderTransactionReceivedFtraceEvent_Decoder;
+  enum : int32_t {
+    kDebugIdFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderTransactionReceivedFtraceEvent"; }
+
+
+  using FieldMetadata_DebugId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionReceivedFtraceEvent>;
+
+  static constexpr FieldMetadata_DebugId kDebugId{};
+  void set_debug_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DebugId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BinderTransactionFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BinderTransactionFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BinderTransactionFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BinderTransactionFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_debug_id() const { return at<1>().valid(); }
+  int32_t debug_id() const { return at<1>().as_int32(); }
+  bool has_target_node() const { return at<2>().valid(); }
+  int32_t target_node() const { return at<2>().as_int32(); }
+  bool has_to_proc() const { return at<3>().valid(); }
+  int32_t to_proc() const { return at<3>().as_int32(); }
+  bool has_to_thread() const { return at<4>().valid(); }
+  int32_t to_thread() const { return at<4>().as_int32(); }
+  bool has_reply() const { return at<5>().valid(); }
+  int32_t reply() const { return at<5>().as_int32(); }
+  bool has_code() const { return at<6>().valid(); }
+  uint32_t code() const { return at<6>().as_uint32(); }
+  bool has_flags() const { return at<7>().valid(); }
+  uint32_t flags() const { return at<7>().as_uint32(); }
+};
+
+class BinderTransactionFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BinderTransactionFtraceEvent_Decoder;
+  enum : int32_t {
+    kDebugIdFieldNumber = 1,
+    kTargetNodeFieldNumber = 2,
+    kToProcFieldNumber = 3,
+    kToThreadFieldNumber = 4,
+    kReplyFieldNumber = 5,
+    kCodeFieldNumber = 6,
+    kFlagsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BinderTransactionFtraceEvent"; }
+
+
+  using FieldMetadata_DebugId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_DebugId kDebugId{};
+  void set_debug_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DebugId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetNode =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_TargetNode kTargetNode{};
+  void set_target_node(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetNode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ToProc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_ToProc kToProc{};
+  void set_to_proc(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ToProc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ToThread =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_ToThread kToThread{};
+  void set_to_thread(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ToThread::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Reply =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Reply kReply{};
+  void set_reply(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reply::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Code =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Code kCode{};
+  void set_code(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Code::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BinderTransactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/block.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_BLOCK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_BLOCK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class BlockUnplugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockUnplugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockUnplugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockUnplugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nr_rq() const { return at<1>().valid(); }
+  int32_t nr_rq() const { return at<1>().as_int32(); }
+  bool has_comm() const { return at<2>().valid(); }
+  ::protozero::ConstChars comm() const { return at<2>().as_string(); }
+};
+
+class BlockUnplugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockUnplugFtraceEvent_Decoder;
+  enum : int32_t {
+    kNrRqFieldNumber = 1,
+    kCommFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockUnplugFtraceEvent"; }
+
+
+  using FieldMetadata_NrRq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockUnplugFtraceEvent>;
+
+  static constexpr FieldMetadata_NrRq kNrRq{};
+  void set_nr_rq(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrRq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockUnplugFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockTouchBufferFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockTouchBufferFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockTouchBufferFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockTouchBufferFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+};
+
+class BlockTouchBufferFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockTouchBufferFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockTouchBufferFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockTouchBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockTouchBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockTouchBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockSplitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockSplitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockSplitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockSplitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_new_sector() const { return at<3>().valid(); }
+  uint64_t new_sector() const { return at<3>().as_uint64(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockSplitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockSplitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNewSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockSplitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSplitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSplitFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NewSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSplitFtraceEvent>;
+
+  static constexpr FieldMetadata_NewSector kNewSector{};
+  void set_new_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockSplitFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockSplitFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockSleeprqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockSleeprqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockSleeprqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockSleeprqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockSleeprqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockSleeprqFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockSleeprqFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSleeprqFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockSleeprqFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockSleeprqFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockSleeprqFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockSleeprqFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockRqRequeueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqRequeueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqRequeueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqRequeueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_errors() const { return at<4>().valid(); }
+  int32_t errors() const { return at<4>().as_int32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+  bool has_cmd() const { return at<6>().valid(); }
+  ::protozero::ConstChars cmd() const { return at<6>().as_string(); }
+};
+
+class BlockRqRequeueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqRequeueFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+    kCmdFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqRequeueFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Errors =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_Errors kErrors{};
+  void set_errors(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Errors::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqRequeueFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, size);
+  }
+  void set_cmd(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, chars.data, chars.size);
+  }
+  void set_cmd(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockRqRemapFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqRemapFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqRemapFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqRemapFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_old_dev() const { return at<4>().valid(); }
+  uint64_t old_dev() const { return at<4>().as_uint64(); }
+  bool has_old_sector() const { return at<5>().valid(); }
+  uint64_t old_sector() const { return at<5>().as_uint64(); }
+  bool has_nr_bios() const { return at<6>().valid(); }
+  uint32_t nr_bios() const { return at<6>().as_uint32(); }
+  bool has_rwbs() const { return at<7>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<7>().as_string(); }
+};
+
+class BlockRqRemapFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqRemapFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kOldDevFieldNumber = 4,
+    kOldSectorFieldNumber = 5,
+    kNrBiosFieldNumber = 6,
+    kRwbsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqRemapFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldDev =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_OldDev kOldDev{};
+  void set_old_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldDev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldSector =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_OldSector kOldSector{};
+  void set_old_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrBios =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_NrBios kNrBios{};
+  void set_nr_bios(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrBios::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockRqInsertFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqInsertFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqInsertFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqInsertFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_bytes() const { return at<4>().valid(); }
+  uint32_t bytes() const { return at<4>().as_uint32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+  bool has_comm() const { return at<6>().valid(); }
+  ::protozero::ConstChars comm() const { return at<6>().as_string(); }
+  bool has_cmd() const { return at<7>().valid(); }
+  ::protozero::ConstChars cmd() const { return at<7>().as_string(); }
+};
+
+class BlockRqInsertFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqInsertFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kBytesFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+    kCommFieldNumber = 6,
+    kCmdFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqInsertFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqInsertFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, size);
+  }
+  void set_cmd(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, chars.data, chars.size);
+  }
+  void set_cmd(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockRqCompleteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqCompleteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqCompleteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqCompleteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_errors() const { return at<4>().valid(); }
+  int32_t errors() const { return at<4>().as_int32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+  bool has_cmd() const { return at<6>().valid(); }
+  ::protozero::ConstChars cmd() const { return at<6>().as_string(); }
+  bool has_error() const { return at<7>().valid(); }
+  int32_t error() const { return at<7>().as_int32(); }
+};
+
+class BlockRqCompleteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqCompleteFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+    kCmdFieldNumber = 6,
+    kErrorFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqCompleteFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Errors =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Errors kErrors{};
+  void set_errors(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Errors::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, size);
+  }
+  void set_cmd(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, chars.data, chars.size);
+  }
+  void set_cmd(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockRqCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockRqAbortFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqAbortFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqAbortFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqAbortFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_errors() const { return at<4>().valid(); }
+  int32_t errors() const { return at<4>().as_int32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+  bool has_cmd() const { return at<6>().valid(); }
+  ::protozero::ConstChars cmd() const { return at<6>().as_string(); }
+};
+
+class BlockRqAbortFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqAbortFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kErrorsFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+    kCmdFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqAbortFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Errors =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Errors kErrors{};
+  void set_errors(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Errors::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, size);
+  }
+  void set_cmd(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, chars.data, chars.size);
+  }
+  void set_cmd(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockPlugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockPlugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockPlugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockPlugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+};
+
+class BlockPlugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockPlugFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockPlugFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockPlugFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockGetrqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockGetrqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockGetrqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockGetrqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockGetrqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockGetrqFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockGetrqFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockGetrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockGetrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockGetrqFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockGetrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockGetrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockDirtyBufferFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockDirtyBufferFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockDirtyBufferFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockDirtyBufferFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+};
+
+class BlockDirtyBufferFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockDirtyBufferFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockDirtyBufferFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockDirtyBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockDirtyBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockDirtyBufferFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockBioRemapFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioRemapFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioRemapFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioRemapFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_old_dev() const { return at<4>().valid(); }
+  uint64_t old_dev() const { return at<4>().as_uint64(); }
+  bool has_old_sector() const { return at<5>().valid(); }
+  uint64_t old_sector() const { return at<5>().as_uint64(); }
+  bool has_rwbs() const { return at<6>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<6>().as_string(); }
+};
+
+class BlockBioRemapFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioRemapFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kOldDevFieldNumber = 4,
+    kOldSectorFieldNumber = 5,
+    kRwbsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioRemapFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldDev =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_OldDev kOldDev{};
+  void set_old_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldDev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldSector =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_OldSector kOldSector{};
+  void set_old_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioRemapFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockBioQueueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioQueueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioQueueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioQueueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockBioQueueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioQueueFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioQueueFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockBioFrontmergeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioFrontmergeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioFrontmergeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioFrontmergeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockBioFrontmergeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioFrontmergeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioFrontmergeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioFrontmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioFrontmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioFrontmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioFrontmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioFrontmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockBioCompleteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioCompleteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioCompleteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioCompleteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_error() const { return at<4>().valid(); }
+  int32_t error() const { return at<4>().as_int32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+};
+
+class BlockBioCompleteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioCompleteFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kErrorFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioCompleteFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      BlockBioCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockBioBounceFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioBounceFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioBounceFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioBounceFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockBioBounceFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioBounceFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioBounceFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioBounceFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioBounceFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioBounceFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioBounceFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioBounceFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockBioBackmergeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockBioBackmergeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockBioBackmergeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockBioBackmergeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_rwbs() const { return at<4>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<4>().as_string(); }
+  bool has_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars comm() const { return at<5>().as_string(); }
+};
+
+class BlockBioBackmergeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockBioBackmergeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kRwbsFieldNumber = 4,
+    kCommFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockBioBackmergeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioBackmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockBioBackmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockBioBackmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioBackmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockBioBackmergeFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BlockRqIssueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BlockRqIssueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BlockRqIssueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BlockRqIssueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_sector() const { return at<2>().valid(); }
+  uint64_t sector() const { return at<2>().as_uint64(); }
+  bool has_nr_sector() const { return at<3>().valid(); }
+  uint32_t nr_sector() const { return at<3>().as_uint32(); }
+  bool has_bytes() const { return at<4>().valid(); }
+  uint32_t bytes() const { return at<4>().as_uint32(); }
+  bool has_rwbs() const { return at<5>().valid(); }
+  ::protozero::ConstChars rwbs() const { return at<5>().as_string(); }
+  bool has_comm() const { return at<6>().valid(); }
+  ::protozero::ConstChars comm() const { return at<6>().as_string(); }
+  bool has_cmd() const { return at<7>().valid(); }
+  ::protozero::ConstChars cmd() const { return at<7>().as_string(); }
+};
+
+class BlockRqIssueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = BlockRqIssueFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kSectorFieldNumber = 2,
+    kNrSectorFieldNumber = 3,
+    kBytesFieldNumber = 4,
+    kRwbsFieldNumber = 5,
+    kCommFieldNumber = 6,
+    kCmdFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BlockRqIssueFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSector =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSector kNrSector{};
+  void set_nr_sector(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Bytes =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytes kBytes{};
+  void set_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rwbs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Rwbs kRwbs{};
+  void set_rwbs(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, data, size);
+  }
+  void set_rwbs(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Rwbs::kFieldId, chars.data, chars.size);
+  }
+  void set_rwbs(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rwbs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BlockRqIssueFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, data, size);
+  }
+  void set_cmd(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmd::kFieldId, chars.data, chars.size);
+  }
+  void set_cmd(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/cgroup.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CGROUP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CGROUP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class CgroupSetupRootFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupSetupRootFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupSetupRootFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupSetupRootFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_ss_mask() const { return at<2>().valid(); }
+  uint32_t ss_mask() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+};
+
+class CgroupSetupRootFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupSetupRootFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kSsMaskFieldNumber = 2,
+    kNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupSetupRootFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupSetupRootFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SsMask =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CgroupSetupRootFtraceEvent>;
+
+  static constexpr FieldMetadata_SsMask kSsMask{};
+  void set_ss_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SsMask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupSetupRootFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CgroupRenameFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupRenameFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupRenameFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupRenameFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_id() const { return at<2>().valid(); }
+  int32_t id() const { return at<2>().as_int32(); }
+  bool has_cname() const { return at<3>().valid(); }
+  ::protozero::ConstChars cname() const { return at<3>().as_string(); }
+  bool has_level() const { return at<4>().valid(); }
+  int32_t level() const { return at<4>().as_int32(); }
+  bool has_path() const { return at<5>().valid(); }
+  ::protozero::ConstChars path() const { return at<5>().as_string(); }
+};
+
+class CgroupRenameFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupRenameFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+    kLevelFieldNumber = 4,
+    kPathFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupRenameFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CgroupReleaseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupReleaseFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupReleaseFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupReleaseFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_id() const { return at<2>().valid(); }
+  int32_t id() const { return at<2>().as_int32(); }
+  bool has_cname() const { return at<3>().valid(); }
+  ::protozero::ConstChars cname() const { return at<3>().as_string(); }
+  bool has_level() const { return at<4>().valid(); }
+  int32_t level() const { return at<4>().as_int32(); }
+  bool has_path() const { return at<5>().valid(); }
+  ::protozero::ConstChars path() const { return at<5>().as_string(); }
+};
+
+class CgroupReleaseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupReleaseFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+    kLevelFieldNumber = 4,
+    kPathFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupReleaseFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupReleaseFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupReleaseFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupReleaseFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupReleaseFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupReleaseFtraceEvent>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CgroupDestroyRootFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupDestroyRootFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupDestroyRootFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupDestroyRootFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_ss_mask() const { return at<2>().valid(); }
+  uint32_t ss_mask() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+};
+
+class CgroupDestroyRootFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupDestroyRootFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kSsMaskFieldNumber = 2,
+    kNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupDestroyRootFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupDestroyRootFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SsMask =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CgroupDestroyRootFtraceEvent>;
+
+  static constexpr FieldMetadata_SsMask kSsMask{};
+  void set_ss_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SsMask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupDestroyRootFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CgroupTransferTasksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupTransferTasksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupTransferTasksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupTransferTasksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dst_root() const { return at<1>().valid(); }
+  int32_t dst_root() const { return at<1>().as_int32(); }
+  bool has_dst_id() const { return at<2>().valid(); }
+  int32_t dst_id() const { return at<2>().as_int32(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+  bool has_comm() const { return at<4>().valid(); }
+  ::protozero::ConstChars comm() const { return at<4>().as_string(); }
+  bool has_cname() const { return at<5>().valid(); }
+  ::protozero::ConstChars cname() const { return at<5>().as_string(); }
+  bool has_dst_level() const { return at<6>().valid(); }
+  int32_t dst_level() const { return at<6>().as_int32(); }
+  bool has_dst_path() const { return at<7>().valid(); }
+  ::protozero::ConstChars dst_path() const { return at<7>().as_string(); }
+};
+
+class CgroupTransferTasksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupTransferTasksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDstRootFieldNumber = 1,
+    kDstIdFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kCommFieldNumber = 4,
+    kCnameFieldNumber = 5,
+    kDstLevelFieldNumber = 6,
+    kDstPathFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupTransferTasksFtraceEvent"; }
+
+
+  using FieldMetadata_DstRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_DstRoot kDstRoot{};
+  void set_dst_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstRoot::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_DstId kDstId{};
+  void set_dst_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstLevel =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_DstLevel kDstLevel{};
+  void set_dst_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstLevel::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstPath =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupTransferTasksFtraceEvent>;
+
+  static constexpr FieldMetadata_DstPath kDstPath{};
+  void set_dst_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DstPath::kFieldId, data, size);
+  }
+  void set_dst_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DstPath::kFieldId, chars.data, chars.size);
+  }
+  void set_dst_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstPath::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CgroupRmdirFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupRmdirFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupRmdirFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupRmdirFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_id() const { return at<2>().valid(); }
+  int32_t id() const { return at<2>().as_int32(); }
+  bool has_cname() const { return at<3>().valid(); }
+  ::protozero::ConstChars cname() const { return at<3>().as_string(); }
+  bool has_level() const { return at<4>().valid(); }
+  int32_t level() const { return at<4>().as_int32(); }
+  bool has_path() const { return at<5>().valid(); }
+  ::protozero::ConstChars path() const { return at<5>().as_string(); }
+};
+
+class CgroupRmdirFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupRmdirFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+    kLevelFieldNumber = 4,
+    kPathFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupRmdirFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRmdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRmdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupRmdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRmdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupRmdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CgroupRemountFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupRemountFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupRemountFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupRemountFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_ss_mask() const { return at<2>().valid(); }
+  uint32_t ss_mask() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+};
+
+class CgroupRemountFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupRemountFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kSsMaskFieldNumber = 2,
+    kNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupRemountFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupRemountFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SsMask =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CgroupRemountFtraceEvent>;
+
+  static constexpr FieldMetadata_SsMask kSsMask{};
+  void set_ss_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SsMask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupRemountFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CgroupMkdirFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupMkdirFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupMkdirFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupMkdirFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_root() const { return at<1>().valid(); }
+  int32_t root() const { return at<1>().as_int32(); }
+  bool has_id() const { return at<2>().valid(); }
+  int32_t id() const { return at<2>().as_int32(); }
+  bool has_cname() const { return at<3>().valid(); }
+  ::protozero::ConstChars cname() const { return at<3>().as_string(); }
+  bool has_level() const { return at<4>().valid(); }
+  int32_t level() const { return at<4>().as_int32(); }
+  bool has_path() const { return at<5>().valid(); }
+  ::protozero::ConstChars path() const { return at<5>().as_string(); }
+};
+
+class CgroupMkdirFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupMkdirFtraceEvent_Decoder;
+  enum : int32_t {
+    kRootFieldNumber = 1,
+    kIdFieldNumber = 2,
+    kCnameFieldNumber = 3,
+    kLevelFieldNumber = 4,
+    kPathFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupMkdirFtraceEvent"; }
+
+
+  using FieldMetadata_Root =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupMkdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Root kRoot{};
+  void set_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Root::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupMkdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupMkdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupMkdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupMkdirFtraceEvent>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CgroupAttachTaskFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CgroupAttachTaskFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CgroupAttachTaskFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CgroupAttachTaskFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dst_root() const { return at<1>().valid(); }
+  int32_t dst_root() const { return at<1>().as_int32(); }
+  bool has_dst_id() const { return at<2>().valid(); }
+  int32_t dst_id() const { return at<2>().as_int32(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+  bool has_comm() const { return at<4>().valid(); }
+  ::protozero::ConstChars comm() const { return at<4>().as_string(); }
+  bool has_cname() const { return at<5>().valid(); }
+  ::protozero::ConstChars cname() const { return at<5>().as_string(); }
+  bool has_dst_level() const { return at<6>().valid(); }
+  int32_t dst_level() const { return at<6>().as_int32(); }
+  bool has_dst_path() const { return at<7>().valid(); }
+  ::protozero::ConstChars dst_path() const { return at<7>().as_string(); }
+};
+
+class CgroupAttachTaskFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CgroupAttachTaskFtraceEvent_Decoder;
+  enum : int32_t {
+    kDstRootFieldNumber = 1,
+    kDstIdFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kCommFieldNumber = 4,
+    kCnameFieldNumber = 5,
+    kDstLevelFieldNumber = 6,
+    kDstPathFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CgroupAttachTaskFtraceEvent"; }
+
+
+  using FieldMetadata_DstRoot =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_DstRoot kDstRoot{};
+  void set_dst_root(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstRoot::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_DstId kDstId{};
+  void set_dst_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cname =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Cname kCname{};
+  void set_cname(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, data, size);
+  }
+  void set_cname(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cname::kFieldId, chars.data, chars.size);
+  }
+  void set_cname(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cname::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstLevel =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_DstLevel kDstLevel{};
+  void set_dst_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstLevel::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstPath =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CgroupAttachTaskFtraceEvent>;
+
+  static constexpr FieldMetadata_DstPath kDstPath{};
+  void set_dst_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DstPath::kFieldId, data, size);
+  }
+  void set_dst_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DstPath::kFieldId, chars.data, chars.size);
+  }
+  void set_dst_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstPath::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/clk.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CLK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CLK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ClkSetRateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClkSetRateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClkSetRateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClkSetRateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_rate() const { return at<2>().valid(); }
+  uint64_t rate() const { return at<2>().as_uint64(); }
+};
+
+class ClkSetRateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClkSetRateFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kRateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClkSetRateFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClkSetRateFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rate =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClkSetRateFtraceEvent>;
+
+  static constexpr FieldMetadata_Rate kRate{};
+  void set_rate(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ClkDisableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClkDisableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClkDisableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClkDisableFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+};
+
+class ClkDisableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClkDisableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClkDisableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClkDisableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ClkEnableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClkEnableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClkEnableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClkEnableFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+};
+
+class ClkEnableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClkEnableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClkEnableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClkEnableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/cma.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CMA_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CMA_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class CmaAllocInfoFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CmaAllocInfoFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CmaAllocInfoFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CmaAllocInfoFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint32_t align() const { return at<1>().as_uint32(); }
+  bool has_count() const { return at<2>().valid(); }
+  uint32_t count() const { return at<2>().as_uint32(); }
+  bool has_err_iso() const { return at<3>().valid(); }
+  uint32_t err_iso() const { return at<3>().as_uint32(); }
+  bool has_err_mig() const { return at<4>().valid(); }
+  uint32_t err_mig() const { return at<4>().as_uint32(); }
+  bool has_err_test() const { return at<5>().valid(); }
+  uint32_t err_test() const { return at<5>().as_uint32(); }
+  bool has_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars name() const { return at<6>().as_string(); }
+  bool has_nr_mapped() const { return at<7>().valid(); }
+  uint64_t nr_mapped() const { return at<7>().as_uint64(); }
+  bool has_nr_migrated() const { return at<8>().valid(); }
+  uint64_t nr_migrated() const { return at<8>().as_uint64(); }
+  bool has_nr_reclaimed() const { return at<9>().valid(); }
+  uint64_t nr_reclaimed() const { return at<9>().as_uint64(); }
+  bool has_pfn() const { return at<10>().valid(); }
+  uint64_t pfn() const { return at<10>().as_uint64(); }
+};
+
+class CmaAllocInfoFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CmaAllocInfoFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kCountFieldNumber = 2,
+    kErrIsoFieldNumber = 3,
+    kErrMigFieldNumber = 4,
+    kErrTestFieldNumber = 5,
+    kNameFieldNumber = 6,
+    kNrMappedFieldNumber = 7,
+    kNrMigratedFieldNumber = 8,
+    kNrReclaimedFieldNumber = 9,
+    kPfnFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CmaAllocInfoFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ErrIso =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_ErrIso kErrIso{};
+  void set_err_iso(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ErrIso::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ErrMig =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_ErrMig kErrMig{};
+  void set_err_mig(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ErrMig::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ErrTest =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_ErrTest kErrTest{};
+  void set_err_test(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ErrTest::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrMapped =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_NrMapped kNrMapped{};
+  void set_nr_mapped(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrMapped::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrMigrated =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_NrMigrated kNrMigrated{};
+  void set_nr_migrated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrMigrated::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrReclaimed =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_NrReclaimed kNrReclaimed{};
+  void set_nr_reclaimed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrReclaimed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CmaAllocInfoFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CmaAllocStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CmaAllocStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CmaAllocStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CmaAllocStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint32_t align() const { return at<1>().as_uint32(); }
+  bool has_count() const { return at<2>().valid(); }
+  uint32_t count() const { return at<2>().as_uint32(); }
+  bool has_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars name() const { return at<3>().as_string(); }
+};
+
+class CmaAllocStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CmaAllocStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kCountFieldNumber = 2,
+    kNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CmaAllocStartFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CmaAllocStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CmaAllocStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/compaction.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_COMPACTION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_COMPACTION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class MmCompactionWakeupKcompactdFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionWakeupKcompactdFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionWakeupKcompactdFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionWakeupKcompactdFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_order() const { return at<2>().valid(); }
+  int32_t order() const { return at<2>().as_int32(); }
+  bool has_classzone_idx() const { return at<3>().valid(); }
+  uint32_t classzone_idx() const { return at<3>().as_uint32(); }
+  bool has_highest_zoneidx() const { return at<4>().valid(); }
+  uint32_t highest_zoneidx() const { return at<4>().as_uint32(); }
+};
+
+class MmCompactionWakeupKcompactdFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionWakeupKcompactdFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kClasszoneIdxFieldNumber = 3,
+    kHighestZoneidxFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionWakeupKcompactdFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionWakeupKcompactdFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionWakeupKcompactdFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ClasszoneIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionWakeupKcompactdFtraceEvent>;
+
+  static constexpr FieldMetadata_ClasszoneIdx kClasszoneIdx{};
+  void set_classzone_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClasszoneIdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HighestZoneidx =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionWakeupKcompactdFtraceEvent>;
+
+  static constexpr FieldMetadata_HighestZoneidx kHighestZoneidx{};
+  void set_highest_zoneidx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HighestZoneidx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionTryToCompactPagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionTryToCompactPagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionTryToCompactPagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionTryToCompactPagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_order() const { return at<1>().valid(); }
+  int32_t order() const { return at<1>().as_int32(); }
+  bool has_gfp_mask() const { return at<2>().valid(); }
+  uint32_t gfp_mask() const { return at<2>().as_uint32(); }
+  bool has_mode() const { return at<3>().valid(); }
+  uint32_t mode() const { return at<3>().as_uint32(); }
+  bool has_prio() const { return at<4>().valid(); }
+  int32_t prio() const { return at<4>().as_int32(); }
+};
+
+class MmCompactionTryToCompactPagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionTryToCompactPagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kOrderFieldNumber = 1,
+    kGfpMaskFieldNumber = 2,
+    kModeFieldNumber = 3,
+    kPrioFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionTryToCompactPagesFtraceEvent"; }
+
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionTryToCompactPagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GfpMask =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionTryToCompactPagesFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpMask kGfpMask{};
+  void set_gfp_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpMask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionTryToCompactPagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionTryToCompactPagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionSuitableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionSuitableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionSuitableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionSuitableFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  uint32_t idx() const { return at<2>().as_uint32(); }
+  bool has_order() const { return at<3>().valid(); }
+  int32_t order() const { return at<3>().as_int32(); }
+  bool has_ret() const { return at<4>().valid(); }
+  int32_t ret() const { return at<4>().as_int32(); }
+};
+
+class MmCompactionSuitableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionSuitableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kRetFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionSuitableFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionSuitableFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionSuitableFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionSuitableFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionSuitableFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionMigratepagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionMigratepagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionMigratepagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionMigratepagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nr_migrated() const { return at<1>().valid(); }
+  uint64_t nr_migrated() const { return at<1>().as_uint64(); }
+  bool has_nr_failed() const { return at<2>().valid(); }
+  uint64_t nr_failed() const { return at<2>().as_uint64(); }
+};
+
+class MmCompactionMigratepagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionMigratepagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kNrMigratedFieldNumber = 1,
+    kNrFailedFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionMigratepagesFtraceEvent"; }
+
+
+  using FieldMetadata_NrMigrated =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrMigrated kNrMigrated{};
+  void set_nr_migrated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrMigrated::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrFailed kNrFailed{};
+  void set_nr_failed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrFailed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionKcompactdWakeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionKcompactdWakeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionKcompactdWakeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionKcompactdWakeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_order() const { return at<2>().valid(); }
+  int32_t order() const { return at<2>().as_int32(); }
+  bool has_classzone_idx() const { return at<3>().valid(); }
+  uint32_t classzone_idx() const { return at<3>().as_uint32(); }
+  bool has_highest_zoneidx() const { return at<4>().valid(); }
+  uint32_t highest_zoneidx() const { return at<4>().as_uint32(); }
+};
+
+class MmCompactionKcompactdWakeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionKcompactdWakeFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kClasszoneIdxFieldNumber = 3,
+    kHighestZoneidxFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionKcompactdWakeFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionKcompactdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionKcompactdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ClasszoneIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionKcompactdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_ClasszoneIdx kClasszoneIdx{};
+  void set_classzone_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClasszoneIdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HighestZoneidx =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionKcompactdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_HighestZoneidx kHighestZoneidx{};
+  void set_highest_zoneidx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HighestZoneidx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionKcompactdSleepFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionKcompactdSleepFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionKcompactdSleepFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionKcompactdSleepFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+};
+
+class MmCompactionKcompactdSleepFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionKcompactdSleepFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionKcompactdSleepFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionKcompactdSleepFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionIsolateMigratepagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionIsolateMigratepagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionIsolateMigratepagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionIsolateMigratepagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_start_pfn() const { return at<1>().valid(); }
+  uint64_t start_pfn() const { return at<1>().as_uint64(); }
+  bool has_end_pfn() const { return at<2>().valid(); }
+  uint64_t end_pfn() const { return at<2>().as_uint64(); }
+  bool has_nr_scanned() const { return at<3>().valid(); }
+  uint64_t nr_scanned() const { return at<3>().as_uint64(); }
+  bool has_nr_taken() const { return at<4>().valid(); }
+  uint64_t nr_taken() const { return at<4>().as_uint64(); }
+};
+
+class MmCompactionIsolateMigratepagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionIsolateMigratepagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kStartPfnFieldNumber = 1,
+    kEndPfnFieldNumber = 2,
+    kNrScannedFieldNumber = 3,
+    kNrTakenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionIsolateMigratepagesFtraceEvent"; }
+
+
+  using FieldMetadata_StartPfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_StartPfn kStartPfn{};
+  void set_start_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartPfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EndPfn =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_EndPfn kEndPfn{};
+  void set_end_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EndPfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrScanned =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrScanned kNrScanned{};
+  void set_nr_scanned(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrScanned::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrTaken =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateMigratepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrTaken kNrTaken{};
+  void set_nr_taken(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrTaken::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionIsolateFreepagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionIsolateFreepagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionIsolateFreepagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionIsolateFreepagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_start_pfn() const { return at<1>().valid(); }
+  uint64_t start_pfn() const { return at<1>().as_uint64(); }
+  bool has_end_pfn() const { return at<2>().valid(); }
+  uint64_t end_pfn() const { return at<2>().as_uint64(); }
+  bool has_nr_scanned() const { return at<3>().valid(); }
+  uint64_t nr_scanned() const { return at<3>().as_uint64(); }
+  bool has_nr_taken() const { return at<4>().valid(); }
+  uint64_t nr_taken() const { return at<4>().as_uint64(); }
+};
+
+class MmCompactionIsolateFreepagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionIsolateFreepagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kStartPfnFieldNumber = 1,
+    kEndPfnFieldNumber = 2,
+    kNrScannedFieldNumber = 3,
+    kNrTakenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionIsolateFreepagesFtraceEvent"; }
+
+
+  using FieldMetadata_StartPfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateFreepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_StartPfn kStartPfn{};
+  void set_start_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartPfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EndPfn =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateFreepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_EndPfn kEndPfn{};
+  void set_end_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EndPfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrScanned =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateFreepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrScanned kNrScanned{};
+  void set_nr_scanned(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrScanned::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrTaken =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionIsolateFreepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrTaken kNrTaken{};
+  void set_nr_taken(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrTaken::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionFinishedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionFinishedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionFinishedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionFinishedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  uint32_t idx() const { return at<2>().as_uint32(); }
+  bool has_order() const { return at<3>().valid(); }
+  int32_t order() const { return at<3>().as_int32(); }
+  bool has_ret() const { return at<4>().valid(); }
+  int32_t ret() const { return at<4>().as_int32(); }
+};
+
+class MmCompactionFinishedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionFinishedFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kRetFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionFinishedFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionFinishedFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionFinishedFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionFinishedFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionFinishedFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_zone_start() const { return at<1>().valid(); }
+  uint64_t zone_start() const { return at<1>().as_uint64(); }
+  bool has_migrate_pfn() const { return at<2>().valid(); }
+  uint64_t migrate_pfn() const { return at<2>().as_uint64(); }
+  bool has_free_pfn() const { return at<3>().valid(); }
+  uint64_t free_pfn() const { return at<3>().as_uint64(); }
+  bool has_zone_end() const { return at<4>().valid(); }
+  uint64_t zone_end() const { return at<4>().as_uint64(); }
+  bool has_sync() const { return at<5>().valid(); }
+  uint32_t sync() const { return at<5>().as_uint32(); }
+  bool has_status() const { return at<6>().valid(); }
+  int32_t status() const { return at<6>().as_int32(); }
+};
+
+class MmCompactionEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kZoneStartFieldNumber = 1,
+    kMigratePfnFieldNumber = 2,
+    kFreePfnFieldNumber = 3,
+    kZoneEndFieldNumber = 4,
+    kSyncFieldNumber = 5,
+    kStatusFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionEndFtraceEvent"; }
+
+
+  using FieldMetadata_ZoneStart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_ZoneStart kZoneStart{};
+  void set_zone_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ZoneStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MigratePfn =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_MigratePfn kMigratePfn{};
+  void set_migrate_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MigratePfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FreePfn =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_FreePfn kFreePfn{};
+  void set_free_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreePfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ZoneEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_ZoneEnd kZoneEnd{};
+  void set_zone_end(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ZoneEnd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sync =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Sync kSync{};
+  void set_sync(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sync::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionDeferResetFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionDeferResetFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionDeferResetFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionDeferResetFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  uint32_t idx() const { return at<2>().as_uint32(); }
+  bool has_order() const { return at<3>().valid(); }
+  int32_t order() const { return at<3>().as_int32(); }
+  bool has_considered() const { return at<4>().valid(); }
+  uint32_t considered() const { return at<4>().as_uint32(); }
+  bool has_defer_shift() const { return at<5>().valid(); }
+  uint32_t defer_shift() const { return at<5>().as_uint32(); }
+  bool has_order_failed() const { return at<6>().valid(); }
+  int32_t order_failed() const { return at<6>().as_int32(); }
+};
+
+class MmCompactionDeferResetFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionDeferResetFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kConsideredFieldNumber = 4,
+    kDeferShiftFieldNumber = 5,
+    kOrderFailedFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionDeferResetFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Considered =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_Considered kConsidered{};
+  void set_considered(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Considered::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeferShift =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_DeferShift kDeferShift{};
+  void set_defer_shift(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeferShift::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrderFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferResetFtraceEvent>;
+
+  static constexpr FieldMetadata_OrderFailed kOrderFailed{};
+  void set_order_failed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrderFailed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionDeferredFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionDeferredFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionDeferredFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionDeferredFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  uint32_t idx() const { return at<2>().as_uint32(); }
+  bool has_order() const { return at<3>().valid(); }
+  int32_t order() const { return at<3>().as_int32(); }
+  bool has_considered() const { return at<4>().valid(); }
+  uint32_t considered() const { return at<4>().as_uint32(); }
+  bool has_defer_shift() const { return at<5>().valid(); }
+  uint32_t defer_shift() const { return at<5>().as_uint32(); }
+  bool has_order_failed() const { return at<6>().valid(); }
+  int32_t order_failed() const { return at<6>().as_int32(); }
+};
+
+class MmCompactionDeferredFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionDeferredFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kConsideredFieldNumber = 4,
+    kDeferShiftFieldNumber = 5,
+    kOrderFailedFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionDeferredFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Considered =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_Considered kConsidered{};
+  void set_considered(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Considered::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeferShift =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_DeferShift kDeferShift{};
+  void set_defer_shift(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeferShift::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrderFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferredFtraceEvent>;
+
+  static constexpr FieldMetadata_OrderFailed kOrderFailed{};
+  void set_order_failed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrderFailed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionDeferCompactionFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionDeferCompactionFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionDeferCompactionFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionDeferCompactionFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  uint32_t idx() const { return at<2>().as_uint32(); }
+  bool has_order() const { return at<3>().valid(); }
+  int32_t order() const { return at<3>().as_int32(); }
+  bool has_considered() const { return at<4>().valid(); }
+  uint32_t considered() const { return at<4>().as_uint32(); }
+  bool has_defer_shift() const { return at<5>().valid(); }
+  uint32_t defer_shift() const { return at<5>().as_uint32(); }
+  bool has_order_failed() const { return at<6>().valid(); }
+  int32_t order_failed() const { return at<6>().as_int32(); }
+};
+
+class MmCompactionDeferCompactionFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionDeferCompactionFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kConsideredFieldNumber = 4,
+    kDeferShiftFieldNumber = 5,
+    kOrderFailedFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionDeferCompactionFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Considered =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_Considered kConsidered{};
+  void set_considered(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Considered::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeferShift =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_DeferShift kDeferShift{};
+  void set_defer_shift(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeferShift::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrderFailed =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmCompactionDeferCompactionFtraceEvent>;
+
+  static constexpr FieldMetadata_OrderFailed kOrderFailed{};
+  void set_order_failed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrderFailed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmCompactionBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmCompactionBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmCompactionBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmCompactionBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_zone_start() const { return at<1>().valid(); }
+  uint64_t zone_start() const { return at<1>().as_uint64(); }
+  bool has_migrate_pfn() const { return at<2>().valid(); }
+  uint64_t migrate_pfn() const { return at<2>().as_uint64(); }
+  bool has_free_pfn() const { return at<3>().valid(); }
+  uint64_t free_pfn() const { return at<3>().as_uint64(); }
+  bool has_zone_end() const { return at<4>().valid(); }
+  uint64_t zone_end() const { return at<4>().as_uint64(); }
+  bool has_sync() const { return at<5>().valid(); }
+  uint32_t sync() const { return at<5>().as_uint32(); }
+};
+
+class MmCompactionBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmCompactionBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kZoneStartFieldNumber = 1,
+    kMigratePfnFieldNumber = 2,
+    kFreePfnFieldNumber = 3,
+    kZoneEndFieldNumber = 4,
+    kSyncFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmCompactionBeginFtraceEvent"; }
+
+
+  using FieldMetadata_ZoneStart =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_ZoneStart kZoneStart{};
+  void set_zone_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ZoneStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MigratePfn =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_MigratePfn kMigratePfn{};
+  void set_migrate_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MigratePfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FreePfn =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_FreePfn kFreePfn{};
+  void set_free_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreePfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ZoneEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmCompactionBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_ZoneEnd kZoneEnd{};
+  void set_zone_end(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ZoneEnd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sync =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmCompactionBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Sync kSync{};
+  void set_sync(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sync::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/cpuhp.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CPUHP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CPUHP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class CpuhpPauseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuhpPauseFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuhpPauseFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuhpPauseFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_active_cpus() const { return at<1>().valid(); }
+  uint32_t active_cpus() const { return at<1>().as_uint32(); }
+  bool has_cpus() const { return at<2>().valid(); }
+  uint32_t cpus() const { return at<2>().as_uint32(); }
+  bool has_pause() const { return at<3>().valid(); }
+  uint32_t pause() const { return at<3>().as_uint32(); }
+  bool has_time() const { return at<4>().valid(); }
+  uint32_t time() const { return at<4>().as_uint32(); }
+};
+
+class CpuhpPauseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuhpPauseFtraceEvent_Decoder;
+  enum : int32_t {
+    kActiveCpusFieldNumber = 1,
+    kCpusFieldNumber = 2,
+    kPauseFieldNumber = 3,
+    kTimeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuhpPauseFtraceEvent"; }
+
+
+  using FieldMetadata_ActiveCpus =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpPauseFtraceEvent>;
+
+  static constexpr FieldMetadata_ActiveCpus kActiveCpus{};
+  void set_active_cpus(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActiveCpus::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cpus =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpPauseFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpus kCpus{};
+  void set_cpus(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpus::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pause =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpPauseFtraceEvent>;
+
+  static constexpr FieldMetadata_Pause kPause{};
+  void set_pause(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pause::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Time =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpPauseFtraceEvent>;
+
+  static constexpr FieldMetadata_Time kTime{};
+  void set_time(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Time::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CpuhpLatencyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuhpLatencyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuhpLatencyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuhpLatencyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int32_t ret() const { return at<2>().as_int32(); }
+  bool has_state() const { return at<3>().valid(); }
+  uint32_t state() const { return at<3>().as_uint32(); }
+  bool has_time() const { return at<4>().valid(); }
+  uint64_t time() const { return at<4>().as_uint64(); }
+};
+
+class CpuhpLatencyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuhpLatencyFtraceEvent_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kRetFieldNumber = 2,
+    kStateFieldNumber = 3,
+    kTimeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuhpLatencyFtraceEvent"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Time =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CpuhpLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_Time kTime{};
+  void set_time(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Time::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CpuhpEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuhpEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuhpEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuhpEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_fun() const { return at<2>().valid(); }
+  uint64_t fun() const { return at<2>().as_uint64(); }
+  bool has_idx() const { return at<3>().valid(); }
+  int32_t idx() const { return at<3>().as_int32(); }
+  bool has_target() const { return at<4>().valid(); }
+  int32_t target() const { return at<4>().as_int32(); }
+};
+
+class CpuhpEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuhpEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kFunFieldNumber = 2,
+    kIdxFieldNumber = 3,
+    kTargetFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuhpEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fun =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CpuhpEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Fun kFun{};
+  void set_fun(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fun::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Target =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Target kTarget{};
+  void set_target(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Target::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CpuhpMultiEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuhpMultiEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuhpMultiEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuhpMultiEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_fun() const { return at<2>().valid(); }
+  uint64_t fun() const { return at<2>().as_uint64(); }
+  bool has_idx() const { return at<3>().valid(); }
+  int32_t idx() const { return at<3>().as_int32(); }
+  bool has_target() const { return at<4>().valid(); }
+  int32_t target() const { return at<4>().as_int32(); }
+};
+
+class CpuhpMultiEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuhpMultiEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kFunFieldNumber = 2,
+    kIdxFieldNumber = 3,
+    kTargetFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuhpMultiEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpMultiEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fun =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CpuhpMultiEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Fun kFun{};
+  void set_fun(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fun::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpMultiEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Target =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpMultiEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Target kTarget{};
+  void set_target(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Target::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CpuhpExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuhpExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuhpExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuhpExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_idx() const { return at<2>().valid(); }
+  int32_t idx() const { return at<2>().as_int32(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+  bool has_state() const { return at<4>().valid(); }
+  int32_t state() const { return at<4>().as_int32(); }
+};
+
+class CpuhpExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuhpExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kIdxFieldNumber = 2,
+    kRetFieldNumber = 3,
+    kStateFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuhpExitFtraceEvent"; }
+
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuhpExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Idx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Idx kIdx{};
+  void set_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Idx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      CpuhpExitFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/cros_ec.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CROS_EC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_CROS_EC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class CrosEcSensorhubDataFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CrosEcSensorhubDataFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CrosEcSensorhubDataFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CrosEcSensorhubDataFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_current_time() const { return at<1>().valid(); }
+  int64_t current_time() const { return at<1>().as_int64(); }
+  bool has_current_timestamp() const { return at<2>().valid(); }
+  int64_t current_timestamp() const { return at<2>().as_int64(); }
+  bool has_delta() const { return at<3>().valid(); }
+  int64_t delta() const { return at<3>().as_int64(); }
+  bool has_ec_fifo_timestamp() const { return at<4>().valid(); }
+  uint32_t ec_fifo_timestamp() const { return at<4>().as_uint32(); }
+  bool has_ec_sensor_num() const { return at<5>().valid(); }
+  uint32_t ec_sensor_num() const { return at<5>().as_uint32(); }
+  bool has_fifo_timestamp() const { return at<6>().valid(); }
+  int64_t fifo_timestamp() const { return at<6>().as_int64(); }
+};
+
+class CrosEcSensorhubDataFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CrosEcSensorhubDataFtraceEvent_Decoder;
+  enum : int32_t {
+    kCurrentTimeFieldNumber = 1,
+    kCurrentTimestampFieldNumber = 2,
+    kDeltaFieldNumber = 3,
+    kEcFifoTimestampFieldNumber = 4,
+    kEcSensorNumFieldNumber = 5,
+    kFifoTimestampFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CrosEcSensorhubDataFtraceEvent"; }
+
+
+  using FieldMetadata_CurrentTime =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_CurrentTime kCurrentTime{};
+  void set_current_time(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentTime::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CurrentTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_CurrentTimestamp kCurrentTimestamp{};
+  void set_current_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Delta =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_Delta kDelta{};
+  void set_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Delta::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EcFifoTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_EcFifoTimestamp kEcFifoTimestamp{};
+  void set_ec_fifo_timestamp(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EcFifoTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EcSensorNum =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_EcSensorNum kEcSensorNum{};
+  void set_ec_sensor_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EcSensorNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FifoTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CrosEcSensorhubDataFtraceEvent>;
+
+  static constexpr FieldMetadata_FifoTimestamp kFifoTimestamp{};
+  void set_fifo_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FifoTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/dma_fence.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DMA_FENCE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DMA_FENCE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class DmaFenceWaitEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaFenceWaitEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaFenceWaitEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaFenceWaitEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class DmaFenceWaitEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaFenceWaitEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaFenceWaitEndFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceWaitEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceWaitEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceWaitEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceWaitEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DmaFenceWaitStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaFenceWaitStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaFenceWaitStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaFenceWaitStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class DmaFenceWaitStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaFenceWaitStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaFenceWaitStartFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceWaitStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceWaitStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceWaitStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceWaitStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DmaFenceSignaledFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaFenceSignaledFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaFenceSignaledFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaFenceSignaledFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class DmaFenceSignaledFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaFenceSignaledFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaFenceSignaledFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DmaFenceEmitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaFenceEmitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaFenceEmitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaFenceEmitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class DmaFenceEmitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaFenceEmitFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaFenceEmitFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceEmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceEmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceEmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceEmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DmaFenceInitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaFenceInitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaFenceInitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaFenceInitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class DmaFenceInitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaFenceInitFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaFenceInitFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DmaFenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DmaFenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DMABUF_HEAP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DMABUF_HEAP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class DmaHeapStatFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaHeapStatFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaHeapStatFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaHeapStatFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_inode() const { return at<1>().valid(); }
+  uint64_t inode() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  int64_t len() const { return at<2>().as_int64(); }
+  bool has_total_allocated() const { return at<3>().valid(); }
+  uint64_t total_allocated() const { return at<3>().as_uint64(); }
+};
+
+class DmaHeapStatFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaHeapStatFtraceEvent_Decoder;
+  enum : int32_t {
+    kInodeFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTotalAllocatedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaHeapStatFtraceEvent"; }
+
+
+  using FieldMetadata_Inode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DmaHeapStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Inode kInode{};
+  void set_inode(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Inode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      DmaHeapStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DmaHeapStatFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated{};
+  void set_total_allocated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalAllocated::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/dpu.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DPU_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DPU_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class DpuTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DpuTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DpuTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DpuTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_trace_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars trace_name() const { return at<2>().as_string(); }
+  bool has_trace_begin() const { return at<3>().valid(); }
+  uint32_t trace_begin() const { return at<3>().as_uint32(); }
+  bool has_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars name() const { return at<4>().as_string(); }
+  bool has_type() const { return at<5>().valid(); }
+  uint32_t type() const { return at<5>().as_uint32(); }
+  bool has_value() const { return at<6>().valid(); }
+  int32_t value() const { return at<6>().as_int32(); }
+};
+
+class DpuTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DpuTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTraceNameFieldNumber = 2,
+    kTraceBeginFieldNumber = 3,
+    kNameFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kValueFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DpuTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceName kTraceName{};
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, size);
+  }
+  void set_trace_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceBegin kTraceBegin{};
+  void set_trace_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceBegin::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DpuTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/drm.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DRM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_DRM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class DrmVblankEventDeliveredFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DrmVblankEventDeliveredFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DrmVblankEventDeliveredFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DrmVblankEventDeliveredFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_crtc() const { return at<1>().valid(); }
+  int32_t crtc() const { return at<1>().as_int32(); }
+  bool has_file() const { return at<2>().valid(); }
+  uint64_t file() const { return at<2>().as_uint64(); }
+  bool has_seq() const { return at<3>().valid(); }
+  uint32_t seq() const { return at<3>().as_uint32(); }
+};
+
+class DrmVblankEventDeliveredFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DrmVblankEventDeliveredFtraceEvent_Decoder;
+  enum : int32_t {
+    kCrtcFieldNumber = 1,
+    kFileFieldNumber = 2,
+    kSeqFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DrmVblankEventDeliveredFtraceEvent"; }
+
+
+  using FieldMetadata_Crtc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DrmVblankEventDeliveredFtraceEvent>;
+
+  static constexpr FieldMetadata_Crtc kCrtc{};
+  void set_crtc(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Crtc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_File =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmVblankEventDeliveredFtraceEvent>;
+
+  static constexpr FieldMetadata_File kFile{};
+  void set_file(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_File::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seq =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DrmVblankEventDeliveredFtraceEvent>;
+
+  static constexpr FieldMetadata_Seq kSeq{};
+  void set_seq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DrmVblankEventFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DrmVblankEventFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DrmVblankEventFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DrmVblankEventFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_crtc() const { return at<1>().valid(); }
+  int32_t crtc() const { return at<1>().as_int32(); }
+  bool has_high_prec() const { return at<2>().valid(); }
+  uint32_t high_prec() const { return at<2>().as_uint32(); }
+  bool has_seq() const { return at<3>().valid(); }
+  uint32_t seq() const { return at<3>().as_uint32(); }
+  bool has_time() const { return at<4>().valid(); }
+  int64_t time() const { return at<4>().as_int64(); }
+};
+
+class DrmVblankEventFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DrmVblankEventFtraceEvent_Decoder;
+  enum : int32_t {
+    kCrtcFieldNumber = 1,
+    kHighPrecFieldNumber = 2,
+    kSeqFieldNumber = 3,
+    kTimeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DrmVblankEventFtraceEvent"; }
+
+
+  using FieldMetadata_Crtc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DrmVblankEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Crtc kCrtc{};
+  void set_crtc(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Crtc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HighPrec =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DrmVblankEventFtraceEvent>;
+
+  static constexpr FieldMetadata_HighPrec kHighPrec{};
+  void set_high_prec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HighPrec::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seq =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DrmVblankEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Seq kSeq{};
+  void set_seq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Time =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      DrmVblankEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Time kTime{};
+  void set_time(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Time::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ext4.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_EXT4_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_EXT4_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class Ext4ZeroRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ZeroRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ZeroRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ZeroRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+  bool has_mode() const { return at<5>().valid(); }
+  int32_t mode() const { return at<5>().as_int32(); }
+};
+
+class Ext4ZeroRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ZeroRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kModeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ZeroRangeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ZeroRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4WritepagesResultFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4WritepagesResultFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4WritepagesResultFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4WritepagesResultFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+  bool has_pages_written() const { return at<4>().valid(); }
+  int32_t pages_written() const { return at<4>().as_int32(); }
+  bool has_pages_skipped() const { return at<5>().valid(); }
+  int64_t pages_skipped() const { return at<5>().as_int64(); }
+  bool has_writeback_index() const { return at<6>().valid(); }
+  uint64_t writeback_index() const { return at<6>().as_uint64(); }
+  bool has_sync_mode() const { return at<7>().valid(); }
+  int32_t sync_mode() const { return at<7>().as_int32(); }
+};
+
+class Ext4WritepagesResultFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4WritepagesResultFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+    kPagesWrittenFieldNumber = 4,
+    kPagesSkippedFieldNumber = 5,
+    kWritebackIndexFieldNumber = 6,
+    kSyncModeFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4WritepagesResultFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PagesWritten =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_PagesWritten kPagesWritten{};
+  void set_pages_written(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagesWritten::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PagesSkipped =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_PagesSkipped kPagesSkipped{};
+  void set_pages_skipped(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagesSkipped::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WritebackIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_WritebackIndex kWritebackIndex{};
+  void set_writeback_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WritebackIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SyncMode =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4WritepagesResultFtraceEvent>;
+
+  static constexpr FieldMetadata_SyncMode kSyncMode{};
+  void set_sync_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SyncMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4WritepagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4WritepagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4WritepagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4WritepagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nr_to_write() const { return at<3>().valid(); }
+  int64_t nr_to_write() const { return at<3>().as_int64(); }
+  bool has_pages_skipped() const { return at<4>().valid(); }
+  int64_t pages_skipped() const { return at<4>().as_int64(); }
+  bool has_range_start() const { return at<5>().valid(); }
+  int64_t range_start() const { return at<5>().as_int64(); }
+  bool has_range_end() const { return at<6>().valid(); }
+  int64_t range_end() const { return at<6>().as_int64(); }
+  bool has_writeback_index() const { return at<7>().valid(); }
+  uint64_t writeback_index() const { return at<7>().as_uint64(); }
+  bool has_sync_mode() const { return at<8>().valid(); }
+  int32_t sync_mode() const { return at<8>().as_int32(); }
+  bool has_for_kupdate() const { return at<9>().valid(); }
+  uint32_t for_kupdate() const { return at<9>().as_uint32(); }
+  bool has_range_cyclic() const { return at<10>().valid(); }
+  uint32_t range_cyclic() const { return at<10>().as_uint32(); }
+};
+
+class Ext4WritepagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4WritepagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNrToWriteFieldNumber = 3,
+    kPagesSkippedFieldNumber = 4,
+    kRangeStartFieldNumber = 5,
+    kRangeEndFieldNumber = 6,
+    kWritebackIndexFieldNumber = 7,
+    kSyncModeFieldNumber = 8,
+    kForKupdateFieldNumber = 9,
+    kRangeCyclicFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4WritepagesFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrToWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrToWrite kNrToWrite{};
+  void set_nr_to_write(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrToWrite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PagesSkipped =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_PagesSkipped kPagesSkipped{};
+  void set_pages_skipped(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagesSkipped::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RangeStart =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_RangeStart kRangeStart{};
+  void set_range_start(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RangeStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RangeEnd =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_RangeEnd kRangeEnd{};
+  void set_range_end(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RangeEnd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WritebackIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_WritebackIndex kWritebackIndex{};
+  void set_writeback_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WritebackIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SyncMode =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_SyncMode kSyncMode{};
+  void set_sync_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SyncMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ForKupdate =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_ForKupdate kForKupdate{};
+  void set_for_kupdate(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ForKupdate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RangeCyclic =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WritepagesFtraceEvent>;
+
+  static constexpr FieldMetadata_RangeCyclic kRangeCyclic{};
+  void set_range_cyclic(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RangeCyclic::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4WritepageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4WritepageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4WritepageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4WritepageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+};
+
+class Ext4WritepageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4WritepageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4WritepageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WritepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4WriteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4WriteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4WriteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4WriteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_copied() const { return at<5>().valid(); }
+  uint32_t copied() const { return at<5>().as_uint32(); }
+};
+
+class Ext4WriteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4WriteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kCopiedFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4WriteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Copied =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Copied kCopied{};
+  void set_copied(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Copied::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4WriteBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4WriteBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4WriteBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4WriteBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class Ext4WriteBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4WriteBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4WriteBeginFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4WriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4UnlinkExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4UnlinkExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4UnlinkExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4UnlinkExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class Ext4UnlinkExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4UnlinkExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4UnlinkExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4UnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4UnlinkEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4UnlinkEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4UnlinkEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4UnlinkEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_parent() const { return at<3>().valid(); }
+  uint64_t parent() const { return at<3>().as_uint64(); }
+  bool has_size() const { return at<4>().valid(); }
+  int64_t size() const { return at<4>().as_int64(); }
+};
+
+class Ext4UnlinkEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4UnlinkEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kParentFieldNumber = 3,
+    kSizeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4UnlinkEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Parent =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4UnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Parent kParent{};
+  void set_parent(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Parent::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4UnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4TruncateExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4TruncateExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4TruncateExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4TruncateExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_blocks() const { return at<3>().valid(); }
+  uint64_t blocks() const { return at<3>().as_uint64(); }
+};
+
+class Ext4TruncateExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4TruncateExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlocksFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4TruncateExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4TruncateEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4TruncateEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4TruncateEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4TruncateEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_blocks() const { return at<3>().valid(); }
+  uint64_t blocks() const { return at<3>().as_uint64(); }
+};
+
+class Ext4TruncateEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4TruncateEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlocksFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4TruncateEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4TruncateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4TrimExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4TrimExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4TrimExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4TrimExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev_major() const { return at<1>().valid(); }
+  int32_t dev_major() const { return at<1>().as_int32(); }
+  bool has_dev_minor() const { return at<2>().valid(); }
+  int32_t dev_minor() const { return at<2>().as_int32(); }
+  bool has_group() const { return at<3>().valid(); }
+  uint32_t group() const { return at<3>().as_uint32(); }
+  bool has_start() const { return at<4>().valid(); }
+  int32_t start() const { return at<4>().as_int32(); }
+  bool has_len() const { return at<5>().valid(); }
+  int32_t len() const { return at<5>().as_int32(); }
+};
+
+class Ext4TrimExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4TrimExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevMajorFieldNumber = 1,
+    kDevMinorFieldNumber = 2,
+    kGroupFieldNumber = 3,
+    kStartFieldNumber = 4,
+    kLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4TrimExtentFtraceEvent"; }
+
+
+  using FieldMetadata_DevMajor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_DevMajor kDevMajor{};
+  void set_dev_major(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevMajor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DevMinor =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_DevMinor kDevMinor{};
+  void set_dev_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevMinor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4TrimAllFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4TrimAllFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4TrimAllFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4TrimAllFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev_major() const { return at<1>().valid(); }
+  int32_t dev_major() const { return at<1>().as_int32(); }
+  bool has_dev_minor() const { return at<2>().valid(); }
+  int32_t dev_minor() const { return at<2>().as_int32(); }
+  bool has_group() const { return at<3>().valid(); }
+  uint32_t group() const { return at<3>().as_uint32(); }
+  bool has_start() const { return at<4>().valid(); }
+  int32_t start() const { return at<4>().as_int32(); }
+  bool has_len() const { return at<5>().valid(); }
+  int32_t len() const { return at<5>().as_int32(); }
+};
+
+class Ext4TrimAllFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4TrimAllFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevMajorFieldNumber = 1,
+    kDevMinorFieldNumber = 2,
+    kGroupFieldNumber = 3,
+    kStartFieldNumber = 4,
+    kLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4TrimAllFreeFtraceEvent"; }
+
+
+  using FieldMetadata_DevMajor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_DevMajor kDevMajor{};
+  void set_dev_major(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevMajor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DevMinor =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_DevMinor kDevMinor{};
+  void set_dev_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevMinor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4TrimAllFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4SyncFsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4SyncFsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4SyncFsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4SyncFsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_wait() const { return at<2>().valid(); }
+  int32_t wait() const { return at<2>().as_int32(); }
+};
+
+class Ext4SyncFsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4SyncFsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kWaitFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4SyncFsFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Wait =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4SyncFsFtraceEvent>;
+
+  static constexpr FieldMetadata_Wait kWait{};
+  void set_wait(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Wait::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4RequestInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4RequestInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4RequestInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4RequestInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_dir() const { return at<2>().valid(); }
+  uint64_t dir() const { return at<2>().as_uint64(); }
+  bool has_mode() const { return at<3>().valid(); }
+  uint32_t mode() const { return at<3>().as_uint32(); }
+};
+
+class Ext4RequestInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4RequestInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kDirFieldNumber = 2,
+    kModeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4RequestInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dir =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dir kDir{};
+  void set_dir(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dir::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4RequestBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4RequestBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4RequestBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4RequestBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_len() const { return at<3>().valid(); }
+  uint32_t len() const { return at<3>().as_uint32(); }
+  bool has_logical() const { return at<4>().valid(); }
+  uint32_t logical() const { return at<4>().as_uint32(); }
+  bool has_lleft() const { return at<5>().valid(); }
+  uint32_t lleft() const { return at<5>().as_uint32(); }
+  bool has_lright() const { return at<6>().valid(); }
+  uint32_t lright() const { return at<6>().as_uint32(); }
+  bool has_goal() const { return at<7>().valid(); }
+  uint64_t goal() const { return at<7>().as_uint64(); }
+  bool has_pleft() const { return at<8>().valid(); }
+  uint64_t pleft() const { return at<8>().as_uint64(); }
+  bool has_pright() const { return at<9>().valid(); }
+  uint64_t pright() const { return at<9>().as_uint64(); }
+  bool has_flags() const { return at<10>().valid(); }
+  uint32_t flags() const { return at<10>().as_uint32(); }
+};
+
+class Ext4RequestBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4RequestBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLenFieldNumber = 3,
+    kLogicalFieldNumber = 4,
+    kLleftFieldNumber = 5,
+    kLrightFieldNumber = 6,
+    kGoalFieldNumber = 7,
+    kPleftFieldNumber = 8,
+    kPrightFieldNumber = 9,
+    kFlagsFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4RequestBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Logical =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Logical kLogical{};
+  void set_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Logical::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lleft =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Lleft kLleft{};
+  void set_lleft(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lleft::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lright =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Lright kLright{};
+  void set_lright(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lright::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Goal =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Goal kGoal{};
+  void set_goal(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Goal::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pleft =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Pleft kPleft{};
+  void set_pleft(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pleft::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pright =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Pright kPright{};
+  void set_pright(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pright::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RequestBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4RemoveBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4RemoveBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4RemoveBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4RemoveBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_from() const { return at<3>().valid(); }
+  uint32_t from() const { return at<3>().as_uint32(); }
+  bool has_to() const { return at<4>().valid(); }
+  uint32_t to() const { return at<4>().as_uint32(); }
+  bool has_partial() const { return at<5>().valid(); }
+  int64_t partial() const { return at<5>().as_int64(); }
+  bool has_ee_pblk() const { return at<6>().valid(); }
+  uint64_t ee_pblk() const { return at<6>().as_uint64(); }
+  bool has_ee_lblk() const { return at<7>().valid(); }
+  uint32_t ee_lblk() const { return at<7>().as_uint32(); }
+  bool has_ee_len() const { return at<8>().valid(); }
+  uint32_t ee_len() const { return at<8>().as_uint32(); }
+  bool has_pc_lblk() const { return at<9>().valid(); }
+  uint32_t pc_lblk() const { return at<9>().as_uint32(); }
+  bool has_pc_pclu() const { return at<10>().valid(); }
+  uint64_t pc_pclu() const { return at<10>().as_uint64(); }
+  bool has_pc_state() const { return at<11>().valid(); }
+  int32_t pc_state() const { return at<11>().as_int32(); }
+};
+
+class Ext4RemoveBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4RemoveBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFromFieldNumber = 3,
+    kToFieldNumber = 4,
+    kPartialFieldNumber = 5,
+    kEePblkFieldNumber = 6,
+    kEeLblkFieldNumber = 7,
+    kEeLenFieldNumber = 8,
+    kPcLblkFieldNumber = 9,
+    kPcPcluFieldNumber = 10,
+    kPcStateFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4RemoveBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_From =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_From kFrom{};
+  void set_from(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_From::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_To =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_To kTo{};
+  void set_to(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_To::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Partial =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Partial kPartial{};
+  void set_partial(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Partial::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EePblk =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_EePblk kEePblk{};
+  void set_ee_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EePblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EeLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_EeLblk kEeLblk{};
+  void set_ee_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EeLblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EeLen =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_EeLen kEeLen{};
+  void set_ee_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EeLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PcLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_PcLblk kPcLblk{};
+  void set_pc_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcLblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PcPclu =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_PcPclu kPcPclu{};
+  void set_pc_pclu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcPclu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PcState =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4RemoveBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_PcState kPcState{};
+  void set_pc_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ReleasepageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ReleasepageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ReleasepageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ReleasepageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+};
+
+class Ext4ReleasepageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ReleasepageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ReleasepageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReleasepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReleasepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReleasepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ReadpageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ReadpageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ReadpageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ReadpageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+};
+
+class Ext4ReadpageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ReadpageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ReadpageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ReadBlockBitmapLoadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ReadBlockBitmapLoadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ReadBlockBitmapLoadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ReadBlockBitmapLoadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_group() const { return at<2>().valid(); }
+  uint32_t group() const { return at<2>().as_uint32(); }
+  bool has_prefetch() const { return at<3>().valid(); }
+  uint32_t prefetch() const { return at<3>().as_uint32(); }
+};
+
+class Ext4ReadBlockBitmapLoadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ReadBlockBitmapLoadFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kGroupFieldNumber = 2,
+    kPrefetchFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ReadBlockBitmapLoadFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ReadBlockBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ReadBlockBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prefetch =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ReadBlockBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Prefetch kPrefetch{};
+  void set_prefetch(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prefetch::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4PunchHoleFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4PunchHoleFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4PunchHoleFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4PunchHoleFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+  bool has_mode() const { return at<5>().valid(); }
+  int32_t mode() const { return at<5>().as_int32(); }
+};
+
+class Ext4PunchHoleFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4PunchHoleFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kModeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4PunchHoleFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4PunchHoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4OtherInodeUpdateTimeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4OtherInodeUpdateTimeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4OtherInodeUpdateTimeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4OtherInodeUpdateTimeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_orig_ino() const { return at<3>().valid(); }
+  uint64_t orig_ino() const { return at<3>().as_uint64(); }
+  bool has_uid() const { return at<4>().valid(); }
+  uint32_t uid() const { return at<4>().as_uint32(); }
+  bool has_gid() const { return at<5>().valid(); }
+  uint32_t gid() const { return at<5>().as_uint32(); }
+  bool has_mode() const { return at<6>().valid(); }
+  uint32_t mode() const { return at<6>().as_uint32(); }
+};
+
+class Ext4OtherInodeUpdateTimeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4OtherInodeUpdateTimeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOrigInoFieldNumber = 3,
+    kUidFieldNumber = 4,
+    kGidFieldNumber = 5,
+    kModeFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4OtherInodeUpdateTimeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrigIno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigIno kOrigIno{};
+  void set_orig_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigIno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Gid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_Gid kGid{};
+  void set_gid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Gid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4OtherInodeUpdateTimeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MballocPreallocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MballocPreallocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MballocPreallocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MballocPreallocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_orig_logical() const { return at<3>().valid(); }
+  uint32_t orig_logical() const { return at<3>().as_uint32(); }
+  bool has_orig_start() const { return at<4>().valid(); }
+  int32_t orig_start() const { return at<4>().as_int32(); }
+  bool has_orig_group() const { return at<5>().valid(); }
+  uint32_t orig_group() const { return at<5>().as_uint32(); }
+  bool has_orig_len() const { return at<6>().valid(); }
+  int32_t orig_len() const { return at<6>().as_int32(); }
+  bool has_result_logical() const { return at<7>().valid(); }
+  uint32_t result_logical() const { return at<7>().as_uint32(); }
+  bool has_result_start() const { return at<8>().valid(); }
+  int32_t result_start() const { return at<8>().as_int32(); }
+  bool has_result_group() const { return at<9>().valid(); }
+  uint32_t result_group() const { return at<9>().as_uint32(); }
+  bool has_result_len() const { return at<10>().valid(); }
+  int32_t result_len() const { return at<10>().as_int32(); }
+};
+
+class Ext4MballocPreallocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MballocPreallocFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOrigLogicalFieldNumber = 3,
+    kOrigStartFieldNumber = 4,
+    kOrigGroupFieldNumber = 5,
+    kOrigLenFieldNumber = 6,
+    kResultLogicalFieldNumber = 7,
+    kResultStartFieldNumber = 8,
+    kResultGroupFieldNumber = 9,
+    kResultLenFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MballocPreallocFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrigLogical =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigLogical kOrigLogical{};
+  void set_orig_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigLogical::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrigStart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigStart kOrigStart{};
+  void set_orig_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrigGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigGroup kOrigGroup{};
+  void set_orig_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigGroup::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrigLen =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigLen kOrigLen{};
+  void set_orig_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultLogical =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLogical kResultLogical{};
+  void set_result_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLogical::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultStart =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultStart kResultStart{};
+  void set_result_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultGroup kResultGroup{};
+  void set_result_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultGroup::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultLen =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocPreallocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLen kResultLen{};
+  void set_result_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MballocFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MballocFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MballocFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MballocFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_result_start() const { return at<3>().valid(); }
+  int32_t result_start() const { return at<3>().as_int32(); }
+  bool has_result_group() const { return at<4>().valid(); }
+  uint32_t result_group() const { return at<4>().as_uint32(); }
+  bool has_result_len() const { return at<5>().valid(); }
+  int32_t result_len() const { return at<5>().as_int32(); }
+};
+
+class Ext4MballocFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MballocFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kResultStartFieldNumber = 3,
+    kResultGroupFieldNumber = 4,
+    kResultLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MballocFreeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultStart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultStart kResultStart{};
+  void set_result_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultGroup kResultGroup{};
+  void set_result_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultGroup::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultLen =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLen kResultLen{};
+  void set_result_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MballocDiscardFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MballocDiscardFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MballocDiscardFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MballocDiscardFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_result_start() const { return at<3>().valid(); }
+  int32_t result_start() const { return at<3>().as_int32(); }
+  bool has_result_group() const { return at<4>().valid(); }
+  uint32_t result_group() const { return at<4>().as_uint32(); }
+  bool has_result_len() const { return at<5>().valid(); }
+  int32_t result_len() const { return at<5>().as_int32(); }
+};
+
+class Ext4MballocDiscardFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MballocDiscardFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kResultStartFieldNumber = 3,
+    kResultGroupFieldNumber = 4,
+    kResultLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MballocDiscardFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultStart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultStart kResultStart{};
+  void set_result_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultGroup kResultGroup{};
+  void set_result_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultGroup::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultLen =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocDiscardFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLen kResultLen{};
+  void set_result_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MballocAllocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/20, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MballocAllocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MballocAllocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MballocAllocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_orig_logical() const { return at<3>().valid(); }
+  uint32_t orig_logical() const { return at<3>().as_uint32(); }
+  bool has_orig_start() const { return at<4>().valid(); }
+  int32_t orig_start() const { return at<4>().as_int32(); }
+  bool has_orig_group() const { return at<5>().valid(); }
+  uint32_t orig_group() const { return at<5>().as_uint32(); }
+  bool has_orig_len() const { return at<6>().valid(); }
+  int32_t orig_len() const { return at<6>().as_int32(); }
+  bool has_goal_logical() const { return at<7>().valid(); }
+  uint32_t goal_logical() const { return at<7>().as_uint32(); }
+  bool has_goal_start() const { return at<8>().valid(); }
+  int32_t goal_start() const { return at<8>().as_int32(); }
+  bool has_goal_group() const { return at<9>().valid(); }
+  uint32_t goal_group() const { return at<9>().as_uint32(); }
+  bool has_goal_len() const { return at<10>().valid(); }
+  int32_t goal_len() const { return at<10>().as_int32(); }
+  bool has_result_logical() const { return at<11>().valid(); }
+  uint32_t result_logical() const { return at<11>().as_uint32(); }
+  bool has_result_start() const { return at<12>().valid(); }
+  int32_t result_start() const { return at<12>().as_int32(); }
+  bool has_result_group() const { return at<13>().valid(); }
+  uint32_t result_group() const { return at<13>().as_uint32(); }
+  bool has_result_len() const { return at<14>().valid(); }
+  int32_t result_len() const { return at<14>().as_int32(); }
+  bool has_found() const { return at<15>().valid(); }
+  uint32_t found() const { return at<15>().as_uint32(); }
+  bool has_groups() const { return at<16>().valid(); }
+  uint32_t groups() const { return at<16>().as_uint32(); }
+  bool has_buddy() const { return at<17>().valid(); }
+  uint32_t buddy() const { return at<17>().as_uint32(); }
+  bool has_flags() const { return at<18>().valid(); }
+  uint32_t flags() const { return at<18>().as_uint32(); }
+  bool has_tail() const { return at<19>().valid(); }
+  uint32_t tail() const { return at<19>().as_uint32(); }
+  bool has_cr() const { return at<20>().valid(); }
+  uint32_t cr() const { return at<20>().as_uint32(); }
+};
+
+class Ext4MballocAllocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MballocAllocFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOrigLogicalFieldNumber = 3,
+    kOrigStartFieldNumber = 4,
+    kOrigGroupFieldNumber = 5,
+    kOrigLenFieldNumber = 6,
+    kGoalLogicalFieldNumber = 7,
+    kGoalStartFieldNumber = 8,
+    kGoalGroupFieldNumber = 9,
+    kGoalLenFieldNumber = 10,
+    kResultLogicalFieldNumber = 11,
+    kResultStartFieldNumber = 12,
+    kResultGroupFieldNumber = 13,
+    kResultLenFieldNumber = 14,
+    kFoundFieldNumber = 15,
+    kGroupsFieldNumber = 16,
+    kBuddyFieldNumber = 17,
+    kFlagsFieldNumber = 18,
+    kTailFieldNumber = 19,
+    kCrFieldNumber = 20,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MballocAllocFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrigLogical =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigLogical kOrigLogical{};
+  void set_orig_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigLogical::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrigStart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigStart kOrigStart{};
+  void set_orig_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrigGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigGroup kOrigGroup{};
+  void set_orig_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigGroup::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrigLen =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_OrigLen kOrigLen{};
+  void set_orig_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GoalLogical =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GoalLogical kGoalLogical{};
+  void set_goal_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GoalLogical::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GoalStart =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GoalStart kGoalStart{};
+  void set_goal_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GoalStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GoalGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GoalGroup kGoalGroup{};
+  void set_goal_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GoalGroup::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GoalLen =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GoalLen kGoalLen{};
+  void set_goal_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GoalLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultLogical =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLogical kResultLogical{};
+  void set_result_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLogical::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultStart =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultStart kResultStart{};
+  void set_result_start(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultGroup =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultGroup kResultGroup{};
+  void set_result_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultGroup::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResultLen =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_ResultLen kResultLen{};
+  void set_result_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResultLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Found =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Found kFound{};
+  void set_found(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Found::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Groups =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Groups kGroups{};
+  void set_groups(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Groups::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Buddy =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Buddy kBuddy{};
+  void set_buddy(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Buddy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tail =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Tail kTail{};
+  void set_tail(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tail::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cr =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MballocAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Cr kCr{};
+  void set_cr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MbReleaseInodePaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbReleaseInodePaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbReleaseInodePaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbReleaseInodePaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_block() const { return at<3>().valid(); }
+  uint64_t block() const { return at<3>().as_uint64(); }
+  bool has_count() const { return at<4>().valid(); }
+  uint32_t count() const { return at<4>().as_uint32(); }
+};
+
+class Ext4MbReleaseInodePaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbReleaseInodePaFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlockFieldNumber = 3,
+    kCountFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbReleaseInodePaFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Block =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Block kBlock{};
+  void set_block(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Block::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbReleaseInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MbReleaseGroupPaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbReleaseGroupPaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbReleaseGroupPaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbReleaseGroupPaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_pa_pstart() const { return at<2>().valid(); }
+  uint64_t pa_pstart() const { return at<2>().as_uint64(); }
+  bool has_pa_len() const { return at<3>().valid(); }
+  uint32_t pa_len() const { return at<3>().as_uint32(); }
+};
+
+class Ext4MbReleaseGroupPaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbReleaseGroupPaFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kPaPstartFieldNumber = 2,
+    kPaLenFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbReleaseGroupPaFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PaPstart =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbReleaseGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaPstart kPaPstart{};
+  void set_pa_pstart(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaPstart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PaLen =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbReleaseGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaLen kPaLen{};
+  void set_pa_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MbNewInodePaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbNewInodePaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbNewInodePaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbNewInodePaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pa_pstart() const { return at<3>().valid(); }
+  uint64_t pa_pstart() const { return at<3>().as_uint64(); }
+  bool has_pa_lstart() const { return at<4>().valid(); }
+  uint64_t pa_lstart() const { return at<4>().as_uint64(); }
+  bool has_pa_len() const { return at<5>().valid(); }
+  uint32_t pa_len() const { return at<5>().as_uint32(); }
+};
+
+class Ext4MbNewInodePaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbNewInodePaFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPaPstartFieldNumber = 3,
+    kPaLstartFieldNumber = 4,
+    kPaLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbNewInodePaFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PaPstart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaPstart kPaPstart{};
+  void set_pa_pstart(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaPstart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PaLstart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaLstart kPaLstart{};
+  void set_pa_lstart(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaLstart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PaLen =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbNewInodePaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaLen kPaLen{};
+  void set_pa_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MbNewGroupPaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbNewGroupPaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbNewGroupPaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbNewGroupPaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pa_pstart() const { return at<3>().valid(); }
+  uint64_t pa_pstart() const { return at<3>().as_uint64(); }
+  bool has_pa_lstart() const { return at<4>().valid(); }
+  uint64_t pa_lstart() const { return at<4>().as_uint64(); }
+  bool has_pa_len() const { return at<5>().valid(); }
+  uint32_t pa_len() const { return at<5>().as_uint32(); }
+};
+
+class Ext4MbNewGroupPaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbNewGroupPaFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPaPstartFieldNumber = 3,
+    kPaLstartFieldNumber = 4,
+    kPaLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbNewGroupPaFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PaPstart =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaPstart kPaPstart{};
+  void set_pa_pstart(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaPstart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PaLstart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaLstart kPaLstart{};
+  void set_pa_lstart(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaLstart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PaLen =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbNewGroupPaFtraceEvent>;
+
+  static constexpr FieldMetadata_PaLen kPaLen{};
+  void set_pa_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PaLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MbDiscardPreallocationsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbDiscardPreallocationsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbDiscardPreallocationsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbDiscardPreallocationsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_needed() const { return at<2>().valid(); }
+  int32_t needed() const { return at<2>().as_int32(); }
+};
+
+class Ext4MbDiscardPreallocationsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbDiscardPreallocationsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNeededFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbDiscardPreallocationsFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbDiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Needed =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4MbDiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Needed kNeeded{};
+  void set_needed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Needed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MbBuddyBitmapLoadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbBuddyBitmapLoadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbBuddyBitmapLoadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbBuddyBitmapLoadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_group() const { return at<2>().valid(); }
+  uint32_t group() const { return at<2>().as_uint32(); }
+};
+
+class Ext4MbBuddyBitmapLoadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbBuddyBitmapLoadFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kGroupFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbBuddyBitmapLoadFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbBuddyBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbBuddyBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MbBitmapLoadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MbBitmapLoadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MbBitmapLoadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MbBitmapLoadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_group() const { return at<2>().valid(); }
+  uint32_t group() const { return at<2>().as_uint32(); }
+};
+
+class Ext4MbBitmapLoadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MbBitmapLoadFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kGroupFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MbBitmapLoadFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MbBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4MbBitmapLoadFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4MarkInodeDirtyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4MarkInodeDirtyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4MarkInodeDirtyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4MarkInodeDirtyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ip() const { return at<3>().valid(); }
+  uint64_t ip() const { return at<3>().as_uint64(); }
+};
+
+class Ext4MarkInodeDirtyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4MarkInodeDirtyFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIpFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4MarkInodeDirtyFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MarkInodeDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MarkInodeDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ip =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4MarkInodeDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Ip kIp{};
+  void set_ip(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ip::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4LoadInodeBitmapFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4LoadInodeBitmapFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4LoadInodeBitmapFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4LoadInodeBitmapFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_group() const { return at<2>().valid(); }
+  uint32_t group() const { return at<2>().as_uint32(); }
+};
+
+class Ext4LoadInodeBitmapFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4LoadInodeBitmapFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kGroupFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4LoadInodeBitmapFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4LoadInodeBitmapFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4LoadInodeBitmapFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4LoadInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4LoadInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4LoadInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4LoadInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+};
+
+class Ext4LoadInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4LoadInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4LoadInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4LoadInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4LoadInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4JournalledWriteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4JournalledWriteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4JournalledWriteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4JournalledWriteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_copied() const { return at<5>().valid(); }
+  uint32_t copied() const { return at<5>().as_uint32(); }
+};
+
+class Ext4JournalledWriteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4JournalledWriteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kCopiedFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4JournalledWriteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Copied =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4JournalledWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Copied kCopied{};
+  void set_copied(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Copied::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4JournalledInvalidatepageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4JournalledInvalidatepageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4JournalledInvalidatepageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4JournalledInvalidatepageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+  bool has_offset() const { return at<4>().valid(); }
+  uint64_t offset() const { return at<4>().as_uint64(); }
+  bool has_length() const { return at<5>().valid(); }
+  uint32_t length() const { return at<5>().as_uint32(); }
+};
+
+class Ext4JournalledInvalidatepageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4JournalledInvalidatepageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kOffsetFieldNumber = 4,
+    kLengthFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4JournalledInvalidatepageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Length =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4JournalledInvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Length kLength{};
+  void set_length(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Length::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4JournalStartReservedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4JournalStartReservedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4JournalStartReservedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4JournalStartReservedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ip() const { return at<2>().valid(); }
+  uint64_t ip() const { return at<2>().as_uint64(); }
+  bool has_blocks() const { return at<3>().valid(); }
+  int32_t blocks() const { return at<3>().as_int32(); }
+};
+
+class Ext4JournalStartReservedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4JournalStartReservedFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kIpFieldNumber = 2,
+    kBlocksFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4JournalStartReservedFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalStartReservedFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ip =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalStartReservedFtraceEvent>;
+
+  static constexpr FieldMetadata_Ip kIp{};
+  void set_ip(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ip::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4JournalStartReservedFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4JournalStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4JournalStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4JournalStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4JournalStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ip() const { return at<2>().valid(); }
+  uint64_t ip() const { return at<2>().as_uint64(); }
+  bool has_blocks() const { return at<3>().valid(); }
+  int32_t blocks() const { return at<3>().as_int32(); }
+  bool has_rsv_blocks() const { return at<4>().valid(); }
+  int32_t rsv_blocks() const { return at<4>().as_int32(); }
+  bool has_nblocks() const { return at<5>().valid(); }
+  int32_t nblocks() const { return at<5>().as_int32(); }
+  bool has_revoke_creds() const { return at<6>().valid(); }
+  int32_t revoke_creds() const { return at<6>().as_int32(); }
+};
+
+class Ext4JournalStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4JournalStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kIpFieldNumber = 2,
+    kBlocksFieldNumber = 3,
+    kRsvBlocksFieldNumber = 4,
+    kNblocksFieldNumber = 5,
+    kRevokeCredsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4JournalStartFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ip =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Ip kIp{};
+  void set_ip(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ip::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RsvBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_RsvBlocks kRsvBlocks{};
+  void set_rsv_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RsvBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nblocks =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Nblocks kNblocks{};
+  void set_nblocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nblocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RevokeCreds =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4JournalStartFtraceEvent>;
+
+  static constexpr FieldMetadata_RevokeCreds kRevokeCreds{};
+  void set_revoke_creds(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RevokeCreds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4InvalidatepageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4InvalidatepageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4InvalidatepageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4InvalidatepageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+  bool has_offset() const { return at<4>().valid(); }
+  uint64_t offset() const { return at<4>().as_uint64(); }
+  bool has_length() const { return at<5>().valid(); }
+  uint32_t length() const { return at<5>().as_uint32(); }
+};
+
+class Ext4InvalidatepageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4InvalidatepageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kOffsetFieldNumber = 4,
+    kLengthFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4InvalidatepageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Length =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4InvalidatepageFtraceEvent>;
+
+  static constexpr FieldMetadata_Length kLength{};
+  void set_length(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Length::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4InsertRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4InsertRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4InsertRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4InsertRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+};
+
+class Ext4InsertRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4InsertRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4InsertRangeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InsertRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4InsertRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4InsertRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4InsertRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4IndMapBlocksExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4IndMapBlocksExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4IndMapBlocksExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4IndMapBlocksExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_pblk() const { return at<4>().valid(); }
+  uint64_t pblk() const { return at<4>().as_uint64(); }
+  bool has_lblk() const { return at<5>().valid(); }
+  uint32_t lblk() const { return at<5>().as_uint32(); }
+  bool has_len() const { return at<6>().valid(); }
+  uint32_t len() const { return at<6>().as_uint32(); }
+  bool has_mflags() const { return at<7>().valid(); }
+  uint32_t mflags() const { return at<7>().as_uint32(); }
+  bool has_ret() const { return at<8>().valid(); }
+  int32_t ret() const { return at<8>().as_int32(); }
+};
+
+class Ext4IndMapBlocksExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4IndMapBlocksExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kPblkFieldNumber = 4,
+    kLblkFieldNumber = 5,
+    kLenFieldNumber = 6,
+    kMflagsFieldNumber = 7,
+    kRetFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4IndMapBlocksExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mflags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Mflags kMflags{};
+  void set_mflags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mflags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4IndMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4IndMapBlocksEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4IndMapBlocksEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4IndMapBlocksEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4IndMapBlocksEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class Ext4IndMapBlocksEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4IndMapBlocksEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4IndMapBlocksEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4IndMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4GetReservedClusterAllocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4GetReservedClusterAllocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4GetReservedClusterAllocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4GetReservedClusterAllocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+};
+
+class Ext4GetReservedClusterAllocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4GetReservedClusterAllocFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4GetReservedClusterAllocFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4GetReservedClusterAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4GetReservedClusterAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4GetReservedClusterAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4GetReservedClusterAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4GetImpliedClusterAllocExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4GetImpliedClusterAllocExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4GetImpliedClusterAllocExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4GetImpliedClusterAllocExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_pblk() const { return at<4>().valid(); }
+  uint64_t pblk() const { return at<4>().as_uint64(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+  bool has_ret() const { return at<6>().valid(); }
+  int32_t ret() const { return at<6>().as_int32(); }
+};
+
+class Ext4GetImpliedClusterAllocExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4GetImpliedClusterAllocExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kPblkFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kRetFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4GetImpliedClusterAllocExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4GetImpliedClusterAllocExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4FreeInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4FreeInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4FreeInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4FreeInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_uid() const { return at<3>().valid(); }
+  uint32_t uid() const { return at<3>().as_uint32(); }
+  bool has_gid() const { return at<4>().valid(); }
+  uint32_t gid() const { return at<4>().as_uint32(); }
+  bool has_blocks() const { return at<5>().valid(); }
+  uint64_t blocks() const { return at<5>().as_uint64(); }
+  bool has_mode() const { return at<6>().valid(); }
+  uint32_t mode() const { return at<6>().as_uint32(); }
+};
+
+class Ext4FreeInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4FreeInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kUidFieldNumber = 3,
+    kGidFieldNumber = 4,
+    kBlocksFieldNumber = 5,
+    kModeFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4FreeInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Gid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Gid kGid{};
+  void set_gid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Gid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FreeInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4FreeBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4FreeBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4FreeBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4FreeBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_block() const { return at<3>().valid(); }
+  uint64_t block() const { return at<3>().as_uint64(); }
+  bool has_count() const { return at<4>().valid(); }
+  uint64_t count() const { return at<4>().as_uint64(); }
+  bool has_flags() const { return at<5>().valid(); }
+  int32_t flags() const { return at<5>().as_int32(); }
+  bool has_mode() const { return at<6>().valid(); }
+  uint32_t mode() const { return at<6>().as_uint32(); }
+};
+
+class Ext4FreeBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4FreeBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlockFieldNumber = 3,
+    kCountFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+    kModeFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4FreeBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Block =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Block kBlock{};
+  void set_block(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Block::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FreeBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ForgetFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ForgetFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ForgetFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ForgetFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_block() const { return at<3>().valid(); }
+  uint64_t block() const { return at<3>().as_uint64(); }
+  bool has_is_metadata() const { return at<4>().valid(); }
+  int32_t is_metadata() const { return at<4>().as_int32(); }
+  bool has_mode() const { return at<5>().valid(); }
+  uint32_t mode() const { return at<5>().as_uint32(); }
+};
+
+class Ext4ForgetFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ForgetFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlockFieldNumber = 3,
+    kIsMetadataFieldNumber = 4,
+    kModeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ForgetFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ForgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ForgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Block =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ForgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Block kBlock{};
+  void set_block(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Block::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsMetadata =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ForgetFtraceEvent>;
+
+  static constexpr FieldMetadata_IsMetadata kIsMetadata{};
+  void set_is_metadata(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsMetadata::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ForgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4FindDelallocRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4FindDelallocRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4FindDelallocRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4FindDelallocRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_from() const { return at<3>().valid(); }
+  uint32_t from() const { return at<3>().as_uint32(); }
+  bool has_to() const { return at<4>().valid(); }
+  uint32_t to() const { return at<4>().as_uint32(); }
+  bool has_reverse() const { return at<5>().valid(); }
+  int32_t reverse() const { return at<5>().as_int32(); }
+  bool has_found() const { return at<6>().valid(); }
+  int32_t found() const { return at<6>().as_int32(); }
+  bool has_found_blk() const { return at<7>().valid(); }
+  uint32_t found_blk() const { return at<7>().as_uint32(); }
+};
+
+class Ext4FindDelallocRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4FindDelallocRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFromFieldNumber = 3,
+    kToFieldNumber = 4,
+    kReverseFieldNumber = 5,
+    kFoundFieldNumber = 6,
+    kFoundBlkFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4FindDelallocRangeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_From =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_From kFrom{};
+  void set_from(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_From::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_To =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_To kTo{};
+  void set_to(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_To::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Reverse =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Reverse kReverse{};
+  void set_reverse(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reverse::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Found =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Found kFound{};
+  void set_found(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Found::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FoundBlk =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FindDelallocRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_FoundBlk kFoundBlk{};
+  void set_found_blk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FoundBlk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4FallocateExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4FallocateExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4FallocateExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4FallocateExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_blocks() const { return at<4>().valid(); }
+  uint32_t blocks() const { return at<4>().as_uint32(); }
+  bool has_ret() const { return at<5>().valid(); }
+  int32_t ret() const { return at<5>().as_int32(); }
+};
+
+class Ext4FallocateExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4FallocateExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kBlocksFieldNumber = 4,
+    kRetFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4FallocateExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4FallocateExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4FallocateEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4FallocateEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4FallocateEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4FallocateEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+  bool has_mode() const { return at<5>().valid(); }
+  int32_t mode() const { return at<5>().as_int32(); }
+  bool has_pos() const { return at<6>().valid(); }
+  int64_t pos() const { return at<6>().as_int64(); }
+};
+
+class Ext4FallocateEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4FallocateEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kModeFieldNumber = 5,
+    kPosFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4FallocateEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4FallocateEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtShowExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtShowExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtShowExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtShowExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pblk() const { return at<3>().valid(); }
+  uint64_t pblk() const { return at<3>().as_uint64(); }
+  bool has_lblk() const { return at<4>().valid(); }
+  uint32_t lblk() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+};
+
+class Ext4ExtShowExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtShowExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPblkFieldNumber = 3,
+    kLblkFieldNumber = 4,
+    kLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtShowExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtShowExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtRmLeafFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtRmLeafFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtRmLeafFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtRmLeafFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_partial() const { return at<3>().valid(); }
+  int64_t partial() const { return at<3>().as_int64(); }
+  bool has_start() const { return at<4>().valid(); }
+  uint32_t start() const { return at<4>().as_uint32(); }
+  bool has_ee_lblk() const { return at<5>().valid(); }
+  uint32_t ee_lblk() const { return at<5>().as_uint32(); }
+  bool has_ee_pblk() const { return at<6>().valid(); }
+  uint64_t ee_pblk() const { return at<6>().as_uint64(); }
+  bool has_ee_len() const { return at<7>().valid(); }
+  int32_t ee_len() const { return at<7>().as_int32(); }
+  bool has_pc_lblk() const { return at<8>().valid(); }
+  uint32_t pc_lblk() const { return at<8>().as_uint32(); }
+  bool has_pc_pclu() const { return at<9>().valid(); }
+  uint64_t pc_pclu() const { return at<9>().as_uint64(); }
+  bool has_pc_state() const { return at<10>().valid(); }
+  int32_t pc_state() const { return at<10>().as_int32(); }
+};
+
+class Ext4ExtRmLeafFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtRmLeafFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPartialFieldNumber = 3,
+    kStartFieldNumber = 4,
+    kEeLblkFieldNumber = 5,
+    kEePblkFieldNumber = 6,
+    kEeLenFieldNumber = 7,
+    kPcLblkFieldNumber = 8,
+    kPcPcluFieldNumber = 9,
+    kPcStateFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtRmLeafFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Partial =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_Partial kPartial{};
+  void set_partial(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Partial::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EeLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_EeLblk kEeLblk{};
+  void set_ee_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EeLblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EePblk =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_EePblk kEePblk{};
+  void set_ee_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EePblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EeLen =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_EeLen kEeLen{};
+  void set_ee_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EeLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PcLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_PcLblk kPcLblk{};
+  void set_pc_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcLblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PcPclu =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_PcPclu kPcPclu{};
+  void set_pc_pclu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcPclu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PcState =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtRmLeafFtraceEvent>;
+
+  static constexpr FieldMetadata_PcState kPcState{};
+  void set_pc_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtRmIdxFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtRmIdxFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtRmIdxFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtRmIdxFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pblk() const { return at<3>().valid(); }
+  uint64_t pblk() const { return at<3>().as_uint64(); }
+};
+
+class Ext4ExtRmIdxFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtRmIdxFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPblkFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtRmIdxFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmIdxFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmIdxFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRmIdxFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtRemoveSpaceDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtRemoveSpaceDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtRemoveSpaceDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtRemoveSpaceDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_start() const { return at<3>().valid(); }
+  uint32_t start() const { return at<3>().as_uint32(); }
+  bool has_end() const { return at<4>().valid(); }
+  uint32_t end() const { return at<4>().as_uint32(); }
+  bool has_depth() const { return at<5>().valid(); }
+  int32_t depth() const { return at<5>().as_int32(); }
+  bool has_partial() const { return at<6>().valid(); }
+  int64_t partial() const { return at<6>().as_int64(); }
+  bool has_eh_entries() const { return at<7>().valid(); }
+  uint32_t eh_entries() const { return at<7>().as_uint32(); }
+  bool has_pc_lblk() const { return at<8>().valid(); }
+  uint32_t pc_lblk() const { return at<8>().as_uint32(); }
+  bool has_pc_pclu() const { return at<9>().valid(); }
+  uint64_t pc_pclu() const { return at<9>().as_uint64(); }
+  bool has_pc_state() const { return at<10>().valid(); }
+  int32_t pc_state() const { return at<10>().as_int32(); }
+};
+
+class Ext4ExtRemoveSpaceDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtRemoveSpaceDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kStartFieldNumber = 3,
+    kEndFieldNumber = 4,
+    kDepthFieldNumber = 5,
+    kPartialFieldNumber = 6,
+    kEhEntriesFieldNumber = 7,
+    kPcLblkFieldNumber = 8,
+    kPcPcluFieldNumber = 9,
+    kPcStateFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtRemoveSpaceDoneFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_End =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Depth =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Depth kDepth{};
+  void set_depth(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Depth::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Partial =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Partial kPartial{};
+  void set_partial(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Partial::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EhEntries =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_EhEntries kEhEntries{};
+  void set_eh_entries(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EhEntries::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PcLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_PcLblk kPcLblk{};
+  void set_pc_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcLblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PcPclu =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_PcPclu kPcPclu{};
+  void set_pc_pclu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcPclu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PcState =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtRemoveSpaceDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_PcState kPcState{};
+  void set_pc_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PcState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtRemoveSpaceFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtRemoveSpaceFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtRemoveSpaceFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtRemoveSpaceFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_start() const { return at<3>().valid(); }
+  uint32_t start() const { return at<3>().as_uint32(); }
+  bool has_end() const { return at<4>().valid(); }
+  uint32_t end() const { return at<4>().as_uint32(); }
+  bool has_depth() const { return at<5>().valid(); }
+  int32_t depth() const { return at<5>().as_int32(); }
+};
+
+class Ext4ExtRemoveSpaceFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtRemoveSpaceFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kStartFieldNumber = 3,
+    kEndFieldNumber = 4,
+    kDepthFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtRemoveSpaceFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_End =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Depth =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtRemoveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Depth kDepth{};
+  void set_depth(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Depth::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtPutInCacheFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtPutInCacheFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtPutInCacheFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtPutInCacheFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_start() const { return at<5>().valid(); }
+  uint64_t start() const { return at<5>().as_uint64(); }
+};
+
+class Ext4ExtPutInCacheFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtPutInCacheFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kStartFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtPutInCacheFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtPutInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtMapBlocksExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtMapBlocksExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtMapBlocksExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtMapBlocksExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_pblk() const { return at<4>().valid(); }
+  uint64_t pblk() const { return at<4>().as_uint64(); }
+  bool has_lblk() const { return at<5>().valid(); }
+  uint32_t lblk() const { return at<5>().as_uint32(); }
+  bool has_len() const { return at<6>().valid(); }
+  uint32_t len() const { return at<6>().as_uint32(); }
+  bool has_mflags() const { return at<7>().valid(); }
+  uint32_t mflags() const { return at<7>().as_uint32(); }
+  bool has_ret() const { return at<8>().valid(); }
+  int32_t ret() const { return at<8>().as_int32(); }
+};
+
+class Ext4ExtMapBlocksExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtMapBlocksExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kPblkFieldNumber = 4,
+    kLblkFieldNumber = 5,
+    kLenFieldNumber = 6,
+    kMflagsFieldNumber = 7,
+    kRetFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtMapBlocksExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mflags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Mflags kMflags{};
+  void set_mflags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mflags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtMapBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtMapBlocksEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtMapBlocksEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtMapBlocksEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtMapBlocksEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class Ext4ExtMapBlocksEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtMapBlocksEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtMapBlocksEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtMapBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtLoadExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtLoadExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtLoadExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtLoadExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pblk() const { return at<3>().valid(); }
+  uint64_t pblk() const { return at<3>().as_uint64(); }
+  bool has_lblk() const { return at<4>().valid(); }
+  uint32_t lblk() const { return at<4>().as_uint32(); }
+};
+
+class Ext4ExtLoadExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtLoadExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPblkFieldNumber = 3,
+    kLblkFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtLoadExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtLoadExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtLoadExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtLoadExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtLoadExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtInCacheFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtInCacheFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtInCacheFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtInCacheFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_ret() const { return at<4>().valid(); }
+  int32_t ret() const { return at<4>().as_int32(); }
+};
+
+class Ext4ExtInCacheFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtInCacheFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kRetFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtInCacheFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtInCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtHandleUnwrittenExtentsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtHandleUnwrittenExtentsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtHandleUnwrittenExtentsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtHandleUnwrittenExtentsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_flags() const { return at<3>().valid(); }
+  int32_t flags() const { return at<3>().as_int32(); }
+  bool has_lblk() const { return at<4>().valid(); }
+  uint32_t lblk() const { return at<4>().as_uint32(); }
+  bool has_pblk() const { return at<5>().valid(); }
+  uint64_t pblk() const { return at<5>().as_uint64(); }
+  bool has_len() const { return at<6>().valid(); }
+  uint32_t len() const { return at<6>().as_uint32(); }
+  bool has_allocated() const { return at<7>().valid(); }
+  uint32_t allocated() const { return at<7>().as_uint32(); }
+  bool has_newblk() const { return at<8>().valid(); }
+  uint64_t newblk() const { return at<8>().as_uint64(); }
+};
+
+class Ext4ExtHandleUnwrittenExtentsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtHandleUnwrittenExtentsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kLblkFieldNumber = 4,
+    kPblkFieldNumber = 5,
+    kLenFieldNumber = 6,
+    kAllocatedFieldNumber = 7,
+    kNewblkFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtHandleUnwrittenExtentsFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Allocated =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Allocated kAllocated{};
+  void set_allocated(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Allocated::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Newblk =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtHandleUnwrittenExtentsFtraceEvent>;
+
+  static constexpr FieldMetadata_Newblk kNewblk{};
+  void set_newblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Newblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtConvertToInitializedFastpathFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtConvertToInitializedFastpathFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtConvertToInitializedFastpathFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtConvertToInitializedFastpathFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_m_lblk() const { return at<3>().valid(); }
+  uint32_t m_lblk() const { return at<3>().as_uint32(); }
+  bool has_m_len() const { return at<4>().valid(); }
+  uint32_t m_len() const { return at<4>().as_uint32(); }
+  bool has_u_lblk() const { return at<5>().valid(); }
+  uint32_t u_lblk() const { return at<5>().as_uint32(); }
+  bool has_u_len() const { return at<6>().valid(); }
+  uint32_t u_len() const { return at<6>().as_uint32(); }
+  bool has_u_pblk() const { return at<7>().valid(); }
+  uint64_t u_pblk() const { return at<7>().as_uint64(); }
+  bool has_i_lblk() const { return at<8>().valid(); }
+  uint32_t i_lblk() const { return at<8>().as_uint32(); }
+  bool has_i_len() const { return at<9>().valid(); }
+  uint32_t i_len() const { return at<9>().as_uint32(); }
+  bool has_i_pblk() const { return at<10>().valid(); }
+  uint64_t i_pblk() const { return at<10>().as_uint64(); }
+};
+
+class Ext4ExtConvertToInitializedFastpathFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtConvertToInitializedFastpathFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kMLblkFieldNumber = 3,
+    kMLenFieldNumber = 4,
+    kULblkFieldNumber = 5,
+    kULenFieldNumber = 6,
+    kUPblkFieldNumber = 7,
+    kILblkFieldNumber = 8,
+    kILenFieldNumber = 9,
+    kIPblkFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtConvertToInitializedFastpathFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_MLblk kMLblk{};
+  void set_m_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MLblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MLen =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_MLen kMLen{};
+  void set_m_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ULblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_ULblk kULblk{};
+  void set_u_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ULblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ULen =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_ULen kULen{};
+  void set_u_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ULen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UPblk =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_UPblk kUPblk{};
+  void set_u_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UPblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ILblk =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_ILblk kILblk{};
+  void set_i_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ILblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ILen =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_ILen kILen{};
+  void set_i_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ILen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IPblk =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedFastpathFtraceEvent>;
+
+  static constexpr FieldMetadata_IPblk kIPblk{};
+  void set_i_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IPblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4ExtConvertToInitializedEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4ExtConvertToInitializedEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4ExtConvertToInitializedEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4ExtConvertToInitializedEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_m_lblk() const { return at<3>().valid(); }
+  uint32_t m_lblk() const { return at<3>().as_uint32(); }
+  bool has_m_len() const { return at<4>().valid(); }
+  uint32_t m_len() const { return at<4>().as_uint32(); }
+  bool has_u_lblk() const { return at<5>().valid(); }
+  uint32_t u_lblk() const { return at<5>().as_uint32(); }
+  bool has_u_len() const { return at<6>().valid(); }
+  uint32_t u_len() const { return at<6>().as_uint32(); }
+  bool has_u_pblk() const { return at<7>().valid(); }
+  uint64_t u_pblk() const { return at<7>().as_uint64(); }
+};
+
+class Ext4ExtConvertToInitializedEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4ExtConvertToInitializedEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kMLblkFieldNumber = 3,
+    kMLenFieldNumber = 4,
+    kULblkFieldNumber = 5,
+    kULenFieldNumber = 6,
+    kUPblkFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4ExtConvertToInitializedEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MLblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_MLblk kMLblk{};
+  void set_m_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MLblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MLen =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_MLen kMLen{};
+  void set_m_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ULblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_ULblk kULblk{};
+  void set_u_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ULblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ULen =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_ULen kULen{};
+  void set_u_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ULen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UPblk =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4ExtConvertToInitializedEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_UPblk kUPblk{};
+  void set_u_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UPblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EvictInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EvictInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EvictInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EvictInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nlink() const { return at<3>().valid(); }
+  int32_t nlink() const { return at<3>().as_int32(); }
+};
+
+class Ext4EvictInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EvictInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNlinkFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EvictInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nlink =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nlink kNlink{};
+  void set_nlink(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nlink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsShrinkScanExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsShrinkScanExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsShrinkScanExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsShrinkScanExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_nr_shrunk() const { return at<2>().valid(); }
+  int32_t nr_shrunk() const { return at<2>().as_int32(); }
+  bool has_cache_cnt() const { return at<3>().valid(); }
+  int32_t cache_cnt() const { return at<3>().as_int32(); }
+};
+
+class Ext4EsShrinkScanExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsShrinkScanExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNrShrunkFieldNumber = 2,
+    kCacheCntFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsShrinkScanExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkScanExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrShrunk =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkScanExitFtraceEvent>;
+
+  static constexpr FieldMetadata_NrShrunk kNrShrunk{};
+  void set_nr_shrunk(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrShrunk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CacheCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkScanExitFtraceEvent>;
+
+  static constexpr FieldMetadata_CacheCnt kCacheCnt{};
+  void set_cache_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CacheCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsShrinkScanEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsShrinkScanEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsShrinkScanEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsShrinkScanEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_nr_to_scan() const { return at<2>().valid(); }
+  int32_t nr_to_scan() const { return at<2>().as_int32(); }
+  bool has_cache_cnt() const { return at<3>().valid(); }
+  int32_t cache_cnt() const { return at<3>().as_int32(); }
+};
+
+class Ext4EsShrinkScanEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsShrinkScanEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNrToScanFieldNumber = 2,
+    kCacheCntFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsShrinkScanEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkScanEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrToScan =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkScanEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_NrToScan kNrToScan{};
+  void set_nr_to_scan(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrToScan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CacheCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkScanEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_CacheCnt kCacheCnt{};
+  void set_cache_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CacheCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsShrinkCountFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsShrinkCountFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsShrinkCountFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsShrinkCountFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_nr_to_scan() const { return at<2>().valid(); }
+  int32_t nr_to_scan() const { return at<2>().as_int32(); }
+  bool has_cache_cnt() const { return at<3>().valid(); }
+  int32_t cache_cnt() const { return at<3>().as_int32(); }
+};
+
+class Ext4EsShrinkCountFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsShrinkCountFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNrToScanFieldNumber = 2,
+    kCacheCntFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsShrinkCountFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkCountFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrToScan =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkCountFtraceEvent>;
+
+  static constexpr FieldMetadata_NrToScan kNrToScan{};
+  void set_nr_to_scan(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrToScan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CacheCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkCountFtraceEvent>;
+
+  static constexpr FieldMetadata_CacheCnt kCacheCnt{};
+  void set_cache_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CacheCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsShrinkFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsShrinkFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsShrinkFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsShrinkFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_nr_shrunk() const { return at<2>().valid(); }
+  int32_t nr_shrunk() const { return at<2>().as_int32(); }
+  bool has_scan_time() const { return at<3>().valid(); }
+  uint64_t scan_time() const { return at<3>().as_uint64(); }
+  bool has_nr_skipped() const { return at<4>().valid(); }
+  int32_t nr_skipped() const { return at<4>().as_int32(); }
+  bool has_retried() const { return at<5>().valid(); }
+  int32_t retried() const { return at<5>().as_int32(); }
+};
+
+class Ext4EsShrinkFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsShrinkFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNrShrunkFieldNumber = 2,
+    kScanTimeFieldNumber = 3,
+    kNrSkippedFieldNumber = 4,
+    kRetriedFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsShrinkFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrShrunk =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_NrShrunk kNrShrunk{};
+  void set_nr_shrunk(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrShrunk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ScanTime =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_ScanTime kScanTime{};
+  void set_scan_time(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScanTime::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrSkipped =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_NrSkipped kNrSkipped{};
+  void set_nr_skipped(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrSkipped::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Retried =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_Retried kRetried{};
+  void set_retried(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Retried::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsRemoveExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsRemoveExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsRemoveExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsRemoveExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  int64_t lblk() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+};
+
+class Ext4EsRemoveExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsRemoveExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsRemoveExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsRemoveExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsRemoveExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4EsRemoveExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4EsRemoveExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsLookupExtentExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsLookupExtentExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsLookupExtentExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsLookupExtentExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_pblk() const { return at<5>().valid(); }
+  uint64_t pblk() const { return at<5>().as_uint64(); }
+  bool has_status() const { return at<6>().valid(); }
+  uint64_t status() const { return at<6>().as_uint64(); }
+  bool has_found() const { return at<7>().valid(); }
+  int32_t found() const { return at<7>().as_int32(); }
+};
+
+class Ext4EsLookupExtentExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsLookupExtentExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kPblkFieldNumber = 5,
+    kStatusFieldNumber = 6,
+    kFoundFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsLookupExtentExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Found =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4EsLookupExtentExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Found kFound{};
+  void set_found(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Found::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsLookupExtentEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsLookupExtentEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsLookupExtentEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsLookupExtentEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+};
+
+class Ext4EsLookupExtentEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsLookupExtentEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsLookupExtentEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsLookupExtentEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsLookupExtentEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsInsertExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsInsertExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsInsertExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsInsertExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_pblk() const { return at<5>().valid(); }
+  uint64_t pblk() const { return at<5>().as_uint64(); }
+  bool has_status() const { return at<6>().valid(); }
+  uint64_t status() const { return at<6>().as_uint64(); }
+};
+
+class Ext4EsInsertExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsInsertExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kPblkFieldNumber = 5,
+    kStatusFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsInsertExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsInsertExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsFindDelayedExtentRangeExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsFindDelayedExtentRangeExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsFindDelayedExtentRangeExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsFindDelayedExtentRangeExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_pblk() const { return at<5>().valid(); }
+  uint64_t pblk() const { return at<5>().as_uint64(); }
+  bool has_status() const { return at<6>().valid(); }
+  uint64_t status() const { return at<6>().as_uint64(); }
+};
+
+class Ext4EsFindDelayedExtentRangeExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsFindDelayedExtentRangeExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kPblkFieldNumber = 5,
+    kStatusFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsFindDelayedExtentRangeExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsFindDelayedExtentRangeEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsFindDelayedExtentRangeEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsFindDelayedExtentRangeEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsFindDelayedExtentRangeEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+};
+
+class Ext4EsFindDelayedExtentRangeEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsFindDelayedExtentRangeEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsFindDelayedExtentRangeEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsFindDelayedExtentRangeEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsFindDelayedExtentRangeEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4EsCacheExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4EsCacheExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4EsCacheExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4EsCacheExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint32_t lblk() const { return at<3>().as_uint32(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_pblk() const { return at<5>().valid(); }
+  uint64_t pblk() const { return at<5>().as_uint64(); }
+  bool has_status() const { return at<6>().valid(); }
+  uint32_t status() const { return at<6>().as_uint32(); }
+};
+
+class Ext4EsCacheExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4EsCacheExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kPblkFieldNumber = 5,
+    kStatusFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4EsCacheExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pblk =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Pblk kPblk{};
+  void set_pblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4EsCacheExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DropInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DropInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DropInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DropInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_drop() const { return at<3>().valid(); }
+  int32_t drop() const { return at<3>().as_int32(); }
+};
+
+class Ext4DropInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DropInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kDropFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DropInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DropInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DropInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Drop =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DropInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Drop kDrop{};
+  void set_drop(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Drop::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DiscardPreallocationsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DiscardPreallocationsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DiscardPreallocationsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DiscardPreallocationsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_len() const { return at<3>().valid(); }
+  uint32_t len() const { return at<3>().as_uint32(); }
+  bool has_needed() const { return at<4>().valid(); }
+  uint32_t needed() const { return at<4>().as_uint32(); }
+};
+
+class Ext4DiscardPreallocationsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DiscardPreallocationsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLenFieldNumber = 3,
+    kNeededFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DiscardPreallocationsFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Needed =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DiscardPreallocationsFtraceEvent>;
+
+  static constexpr FieldMetadata_Needed kNeeded{};
+  void set_needed(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Needed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DiscardBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DiscardBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DiscardBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DiscardBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_blk() const { return at<2>().valid(); }
+  uint64_t blk() const { return at<2>().as_uint64(); }
+  bool has_count() const { return at<3>().valid(); }
+  uint64_t count() const { return at<3>().as_uint64(); }
+};
+
+class Ext4DiscardBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DiscardBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kBlkFieldNumber = 2,
+    kCountFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DiscardBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blk =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Blk kBlk{};
+  void set_blk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DiscardBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DirectIOExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DirectIOExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DirectIOExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DirectIOExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+  bool has_rw() const { return at<5>().valid(); }
+  int32_t rw() const { return at<5>().as_int32(); }
+  bool has_ret() const { return at<6>().valid(); }
+  int32_t ret() const { return at<6>().as_int32(); }
+};
+
+class Ext4DirectIOExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DirectIOExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kRwFieldNumber = 5,
+    kRetFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DirectIOExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rw =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Rw kRw{};
+  void set_rw(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rw::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DirectIOExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DirectIOEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DirectIOEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DirectIOEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DirectIOEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+  bool has_rw() const { return at<5>().valid(); }
+  int32_t rw() const { return at<5>().as_int32(); }
+};
+
+class Ext4DirectIOEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DirectIOEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kRwFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DirectIOEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rw =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DirectIOEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Rw kRw{};
+  void set_rw(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rw::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DaWritePagesExtentFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaWritePagesExtentFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaWritePagesExtentFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaWritePagesExtentFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_lblk() const { return at<3>().valid(); }
+  uint64_t lblk() const { return at<3>().as_uint64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class Ext4DaWritePagesExtentFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaWritePagesExtentFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kLblkFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaWritePagesExtentFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lblk =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Lblk kLblk{};
+  void set_lblk(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lblk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWritePagesExtentFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DaWritePagesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaWritePagesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaWritePagesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaWritePagesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_first_page() const { return at<3>().valid(); }
+  uint64_t first_page() const { return at<3>().as_uint64(); }
+  bool has_nr_to_write() const { return at<4>().valid(); }
+  int64_t nr_to_write() const { return at<4>().as_int64(); }
+  bool has_sync_mode() const { return at<5>().valid(); }
+  int32_t sync_mode() const { return at<5>().as_int32(); }
+  bool has_b_blocknr() const { return at<6>().valid(); }
+  uint64_t b_blocknr() const { return at<6>().as_uint64(); }
+  bool has_b_size() const { return at<7>().valid(); }
+  uint32_t b_size() const { return at<7>().as_uint32(); }
+  bool has_b_state() const { return at<8>().valid(); }
+  uint32_t b_state() const { return at<8>().as_uint32(); }
+  bool has_io_done() const { return at<9>().valid(); }
+  int32_t io_done() const { return at<9>().as_int32(); }
+  bool has_pages_written() const { return at<10>().valid(); }
+  int32_t pages_written() const { return at<10>().as_int32(); }
+};
+
+class Ext4DaWritePagesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaWritePagesFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kFirstPageFieldNumber = 3,
+    kNrToWriteFieldNumber = 4,
+    kSyncModeFieldNumber = 5,
+    kBBlocknrFieldNumber = 6,
+    kBSizeFieldNumber = 7,
+    kBStateFieldNumber = 8,
+    kIoDoneFieldNumber = 9,
+    kPagesWrittenFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaWritePagesFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FirstPage =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_FirstPage kFirstPage{};
+  void set_first_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FirstPage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrToWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_NrToWrite kNrToWrite{};
+  void set_nr_to_write(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrToWrite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SyncMode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_SyncMode kSyncMode{};
+  void set_sync_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SyncMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BBlocknr =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_BBlocknr kBBlocknr{};
+  void set_b_blocknr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BBlocknr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BSize =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_BSize kBSize{};
+  void set_b_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BState =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_BState kBState{};
+  void set_b_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IoDone =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_IoDone kIoDone{};
+  void set_io_done(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IoDone::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PagesWritten =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaWritePagesFtraceEvent>;
+
+  static constexpr FieldMetadata_PagesWritten kPagesWritten{};
+  void set_pages_written(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagesWritten::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DaUpdateReserveSpaceFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaUpdateReserveSpaceFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaUpdateReserveSpaceFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaUpdateReserveSpaceFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_i_blocks() const { return at<3>().valid(); }
+  uint64_t i_blocks() const { return at<3>().as_uint64(); }
+  bool has_used_blocks() const { return at<4>().valid(); }
+  int32_t used_blocks() const { return at<4>().as_int32(); }
+  bool has_reserved_data_blocks() const { return at<5>().valid(); }
+  int32_t reserved_data_blocks() const { return at<5>().as_int32(); }
+  bool has_reserved_meta_blocks() const { return at<6>().valid(); }
+  int32_t reserved_meta_blocks() const { return at<6>().as_int32(); }
+  bool has_allocated_meta_blocks() const { return at<7>().valid(); }
+  int32_t allocated_meta_blocks() const { return at<7>().as_int32(); }
+  bool has_quota_claim() const { return at<8>().valid(); }
+  int32_t quota_claim() const { return at<8>().as_int32(); }
+  bool has_mode() const { return at<9>().valid(); }
+  uint32_t mode() const { return at<9>().as_uint32(); }
+};
+
+class Ext4DaUpdateReserveSpaceFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaUpdateReserveSpaceFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIBlocksFieldNumber = 3,
+    kUsedBlocksFieldNumber = 4,
+    kReservedDataBlocksFieldNumber = 5,
+    kReservedMetaBlocksFieldNumber = 6,
+    kAllocatedMetaBlocksFieldNumber = 7,
+    kQuotaClaimFieldNumber = 8,
+    kModeFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaUpdateReserveSpaceFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_IBlocks kIBlocks{};
+  void set_i_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UsedBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_UsedBlocks kUsedBlocks{};
+  void set_used_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UsedBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReservedDataBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedDataBlocks kReservedDataBlocks{};
+  void set_reserved_data_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedDataBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReservedMetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedMetaBlocks kReservedMetaBlocks{};
+  void set_reserved_meta_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedMetaBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllocatedMetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_AllocatedMetaBlocks kAllocatedMetaBlocks{};
+  void set_allocated_meta_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocatedMetaBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_QuotaClaim =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_QuotaClaim kQuotaClaim{};
+  void set_quota_claim(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_QuotaClaim::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaUpdateReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DaReserveSpaceFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaReserveSpaceFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaReserveSpaceFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaReserveSpaceFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_i_blocks() const { return at<3>().valid(); }
+  uint64_t i_blocks() const { return at<3>().as_uint64(); }
+  bool has_reserved_data_blocks() const { return at<4>().valid(); }
+  int32_t reserved_data_blocks() const { return at<4>().as_int32(); }
+  bool has_reserved_meta_blocks() const { return at<5>().valid(); }
+  int32_t reserved_meta_blocks() const { return at<5>().as_int32(); }
+  bool has_mode() const { return at<6>().valid(); }
+  uint32_t mode() const { return at<6>().as_uint32(); }
+  bool has_md_needed() const { return at<7>().valid(); }
+  int32_t md_needed() const { return at<7>().as_int32(); }
+};
+
+class Ext4DaReserveSpaceFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaReserveSpaceFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIBlocksFieldNumber = 3,
+    kReservedDataBlocksFieldNumber = 4,
+    kReservedMetaBlocksFieldNumber = 5,
+    kModeFieldNumber = 6,
+    kMdNeededFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaReserveSpaceFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_IBlocks kIBlocks{};
+  void set_i_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReservedDataBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedDataBlocks kReservedDataBlocks{};
+  void set_reserved_data_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedDataBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReservedMetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedMetaBlocks kReservedMetaBlocks{};
+  void set_reserved_meta_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedMetaBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MdNeeded =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReserveSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_MdNeeded kMdNeeded{};
+  void set_md_needed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MdNeeded::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DaReleaseSpaceFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaReleaseSpaceFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaReleaseSpaceFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaReleaseSpaceFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_i_blocks() const { return at<3>().valid(); }
+  uint64_t i_blocks() const { return at<3>().as_uint64(); }
+  bool has_freed_blocks() const { return at<4>().valid(); }
+  int32_t freed_blocks() const { return at<4>().as_int32(); }
+  bool has_reserved_data_blocks() const { return at<5>().valid(); }
+  int32_t reserved_data_blocks() const { return at<5>().as_int32(); }
+  bool has_reserved_meta_blocks() const { return at<6>().valid(); }
+  int32_t reserved_meta_blocks() const { return at<6>().as_int32(); }
+  bool has_allocated_meta_blocks() const { return at<7>().valid(); }
+  int32_t allocated_meta_blocks() const { return at<7>().as_int32(); }
+  bool has_mode() const { return at<8>().valid(); }
+  uint32_t mode() const { return at<8>().as_uint32(); }
+};
+
+class Ext4DaReleaseSpaceFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaReleaseSpaceFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIBlocksFieldNumber = 3,
+    kFreedBlocksFieldNumber = 4,
+    kReservedDataBlocksFieldNumber = 5,
+    kReservedMetaBlocksFieldNumber = 6,
+    kAllocatedMetaBlocksFieldNumber = 7,
+    kModeFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaReleaseSpaceFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_IBlocks kIBlocks{};
+  void set_i_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FreedBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_FreedBlocks kFreedBlocks{};
+  void set_freed_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreedBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReservedDataBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedDataBlocks kReservedDataBlocks{};
+  void set_reserved_data_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedDataBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReservedMetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_ReservedMetaBlocks kReservedMetaBlocks{};
+  void set_reserved_meta_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReservedMetaBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllocatedMetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_AllocatedMetaBlocks kAllocatedMetaBlocks{};
+  void set_allocated_meta_blocks(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocatedMetaBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaReleaseSpaceFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4CollapseRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4CollapseRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4CollapseRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4CollapseRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_offset() const { return at<3>().valid(); }
+  int64_t offset() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  int64_t len() const { return at<4>().as_int64(); }
+};
+
+class Ext4CollapseRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4CollapseRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kOffsetFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4CollapseRangeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4CollapseRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4CollapseRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4CollapseRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4CollapseRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4BeginOrderedTruncateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4BeginOrderedTruncateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4BeginOrderedTruncateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4BeginOrderedTruncateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_new_size() const { return at<3>().valid(); }
+  int64_t new_size() const { return at<3>().as_int64(); }
+};
+
+class Ext4BeginOrderedTruncateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4BeginOrderedTruncateFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNewSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4BeginOrderedTruncateFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4BeginOrderedTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4BeginOrderedTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NewSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4BeginOrderedTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_NewSize kNewSize{};
+  void set_new_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4AllocateInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4AllocateInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4AllocateInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4AllocateInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_dir() const { return at<3>().valid(); }
+  uint64_t dir() const { return at<3>().as_uint64(); }
+  bool has_mode() const { return at<4>().valid(); }
+  uint32_t mode() const { return at<4>().as_uint32(); }
+};
+
+class Ext4AllocateInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4AllocateInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kDirFieldNumber = 3,
+    kModeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4AllocateInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dir =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dir kDir{};
+  void set_dir(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dir::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4AllocateBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4AllocateBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4AllocateBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4AllocateBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_block() const { return at<3>().valid(); }
+  uint64_t block() const { return at<3>().as_uint64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_logical() const { return at<5>().valid(); }
+  uint32_t logical() const { return at<5>().as_uint32(); }
+  bool has_lleft() const { return at<6>().valid(); }
+  uint32_t lleft() const { return at<6>().as_uint32(); }
+  bool has_lright() const { return at<7>().valid(); }
+  uint32_t lright() const { return at<7>().as_uint32(); }
+  bool has_goal() const { return at<8>().valid(); }
+  uint64_t goal() const { return at<8>().as_uint64(); }
+  bool has_pleft() const { return at<9>().valid(); }
+  uint64_t pleft() const { return at<9>().as_uint64(); }
+  bool has_pright() const { return at<10>().valid(); }
+  uint64_t pright() const { return at<10>().as_uint64(); }
+  bool has_flags() const { return at<11>().valid(); }
+  uint32_t flags() const { return at<11>().as_uint32(); }
+};
+
+class Ext4AllocateBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4AllocateBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kBlockFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kLogicalFieldNumber = 5,
+    kLleftFieldNumber = 6,
+    kLrightFieldNumber = 7,
+    kGoalFieldNumber = 8,
+    kPleftFieldNumber = 9,
+    kPrightFieldNumber = 10,
+    kFlagsFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4AllocateBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Block =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Block kBlock{};
+  void set_block(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Block::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Logical =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Logical kLogical{};
+  void set_logical(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Logical::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lleft =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Lleft kLleft{};
+  void set_lleft(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lleft::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lright =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Lright kLright{};
+  void set_lright(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lright::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Goal =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Goal kGoal{};
+  void set_goal(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Goal::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pleft =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Pleft kPleft{};
+  void set_pleft(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pleft::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pright =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Pright kPright{};
+  void set_pright(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pright::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocateBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4AllocDaBlocksFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4AllocDaBlocksFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4AllocDaBlocksFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4AllocDaBlocksFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_data_blocks() const { return at<3>().valid(); }
+  uint32_t data_blocks() const { return at<3>().as_uint32(); }
+  bool has_meta_blocks() const { return at<4>().valid(); }
+  uint32_t meta_blocks() const { return at<4>().as_uint32(); }
+};
+
+class Ext4AllocDaBlocksFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4AllocDaBlocksFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kDataBlocksFieldNumber = 3,
+    kMetaBlocksFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4AllocDaBlocksFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocDaBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4AllocDaBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocDaBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_DataBlocks kDataBlocks{};
+  void set_data_blocks(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MetaBlocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4AllocDaBlocksFtraceEvent>;
+
+  static constexpr FieldMetadata_MetaBlocks kMetaBlocks{};
+  void set_meta_blocks(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MetaBlocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4SyncFileExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4SyncFileExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4SyncFileExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4SyncFileExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class Ext4SyncFileExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4SyncFileExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4SyncFileExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4SyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4SyncFileEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4SyncFileEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4SyncFileEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4SyncFileEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_parent() const { return at<3>().valid(); }
+  uint64_t parent() const { return at<3>().as_uint64(); }
+  bool has_datasync() const { return at<4>().valid(); }
+  int32_t datasync() const { return at<4>().as_int32(); }
+};
+
+class Ext4SyncFileEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4SyncFileEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kParentFieldNumber = 3,
+    kDatasyncFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4SyncFileEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Parent =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4SyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Parent kParent{};
+  void set_parent(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Parent::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Datasync =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Ext4SyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Datasync kDatasync{};
+  void set_datasync(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Datasync::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DaWriteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaWriteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaWriteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaWriteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_copied() const { return at<5>().valid(); }
+  uint32_t copied() const { return at<5>().as_uint32(); }
+};
+
+class Ext4DaWriteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaWriteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kCopiedFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaWriteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Copied =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Copied kCopied{};
+  void set_copied(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Copied::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Ext4DaWriteBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Ext4DaWriteBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Ext4DaWriteBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Ext4DaWriteBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class Ext4DaWriteBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Ext4DaWriteBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Ext4DaWriteBeginFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Ext4DaWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/f2fs.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_F2FS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_F2FS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class F2fsIostatLatencyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/28, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsIostatLatencyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsIostatLatencyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsIostatLatencyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_d_rd_avg() const { return at<1>().valid(); }
+  uint32_t d_rd_avg() const { return at<1>().as_uint32(); }
+  bool has_d_rd_cnt() const { return at<2>().valid(); }
+  uint32_t d_rd_cnt() const { return at<2>().as_uint32(); }
+  bool has_d_rd_peak() const { return at<3>().valid(); }
+  uint32_t d_rd_peak() const { return at<3>().as_uint32(); }
+  bool has_d_wr_as_avg() const { return at<4>().valid(); }
+  uint32_t d_wr_as_avg() const { return at<4>().as_uint32(); }
+  bool has_d_wr_as_cnt() const { return at<5>().valid(); }
+  uint32_t d_wr_as_cnt() const { return at<5>().as_uint32(); }
+  bool has_d_wr_as_peak() const { return at<6>().valid(); }
+  uint32_t d_wr_as_peak() const { return at<6>().as_uint32(); }
+  bool has_d_wr_s_avg() const { return at<7>().valid(); }
+  uint32_t d_wr_s_avg() const { return at<7>().as_uint32(); }
+  bool has_d_wr_s_cnt() const { return at<8>().valid(); }
+  uint32_t d_wr_s_cnt() const { return at<8>().as_uint32(); }
+  bool has_d_wr_s_peak() const { return at<9>().valid(); }
+  uint32_t d_wr_s_peak() const { return at<9>().as_uint32(); }
+  bool has_dev() const { return at<10>().valid(); }
+  uint64_t dev() const { return at<10>().as_uint64(); }
+  bool has_m_rd_avg() const { return at<11>().valid(); }
+  uint32_t m_rd_avg() const { return at<11>().as_uint32(); }
+  bool has_m_rd_cnt() const { return at<12>().valid(); }
+  uint32_t m_rd_cnt() const { return at<12>().as_uint32(); }
+  bool has_m_rd_peak() const { return at<13>().valid(); }
+  uint32_t m_rd_peak() const { return at<13>().as_uint32(); }
+  bool has_m_wr_as_avg() const { return at<14>().valid(); }
+  uint32_t m_wr_as_avg() const { return at<14>().as_uint32(); }
+  bool has_m_wr_as_cnt() const { return at<15>().valid(); }
+  uint32_t m_wr_as_cnt() const { return at<15>().as_uint32(); }
+  bool has_m_wr_as_peak() const { return at<16>().valid(); }
+  uint32_t m_wr_as_peak() const { return at<16>().as_uint32(); }
+  bool has_m_wr_s_avg() const { return at<17>().valid(); }
+  uint32_t m_wr_s_avg() const { return at<17>().as_uint32(); }
+  bool has_m_wr_s_cnt() const { return at<18>().valid(); }
+  uint32_t m_wr_s_cnt() const { return at<18>().as_uint32(); }
+  bool has_m_wr_s_peak() const { return at<19>().valid(); }
+  uint32_t m_wr_s_peak() const { return at<19>().as_uint32(); }
+  bool has_n_rd_avg() const { return at<20>().valid(); }
+  uint32_t n_rd_avg() const { return at<20>().as_uint32(); }
+  bool has_n_rd_cnt() const { return at<21>().valid(); }
+  uint32_t n_rd_cnt() const { return at<21>().as_uint32(); }
+  bool has_n_rd_peak() const { return at<22>().valid(); }
+  uint32_t n_rd_peak() const { return at<22>().as_uint32(); }
+  bool has_n_wr_as_avg() const { return at<23>().valid(); }
+  uint32_t n_wr_as_avg() const { return at<23>().as_uint32(); }
+  bool has_n_wr_as_cnt() const { return at<24>().valid(); }
+  uint32_t n_wr_as_cnt() const { return at<24>().as_uint32(); }
+  bool has_n_wr_as_peak() const { return at<25>().valid(); }
+  uint32_t n_wr_as_peak() const { return at<25>().as_uint32(); }
+  bool has_n_wr_s_avg() const { return at<26>().valid(); }
+  uint32_t n_wr_s_avg() const { return at<26>().as_uint32(); }
+  bool has_n_wr_s_cnt() const { return at<27>().valid(); }
+  uint32_t n_wr_s_cnt() const { return at<27>().as_uint32(); }
+  bool has_n_wr_s_peak() const { return at<28>().valid(); }
+  uint32_t n_wr_s_peak() const { return at<28>().as_uint32(); }
+};
+
+class F2fsIostatLatencyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsIostatLatencyFtraceEvent_Decoder;
+  enum : int32_t {
+    kDRdAvgFieldNumber = 1,
+    kDRdCntFieldNumber = 2,
+    kDRdPeakFieldNumber = 3,
+    kDWrAsAvgFieldNumber = 4,
+    kDWrAsCntFieldNumber = 5,
+    kDWrAsPeakFieldNumber = 6,
+    kDWrSAvgFieldNumber = 7,
+    kDWrSCntFieldNumber = 8,
+    kDWrSPeakFieldNumber = 9,
+    kDevFieldNumber = 10,
+    kMRdAvgFieldNumber = 11,
+    kMRdCntFieldNumber = 12,
+    kMRdPeakFieldNumber = 13,
+    kMWrAsAvgFieldNumber = 14,
+    kMWrAsCntFieldNumber = 15,
+    kMWrAsPeakFieldNumber = 16,
+    kMWrSAvgFieldNumber = 17,
+    kMWrSCntFieldNumber = 18,
+    kMWrSPeakFieldNumber = 19,
+    kNRdAvgFieldNumber = 20,
+    kNRdCntFieldNumber = 21,
+    kNRdPeakFieldNumber = 22,
+    kNWrAsAvgFieldNumber = 23,
+    kNWrAsCntFieldNumber = 24,
+    kNWrAsPeakFieldNumber = 25,
+    kNWrSAvgFieldNumber = 26,
+    kNWrSCntFieldNumber = 27,
+    kNWrSPeakFieldNumber = 28,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsIostatLatencyFtraceEvent"; }
+
+
+  using FieldMetadata_DRdAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DRdAvg kDRdAvg{};
+  void set_d_rd_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DRdAvg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DRdCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DRdCnt kDRdCnt{};
+  void set_d_rd_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DRdCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DRdPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DRdPeak kDRdPeak{};
+  void set_d_rd_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DRdPeak::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DWrAsAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrAsAvg kDWrAsAvg{};
+  void set_d_wr_as_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrAsAvg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DWrAsCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrAsCnt kDWrAsCnt{};
+  void set_d_wr_as_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrAsCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DWrAsPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrAsPeak kDWrAsPeak{};
+  void set_d_wr_as_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrAsPeak::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DWrSAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrSAvg kDWrSAvg{};
+  void set_d_wr_s_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrSAvg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DWrSCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrSCnt kDWrSCnt{};
+  void set_d_wr_s_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrSCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DWrSPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_DWrSPeak kDWrSPeak{};
+  void set_d_wr_s_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DWrSPeak::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MRdAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MRdAvg kMRdAvg{};
+  void set_m_rd_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MRdAvg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MRdCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MRdCnt kMRdCnt{};
+  void set_m_rd_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MRdCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MRdPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MRdPeak kMRdPeak{};
+  void set_m_rd_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MRdPeak::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MWrAsAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrAsAvg kMWrAsAvg{};
+  void set_m_wr_as_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrAsAvg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MWrAsCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrAsCnt kMWrAsCnt{};
+  void set_m_wr_as_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrAsCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MWrAsPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrAsPeak kMWrAsPeak{};
+  void set_m_wr_as_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrAsPeak::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MWrSAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrSAvg kMWrSAvg{};
+  void set_m_wr_s_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrSAvg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MWrSCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrSCnt kMWrSCnt{};
+  void set_m_wr_s_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrSCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MWrSPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_MWrSPeak kMWrSPeak{};
+  void set_m_wr_s_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MWrSPeak::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NRdAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NRdAvg kNRdAvg{};
+  void set_n_rd_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NRdAvg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NRdCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NRdCnt kNRdCnt{};
+  void set_n_rd_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NRdCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NRdPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NRdPeak kNRdPeak{};
+  void set_n_rd_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NRdPeak::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NWrAsAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrAsAvg kNWrAsAvg{};
+  void set_n_wr_as_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrAsAvg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NWrAsCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrAsCnt kNWrAsCnt{};
+  void set_n_wr_as_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrAsCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NWrAsPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrAsPeak kNWrAsPeak{};
+  void set_n_wr_as_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrAsPeak::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NWrSAvg =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrSAvg kNWrSAvg{};
+  void set_n_wr_s_avg(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrSAvg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NWrSCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrSCnt kNWrSCnt{};
+  void set_n_wr_s_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrSCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NWrSPeak =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIostatLatencyFtraceEvent>;
+
+  static constexpr FieldMetadata_NWrSPeak kNWrSPeak{};
+  void set_n_wr_s_peak(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NWrSPeak::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsIostatFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/23, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsIostatFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsIostatFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsIostatFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_app_bio() const { return at<1>().valid(); }
+  uint64_t app_bio() const { return at<1>().as_uint64(); }
+  bool has_app_brio() const { return at<2>().valid(); }
+  uint64_t app_brio() const { return at<2>().as_uint64(); }
+  bool has_app_dio() const { return at<3>().valid(); }
+  uint64_t app_dio() const { return at<3>().as_uint64(); }
+  bool has_app_drio() const { return at<4>().valid(); }
+  uint64_t app_drio() const { return at<4>().as_uint64(); }
+  bool has_app_mio() const { return at<5>().valid(); }
+  uint64_t app_mio() const { return at<5>().as_uint64(); }
+  bool has_app_mrio() const { return at<6>().valid(); }
+  uint64_t app_mrio() const { return at<6>().as_uint64(); }
+  bool has_app_rio() const { return at<7>().valid(); }
+  uint64_t app_rio() const { return at<7>().as_uint64(); }
+  bool has_app_wio() const { return at<8>().valid(); }
+  uint64_t app_wio() const { return at<8>().as_uint64(); }
+  bool has_dev() const { return at<9>().valid(); }
+  uint64_t dev() const { return at<9>().as_uint64(); }
+  bool has_fs_cdrio() const { return at<10>().valid(); }
+  uint64_t fs_cdrio() const { return at<10>().as_uint64(); }
+  bool has_fs_cp_dio() const { return at<11>().valid(); }
+  uint64_t fs_cp_dio() const { return at<11>().as_uint64(); }
+  bool has_fs_cp_mio() const { return at<12>().valid(); }
+  uint64_t fs_cp_mio() const { return at<12>().as_uint64(); }
+  bool has_fs_cp_nio() const { return at<13>().valid(); }
+  uint64_t fs_cp_nio() const { return at<13>().as_uint64(); }
+  bool has_fs_dio() const { return at<14>().valid(); }
+  uint64_t fs_dio() const { return at<14>().as_uint64(); }
+  bool has_fs_discard() const { return at<15>().valid(); }
+  uint64_t fs_discard() const { return at<15>().as_uint64(); }
+  bool has_fs_drio() const { return at<16>().valid(); }
+  uint64_t fs_drio() const { return at<16>().as_uint64(); }
+  bool has_fs_gc_dio() const { return at<17>().valid(); }
+  uint64_t fs_gc_dio() const { return at<17>().as_uint64(); }
+  bool has_fs_gc_nio() const { return at<18>().valid(); }
+  uint64_t fs_gc_nio() const { return at<18>().as_uint64(); }
+  bool has_fs_gdrio() const { return at<19>().valid(); }
+  uint64_t fs_gdrio() const { return at<19>().as_uint64(); }
+  bool has_fs_mio() const { return at<20>().valid(); }
+  uint64_t fs_mio() const { return at<20>().as_uint64(); }
+  bool has_fs_mrio() const { return at<21>().valid(); }
+  uint64_t fs_mrio() const { return at<21>().as_uint64(); }
+  bool has_fs_nio() const { return at<22>().valid(); }
+  uint64_t fs_nio() const { return at<22>().as_uint64(); }
+  bool has_fs_nrio() const { return at<23>().valid(); }
+  uint64_t fs_nrio() const { return at<23>().as_uint64(); }
+};
+
+class F2fsIostatFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsIostatFtraceEvent_Decoder;
+  enum : int32_t {
+    kAppBioFieldNumber = 1,
+    kAppBrioFieldNumber = 2,
+    kAppDioFieldNumber = 3,
+    kAppDrioFieldNumber = 4,
+    kAppMioFieldNumber = 5,
+    kAppMrioFieldNumber = 6,
+    kAppRioFieldNumber = 7,
+    kAppWioFieldNumber = 8,
+    kDevFieldNumber = 9,
+    kFsCdrioFieldNumber = 10,
+    kFsCpDioFieldNumber = 11,
+    kFsCpMioFieldNumber = 12,
+    kFsCpNioFieldNumber = 13,
+    kFsDioFieldNumber = 14,
+    kFsDiscardFieldNumber = 15,
+    kFsDrioFieldNumber = 16,
+    kFsGcDioFieldNumber = 17,
+    kFsGcNioFieldNumber = 18,
+    kFsGdrioFieldNumber = 19,
+    kFsMioFieldNumber = 20,
+    kFsMrioFieldNumber = 21,
+    kFsNioFieldNumber = 22,
+    kFsNrioFieldNumber = 23,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsIostatFtraceEvent"; }
+
+
+  using FieldMetadata_AppBio =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppBio kAppBio{};
+  void set_app_bio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppBio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AppBrio =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppBrio kAppBrio{};
+  void set_app_brio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppBrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AppDio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppDio kAppDio{};
+  void set_app_dio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppDio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AppDrio =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppDrio kAppDrio{};
+  void set_app_drio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppDrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AppMio =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppMio kAppMio{};
+  void set_app_mio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppMio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AppMrio =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppMrio kAppMrio{};
+  void set_app_mrio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppMrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AppRio =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppRio kAppRio{};
+  void set_app_rio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppRio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AppWio =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_AppWio kAppWio{};
+  void set_app_wio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AppWio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsCdrio =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsCdrio kFsCdrio{};
+  void set_fs_cdrio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsCdrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsCpDio =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsCpDio kFsCpDio{};
+  void set_fs_cp_dio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsCpDio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsCpMio =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsCpMio kFsCpMio{};
+  void set_fs_cp_mio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsCpMio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsCpNio =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsCpNio kFsCpNio{};
+  void set_fs_cp_nio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsCpNio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsDio =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsDio kFsDio{};
+  void set_fs_dio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsDio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsDiscard =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsDiscard kFsDiscard{};
+  void set_fs_discard(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsDiscard::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsDrio =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsDrio kFsDrio{};
+  void set_fs_drio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsDrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsGcDio =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsGcDio kFsGcDio{};
+  void set_fs_gc_dio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsGcDio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsGcNio =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsGcNio kFsGcNio{};
+  void set_fs_gc_nio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsGcNio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsGdrio =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsGdrio kFsGdrio{};
+  void set_fs_gdrio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsGdrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsMio =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsMio kFsMio{};
+  void set_fs_mio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsMio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsMrio =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsMrio kFsMrio{};
+  void set_fs_mrio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsMrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsNio =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsNio kFsNio{};
+  void set_fs_nio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsNio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FsNrio =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIostatFtraceEvent>;
+
+  static constexpr FieldMetadata_FsNrio kFsNrio{};
+  void set_fs_nrio(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FsNrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsWriteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsWriteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsWriteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsWriteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_copied() const { return at<5>().valid(); }
+  uint32_t copied() const { return at<5>().as_uint32(); }
+};
+
+class F2fsWriteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsWriteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kCopiedFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsWriteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Copied =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsWriteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Copied kCopied{};
+  void set_copied(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Copied::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsWriteCheckpointFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsWriteCheckpointFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsWriteCheckpointFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsWriteCheckpointFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_is_umount() const { return at<2>().valid(); }
+  uint32_t is_umount() const { return at<2>().as_uint32(); }
+  bool has_msg() const { return at<3>().valid(); }
+  ::protozero::ConstChars msg() const { return at<3>().as_string(); }
+  bool has_reason() const { return at<4>().valid(); }
+  int32_t reason() const { return at<4>().as_int32(); }
+};
+
+class F2fsWriteCheckpointFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsWriteCheckpointFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kIsUmountFieldNumber = 2,
+    kMsgFieldNumber = 3,
+    kReasonFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsWriteCheckpointFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteCheckpointFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsUmount =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsWriteCheckpointFtraceEvent>;
+
+  static constexpr FieldMetadata_IsUmount kIsUmount{};
+  void set_is_umount(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsUmount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Msg =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      F2fsWriteCheckpointFtraceEvent>;
+
+  static constexpr FieldMetadata_Msg kMsg{};
+  void set_msg(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Msg::kFieldId, data, size);
+  }
+  void set_msg(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Msg::kFieldId, chars.data, chars.size);
+  }
+  void set_msg(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Msg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsWriteCheckpointFtraceEvent>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsWriteBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsWriteBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsWriteBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsWriteBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pos() const { return at<3>().valid(); }
+  int64_t pos() const { return at<3>().as_int64(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint32_t len() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+};
+
+class F2fsWriteBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsWriteBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPosFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsWriteBeginFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pos =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Pos kPos{};
+  void set_pos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsWriteBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsVmPageMkwriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsVmPageMkwriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsVmPageMkwriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsVmPageMkwriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_type() const { return at<3>().valid(); }
+  int32_t type() const { return at<3>().as_int32(); }
+  bool has_dir() const { return at<4>().valid(); }
+  int32_t dir() const { return at<4>().as_int32(); }
+  bool has_index() const { return at<5>().valid(); }
+  uint64_t index() const { return at<5>().as_uint64(); }
+  bool has_dirty() const { return at<6>().valid(); }
+  int32_t dirty() const { return at<6>().as_int32(); }
+  bool has_uptodate() const { return at<7>().valid(); }
+  int32_t uptodate() const { return at<7>().as_int32(); }
+};
+
+class F2fsVmPageMkwriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsVmPageMkwriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kDirFieldNumber = 4,
+    kIndexFieldNumber = 5,
+    kDirtyFieldNumber = 6,
+    kUptodateFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsVmPageMkwriteFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dir =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Dir kDir{};
+  void set_dir(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dir::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dirty =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Dirty kDirty{};
+  void set_dirty(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dirty::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uptodate =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsVmPageMkwriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Uptodate kUptodate{};
+  void set_uptodate(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uptodate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsUnlinkExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsUnlinkExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsUnlinkExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsUnlinkExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsUnlinkExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsUnlinkExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsUnlinkExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsUnlinkExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsUnlinkEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsUnlinkEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsUnlinkEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsUnlinkEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  int64_t size() const { return at<3>().as_int64(); }
+  bool has_blocks() const { return at<4>().valid(); }
+  uint64_t blocks() const { return at<4>().as_uint64(); }
+  bool has_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars name() const { return at<5>().as_string(); }
+};
+
+class F2fsUnlinkEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsUnlinkEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kSizeFieldNumber = 3,
+    kBlocksFieldNumber = 4,
+    kNameFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsUnlinkEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      F2fsUnlinkEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsTruncatePartialNodesFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncatePartialNodesFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncatePartialNodesFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncatePartialNodesFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nid() const { return at<3>().valid(); }
+  uint32_t nid() const { return at<3>().as_uint32(); }
+  bool has_depth() const { return at<4>().valid(); }
+  int32_t depth() const { return at<4>().as_int32(); }
+  bool has_err() const { return at<5>().valid(); }
+  int32_t err() const { return at<5>().as_int32(); }
+};
+
+class F2fsTruncatePartialNodesFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncatePartialNodesFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNidFieldNumber = 3,
+    kDepthFieldNumber = 4,
+    kErrFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncatePartialNodesFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Depth =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  static constexpr FieldMetadata_Depth kDepth{};
+  void set_depth(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Depth::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Err =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncatePartialNodesFtraceEvent>;
+
+  static constexpr FieldMetadata_Err kErr{};
+  void set_err(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Err::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsTruncateNodesExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateNodesExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateNodesExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateNodesExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsTruncateNodesExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateNodesExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateNodesExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodesExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodesExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncateNodesExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsTruncateNodesEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateNodesEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateNodesEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateNodesEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nid() const { return at<3>().valid(); }
+  uint32_t nid() const { return at<3>().as_uint32(); }
+  bool has_blk_addr() const { return at<4>().valid(); }
+  uint32_t blk_addr() const { return at<4>().as_uint32(); }
+};
+
+class F2fsTruncateNodesEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateNodesEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNidFieldNumber = 3,
+    kBlkAddrFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateNodesEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodesEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodesEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateNodesEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BlkAddr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateNodesEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_BlkAddr kBlkAddr{};
+  void set_blk_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlkAddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsTruncateNodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateNodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateNodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateNodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nid() const { return at<3>().valid(); }
+  uint32_t nid() const { return at<3>().as_uint32(); }
+  bool has_blk_addr() const { return at<4>().valid(); }
+  uint32_t blk_addr() const { return at<4>().as_uint32(); }
+};
+
+class F2fsTruncateNodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateNodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNidFieldNumber = 3,
+    kBlkAddrFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateNodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BlkAddr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_BlkAddr kBlkAddr{};
+  void set_blk_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlkAddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsTruncateInodeBlocksExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateInodeBlocksExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateInodeBlocksExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateInodeBlocksExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsTruncateInodeBlocksExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateInodeBlocksExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateInodeBlocksExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncateInodeBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsTruncateInodeBlocksEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateInodeBlocksEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateInodeBlocksEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateInodeBlocksEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  int64_t size() const { return at<3>().as_int64(); }
+  bool has_blocks() const { return at<4>().valid(); }
+  uint64_t blocks() const { return at<4>().as_uint64(); }
+  bool has_from() const { return at<5>().valid(); }
+  uint64_t from() const { return at<5>().as_uint64(); }
+};
+
+class F2fsTruncateInodeBlocksEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateInodeBlocksEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kSizeFieldNumber = 3,
+    kBlocksFieldNumber = 4,
+    kFromFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateInodeBlocksEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_From =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateInodeBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_From kFrom{};
+  void set_from(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_From::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsTruncateDataBlocksRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateDataBlocksRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateDataBlocksRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateDataBlocksRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_nid() const { return at<3>().valid(); }
+  uint32_t nid() const { return at<3>().as_uint32(); }
+  bool has_ofs() const { return at<4>().valid(); }
+  uint32_t ofs() const { return at<4>().as_uint32(); }
+  bool has_free() const { return at<5>().valid(); }
+  int32_t free() const { return at<5>().as_int32(); }
+};
+
+class F2fsTruncateDataBlocksRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateDataBlocksRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNidFieldNumber = 3,
+    kOfsFieldNumber = 4,
+    kFreeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateDataBlocksRangeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ofs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ofs kOfs{};
+  void set_ofs(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ofs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Free =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncateDataBlocksRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Free kFree{};
+  void set_free(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Free::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsTruncateBlocksExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateBlocksExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateBlocksExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateBlocksExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsTruncateBlocksExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateBlocksExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateBlocksExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsTruncateBlocksExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsTruncateBlocksEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateBlocksEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateBlocksEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateBlocksEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_size() const { return at<3>().valid(); }
+  int64_t size() const { return at<3>().as_int64(); }
+  bool has_blocks() const { return at<4>().valid(); }
+  uint64_t blocks() const { return at<4>().as_uint64(); }
+  bool has_from() const { return at<5>().valid(); }
+  uint64_t from() const { return at<5>().as_uint64(); }
+};
+
+class F2fsTruncateBlocksEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateBlocksEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kSizeFieldNumber = 3,
+    kBlocksFieldNumber = 4,
+    kFromFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateBlocksEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_From =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateBlocksEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_From kFrom{};
+  void set_from(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_From::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsTruncateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsTruncateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsTruncateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsTruncateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pino() const { return at<3>().valid(); }
+  uint64_t pino() const { return at<3>().as_uint64(); }
+  bool has_mode() const { return at<4>().valid(); }
+  uint32_t mode() const { return at<4>().as_uint32(); }
+  bool has_size() const { return at<5>().valid(); }
+  int64_t size() const { return at<5>().as_int64(); }
+  bool has_nlink() const { return at<6>().valid(); }
+  uint32_t nlink() const { return at<6>().as_uint32(); }
+  bool has_blocks() const { return at<7>().valid(); }
+  uint64_t blocks() const { return at<7>().as_uint64(); }
+  bool has_advise() const { return at<8>().valid(); }
+  uint32_t advise() const { return at<8>().as_uint32(); }
+};
+
+class F2fsTruncateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsTruncateFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPinoFieldNumber = 3,
+    kModeFieldNumber = 4,
+    kSizeFieldNumber = 5,
+    kNlinkFieldNumber = 6,
+    kBlocksFieldNumber = 7,
+    kAdviseFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsTruncateFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pino =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Pino kPino{};
+  void set_pino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nlink =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Nlink kNlink{};
+  void set_nlink(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nlink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Advise =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsTruncateFtraceEvent>;
+
+  static constexpr FieldMetadata_Advise kAdvise{};
+  void set_advise(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Advise::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsSyncFsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsSyncFsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsSyncFsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsSyncFsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_dirty() const { return at<2>().valid(); }
+  int32_t dirty() const { return at<2>().as_int32(); }
+  bool has_wait() const { return at<3>().valid(); }
+  int32_t wait() const { return at<3>().as_int32(); }
+};
+
+class F2fsSyncFsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSyncFsFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kDirtyFieldNumber = 2,
+    kWaitFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsSyncFsFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dirty =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSyncFsFtraceEvent>;
+
+  static constexpr FieldMetadata_Dirty kDirty{};
+  void set_dirty(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dirty::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Wait =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSyncFsFtraceEvent>;
+
+  static constexpr FieldMetadata_Wait kWait{};
+  void set_wait(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Wait::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsSyncFileExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsSyncFileExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsSyncFileExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsSyncFileExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_need_cp() const { return at<3>().valid(); }
+  uint32_t need_cp() const { return at<3>().as_uint32(); }
+  bool has_datasync() const { return at<4>().valid(); }
+  int32_t datasync() const { return at<4>().as_int32(); }
+  bool has_ret() const { return at<5>().valid(); }
+  int32_t ret() const { return at<5>().as_int32(); }
+  bool has_cp_reason() const { return at<6>().valid(); }
+  int32_t cp_reason() const { return at<6>().as_int32(); }
+};
+
+class F2fsSyncFileExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSyncFileExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kNeedCpFieldNumber = 3,
+    kDatasyncFieldNumber = 4,
+    kRetFieldNumber = 5,
+    kCpReasonFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsSyncFileExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NeedCp =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_NeedCp kNeedCp{};
+  void set_need_cp(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedCp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Datasync =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Datasync kDatasync{};
+  void set_datasync(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Datasync::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpReason =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSyncFileExitFtraceEvent>;
+
+  static constexpr FieldMetadata_CpReason kCpReason{};
+  void set_cp_reason(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpReason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsSyncFileEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsSyncFileEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsSyncFileEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsSyncFileEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pino() const { return at<3>().valid(); }
+  uint64_t pino() const { return at<3>().as_uint64(); }
+  bool has_mode() const { return at<4>().valid(); }
+  uint32_t mode() const { return at<4>().as_uint32(); }
+  bool has_size() const { return at<5>().valid(); }
+  int64_t size() const { return at<5>().as_int64(); }
+  bool has_nlink() const { return at<6>().valid(); }
+  uint32_t nlink() const { return at<6>().as_uint32(); }
+  bool has_blocks() const { return at<7>().valid(); }
+  uint64_t blocks() const { return at<7>().as_uint64(); }
+  bool has_advise() const { return at<8>().valid(); }
+  uint32_t advise() const { return at<8>().as_uint32(); }
+};
+
+class F2fsSyncFileEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSyncFileEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPinoFieldNumber = 3,
+    kModeFieldNumber = 4,
+    kSizeFieldNumber = 5,
+    kNlinkFieldNumber = 6,
+    kBlocksFieldNumber = 7,
+    kAdviseFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsSyncFileEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pino =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Pino kPino{};
+  void set_pino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nlink =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Nlink kNlink{};
+  void set_nlink(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nlink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Advise =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsSyncFileEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Advise kAdvise{};
+  void set_advise(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Advise::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsSubmitWritePageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsSubmitWritePageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsSubmitWritePageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsSubmitWritePageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_type() const { return at<3>().valid(); }
+  int32_t type() const { return at<3>().as_int32(); }
+  bool has_index() const { return at<4>().valid(); }
+  uint64_t index() const { return at<4>().as_uint64(); }
+  bool has_block() const { return at<5>().valid(); }
+  uint32_t block() const { return at<5>().as_uint32(); }
+};
+
+class F2fsSubmitWritePageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSubmitWritePageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kIndexFieldNumber = 4,
+    kBlockFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsSubmitWritePageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Block =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsSubmitWritePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Block kBlock{};
+  void set_block(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Block::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsSetPageDirtyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsSetPageDirtyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsSetPageDirtyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsSetPageDirtyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_type() const { return at<3>().valid(); }
+  int32_t type() const { return at<3>().as_int32(); }
+  bool has_dir() const { return at<4>().valid(); }
+  int32_t dir() const { return at<4>().as_int32(); }
+  bool has_index() const { return at<5>().valid(); }
+  uint64_t index() const { return at<5>().as_uint64(); }
+  bool has_dirty() const { return at<6>().valid(); }
+  int32_t dirty() const { return at<6>().as_int32(); }
+  bool has_uptodate() const { return at<7>().valid(); }
+  int32_t uptodate() const { return at<7>().as_int32(); }
+};
+
+class F2fsSetPageDirtyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsSetPageDirtyFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kDirFieldNumber = 4,
+    kIndexFieldNumber = 5,
+    kDirtyFieldNumber = 6,
+    kUptodateFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsSetPageDirtyFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dir =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Dir kDir{};
+  void set_dir(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dir::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dirty =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Dirty kDirty{};
+  void set_dirty(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dirty::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uptodate =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsSetPageDirtyFtraceEvent>;
+
+  static constexpr FieldMetadata_Uptodate kUptodate{};
+  void set_uptodate(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uptodate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsReserveNewBlockFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsReserveNewBlockFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsReserveNewBlockFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsReserveNewBlockFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_nid() const { return at<2>().valid(); }
+  uint32_t nid() const { return at<2>().as_uint32(); }
+  bool has_ofs_in_node() const { return at<3>().valid(); }
+  uint32_t ofs_in_node() const { return at<3>().as_uint32(); }
+};
+
+class F2fsReserveNewBlockFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsReserveNewBlockFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kNidFieldNumber = 2,
+    kOfsInNodeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsReserveNewBlockFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReserveNewBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsReserveNewBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OfsInNode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsReserveNewBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_OfsInNode kOfsInNode{};
+  void set_ofs_in_node(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OfsInNode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsReadpageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsReadpageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsReadpageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsReadpageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+  bool has_blkaddr() const { return at<4>().valid(); }
+  uint64_t blkaddr() const { return at<4>().as_uint64(); }
+  bool has_type() const { return at<5>().valid(); }
+  int32_t type() const { return at<5>().as_int32(); }
+  bool has_dir() const { return at<6>().valid(); }
+  int32_t dir() const { return at<6>().as_int32(); }
+  bool has_dirty() const { return at<7>().valid(); }
+  int32_t dirty() const { return at<7>().as_int32(); }
+  bool has_uptodate() const { return at<8>().valid(); }
+  int32_t uptodate() const { return at<8>().as_int32(); }
+};
+
+class F2fsReadpageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsReadpageFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kBlkaddrFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kDirFieldNumber = 6,
+    kDirtyFieldNumber = 7,
+    kUptodateFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsReadpageFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blkaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Blkaddr kBlkaddr{};
+  void set_blkaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blkaddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dir =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dir kDir{};
+  void set_dir(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dir::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dirty =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Dirty kDirty{};
+  void set_dirty(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dirty::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uptodate =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsReadpageFtraceEvent>;
+
+  static constexpr FieldMetadata_Uptodate kUptodate{};
+  void set_uptodate(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uptodate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsNewInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsNewInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsNewInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsNewInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsNewInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsNewInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsNewInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsNewInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsNewInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsNewInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsIgetExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsIgetExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsIgetExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsIgetExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class F2fsIgetExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsIgetExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsIgetExitFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsIgetExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsIgetFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsIgetFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsIgetFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsIgetFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pino() const { return at<3>().valid(); }
+  uint64_t pino() const { return at<3>().as_uint64(); }
+  bool has_mode() const { return at<4>().valid(); }
+  uint32_t mode() const { return at<4>().as_uint32(); }
+  bool has_size() const { return at<5>().valid(); }
+  int64_t size() const { return at<5>().as_int64(); }
+  bool has_nlink() const { return at<6>().valid(); }
+  uint32_t nlink() const { return at<6>().as_uint32(); }
+  bool has_blocks() const { return at<7>().valid(); }
+  uint64_t blocks() const { return at<7>().as_uint64(); }
+  bool has_advise() const { return at<8>().valid(); }
+  uint32_t advise() const { return at<8>().as_uint32(); }
+};
+
+class F2fsIgetFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsIgetFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPinoFieldNumber = 3,
+    kModeFieldNumber = 4,
+    kSizeFieldNumber = 5,
+    kNlinkFieldNumber = 6,
+    kBlocksFieldNumber = 7,
+    kAdviseFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsIgetFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pino =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Pino kPino{};
+  void set_pino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nlink =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Nlink kNlink{};
+  void set_nlink(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nlink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Advise =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsIgetFtraceEvent>;
+
+  static constexpr FieldMetadata_Advise kAdvise{};
+  void set_advise(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Advise::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsGetVictimFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsGetVictimFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsGetVictimFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsGetVictimFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_type() const { return at<2>().valid(); }
+  int32_t type() const { return at<2>().as_int32(); }
+  bool has_gc_type() const { return at<3>().valid(); }
+  int32_t gc_type() const { return at<3>().as_int32(); }
+  bool has_alloc_mode() const { return at<4>().valid(); }
+  int32_t alloc_mode() const { return at<4>().as_int32(); }
+  bool has_gc_mode() const { return at<5>().valid(); }
+  int32_t gc_mode() const { return at<5>().as_int32(); }
+  bool has_victim() const { return at<6>().valid(); }
+  uint32_t victim() const { return at<6>().as_uint32(); }
+  bool has_ofs_unit() const { return at<7>().valid(); }
+  uint32_t ofs_unit() const { return at<7>().as_uint32(); }
+  bool has_pre_victim() const { return at<8>().valid(); }
+  uint32_t pre_victim() const { return at<8>().as_uint32(); }
+  bool has_prefree() const { return at<9>().valid(); }
+  uint32_t prefree() const { return at<9>().as_uint32(); }
+  bool has_free() const { return at<10>().valid(); }
+  uint32_t free() const { return at<10>().as_uint32(); }
+  bool has_cost() const { return at<11>().valid(); }
+  uint32_t cost() const { return at<11>().as_uint32(); }
+};
+
+class F2fsGetVictimFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsGetVictimFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kTypeFieldNumber = 2,
+    kGcTypeFieldNumber = 3,
+    kAllocModeFieldNumber = 4,
+    kGcModeFieldNumber = 5,
+    kVictimFieldNumber = 6,
+    kOfsUnitFieldNumber = 7,
+    kPreVictimFieldNumber = 8,
+    kPrefreeFieldNumber = 9,
+    kFreeFieldNumber = 10,
+    kCostFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsGetVictimFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GcType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_GcType kGcType{};
+  void set_gc_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GcType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllocMode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_AllocMode kAllocMode{};
+  void set_alloc_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GcMode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_GcMode kGcMode{};
+  void set_gc_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GcMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Victim =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Victim kVictim{};
+  void set_victim(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Victim::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OfsUnit =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_OfsUnit kOfsUnit{};
+  void set_ofs_unit(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OfsUnit::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PreVictim =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_PreVictim kPreVictim{};
+  void set_pre_victim(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreVictim::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prefree =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Prefree kPrefree{};
+  void set_prefree(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prefree::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Free =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Free kFree{};
+  void set_free(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Free::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cost =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsGetVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Cost kCost{};
+  void set_cost(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cost::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsGetDataBlockFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsGetDataBlockFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsGetDataBlockFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsGetDataBlockFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_iblock() const { return at<3>().valid(); }
+  uint64_t iblock() const { return at<3>().as_uint64(); }
+  bool has_bh_start() const { return at<4>().valid(); }
+  uint64_t bh_start() const { return at<4>().as_uint64(); }
+  bool has_bh_size() const { return at<5>().valid(); }
+  uint64_t bh_size() const { return at<5>().as_uint64(); }
+  bool has_ret() const { return at<6>().valid(); }
+  int32_t ret() const { return at<6>().as_int32(); }
+};
+
+class F2fsGetDataBlockFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsGetDataBlockFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kIblockFieldNumber = 3,
+    kBhStartFieldNumber = 4,
+    kBhSizeFieldNumber = 5,
+    kRetFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsGetDataBlockFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Iblock =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Iblock kIblock{};
+  void set_iblock(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iblock::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BhStart =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_BhStart kBhStart{};
+  void set_bh_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BhStart::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BhSize =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_BhSize kBhSize{};
+  void set_bh_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BhSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsGetDataBlockFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsFallocateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsFallocateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsFallocateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsFallocateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_mode() const { return at<3>().valid(); }
+  int32_t mode() const { return at<3>().as_int32(); }
+  bool has_offset() const { return at<4>().valid(); }
+  int64_t offset() const { return at<4>().as_int64(); }
+  bool has_len() const { return at<5>().valid(); }
+  int64_t len() const { return at<5>().as_int64(); }
+  bool has_size() const { return at<6>().valid(); }
+  int64_t size() const { return at<6>().as_int64(); }
+  bool has_blocks() const { return at<7>().valid(); }
+  uint64_t blocks() const { return at<7>().as_uint64(); }
+  bool has_ret() const { return at<8>().valid(); }
+  int32_t ret() const { return at<8>().as_int32(); }
+};
+
+class F2fsFallocateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsFallocateFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kModeFieldNumber = 3,
+    kOffsetFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kSizeFieldNumber = 6,
+    kBlocksFieldNumber = 7,
+    kRetFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsFallocateFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Offset =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Offset kOffset{};
+  void set_offset(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Offset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsFallocateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsEvictInodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsEvictInodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsEvictInodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsEvictInodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_ino() const { return at<2>().valid(); }
+  uint64_t ino() const { return at<2>().as_uint64(); }
+  bool has_pino() const { return at<3>().valid(); }
+  uint64_t pino() const { return at<3>().as_uint64(); }
+  bool has_mode() const { return at<4>().valid(); }
+  uint32_t mode() const { return at<4>().as_uint32(); }
+  bool has_size() const { return at<5>().valid(); }
+  int64_t size() const { return at<5>().as_int64(); }
+  bool has_nlink() const { return at<6>().valid(); }
+  uint32_t nlink() const { return at<6>().as_uint32(); }
+  bool has_blocks() const { return at<7>().valid(); }
+  uint64_t blocks() const { return at<7>().as_uint64(); }
+  bool has_advise() const { return at<8>().valid(); }
+  uint32_t advise() const { return at<8>().as_uint32(); }
+};
+
+class F2fsEvictInodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsEvictInodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kInoFieldNumber = 2,
+    kPinoFieldNumber = 3,
+    kModeFieldNumber = 4,
+    kSizeFieldNumber = 5,
+    kNlinkFieldNumber = 6,
+    kBlocksFieldNumber = 7,
+    kAdviseFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsEvictInodeFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ino =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ino kIno{};
+  void set_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pino =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Pino kPino{};
+  void set_pino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pino::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nlink =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nlink kNlink{};
+  void set_nlink(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nlink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Blocks =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Blocks kBlocks{};
+  void set_blocks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Blocks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Advise =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsEvictInodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Advise kAdvise{};
+  void set_advise(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Advise::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class F2fsDoSubmitBioFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  F2fsDoSubmitBioFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit F2fsDoSubmitBioFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit F2fsDoSubmitBioFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev() const { return at<1>().valid(); }
+  uint64_t dev() const { return at<1>().as_uint64(); }
+  bool has_btype() const { return at<2>().valid(); }
+  int32_t btype() const { return at<2>().as_int32(); }
+  bool has_sync() const { return at<3>().valid(); }
+  uint32_t sync() const { return at<3>().as_uint32(); }
+  bool has_sector() const { return at<4>().valid(); }
+  uint64_t sector() const { return at<4>().as_uint64(); }
+  bool has_size() const { return at<5>().valid(); }
+  uint32_t size() const { return at<5>().as_uint32(); }
+};
+
+class F2fsDoSubmitBioFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = F2fsDoSubmitBioFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevFieldNumber = 1,
+    kBtypeFieldNumber = 2,
+    kSyncFieldNumber = 3,
+    kSectorFieldNumber = 4,
+    kSizeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.F2fsDoSubmitBioFtraceEvent"; }
+
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Btype =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  static constexpr FieldMetadata_Btype kBtype{};
+  void set_btype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Btype::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sync =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  static constexpr FieldMetadata_Sync kSync{};
+  void set_sync(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sync::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sector =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  static constexpr FieldMetadata_Sector kSector{};
+  void set_sector(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sector::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      F2fsDoSubmitBioFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/fastrpc.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FASTRPC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FASTRPC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class FastrpcDmaStatFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FastrpcDmaStatFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FastrpcDmaStatFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FastrpcDmaStatFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cid() const { return at<1>().valid(); }
+  int32_t cid() const { return at<1>().as_int32(); }
+  bool has_len() const { return at<2>().valid(); }
+  int64_t len() const { return at<2>().as_int64(); }
+  bool has_total_allocated() const { return at<3>().valid(); }
+  uint64_t total_allocated() const { return at<3>().as_uint64(); }
+};
+
+class FastrpcDmaStatFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FastrpcDmaStatFtraceEvent_Decoder;
+  enum : int32_t {
+    kCidFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTotalAllocatedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FastrpcDmaStatFtraceEvent"; }
+
+
+  using FieldMetadata_Cid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FastrpcDmaStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Cid kCid{};
+  void set_cid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      FastrpcDmaStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FastrpcDmaStatFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated{};
+  void set_total_allocated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalAllocated::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/fence.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FENCE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FENCE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class FenceSignaledFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FenceSignaledFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FenceSignaledFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FenceSignaledFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class FenceSignaledFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FenceSignaledFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FenceSignaledFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceSignaledFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FenceEnableSignalFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FenceEnableSignalFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FenceEnableSignalFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FenceEnableSignalFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class FenceEnableSignalFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FenceEnableSignalFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FenceEnableSignalFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceEnableSignalFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceEnableSignalFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceEnableSignalFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceEnableSignalFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FenceDestroyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FenceDestroyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FenceDestroyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FenceDestroyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class FenceDestroyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FenceDestroyFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FenceDestroyFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FenceInitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FenceInitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FenceInitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FenceInitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint32_t context() const { return at<1>().as_uint32(); }
+  bool has_driver() const { return at<2>().valid(); }
+  ::protozero::ConstChars driver() const { return at<2>().as_string(); }
+  bool has_seqno() const { return at<3>().valid(); }
+  uint32_t seqno() const { return at<3>().as_uint32(); }
+  bool has_timeline() const { return at<4>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<4>().as_string(); }
+};
+
+class FenceInitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FenceInitFtraceEvent_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kDriverFieldNumber = 2,
+    kSeqnoFieldNumber = 3,
+    kTimelineFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FenceInitFtraceEvent"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Driver =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Driver kDriver{};
+  void set_driver(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, data, size);
+  }
+  void set_driver(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Driver::kFieldId, chars.data, chars.size);
+  }
+  void set_driver(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Driver::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      FenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      FenceInitFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/filemap.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FILEMAP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FILEMAP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class MmFilemapDeleteFromPageCacheFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmFilemapDeleteFromPageCacheFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmFilemapDeleteFromPageCacheFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmFilemapDeleteFromPageCacheFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pfn() const { return at<1>().valid(); }
+  uint64_t pfn() const { return at<1>().as_uint64(); }
+  bool has_i_ino() const { return at<2>().valid(); }
+  uint64_t i_ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+  bool has_s_dev() const { return at<4>().valid(); }
+  uint64_t s_dev() const { return at<4>().as_uint64(); }
+  bool has_page() const { return at<5>().valid(); }
+  uint64_t page() const { return at<5>().as_uint64(); }
+};
+
+class MmFilemapDeleteFromPageCacheFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmFilemapDeleteFromPageCacheFtraceEvent_Decoder;
+  enum : int32_t {
+    kPfnFieldNumber = 1,
+    kIInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kSDevFieldNumber = 4,
+    kPageFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmFilemapDeleteFromPageCacheFtraceEvent"; }
+
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IIno =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_IIno kIIno{};
+  void set_i_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IIno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SDev =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_SDev kSDev{};
+  void set_s_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SDev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapDeleteFromPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmFilemapAddToPageCacheFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmFilemapAddToPageCacheFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmFilemapAddToPageCacheFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmFilemapAddToPageCacheFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pfn() const { return at<1>().valid(); }
+  uint64_t pfn() const { return at<1>().as_uint64(); }
+  bool has_i_ino() const { return at<2>().valid(); }
+  uint64_t i_ino() const { return at<2>().as_uint64(); }
+  bool has_index() const { return at<3>().valid(); }
+  uint64_t index() const { return at<3>().as_uint64(); }
+  bool has_s_dev() const { return at<4>().valid(); }
+  uint64_t s_dev() const { return at<4>().as_uint64(); }
+  bool has_page() const { return at<5>().valid(); }
+  uint64_t page() const { return at<5>().as_uint64(); }
+};
+
+class MmFilemapAddToPageCacheFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmFilemapAddToPageCacheFtraceEvent_Decoder;
+  enum : int32_t {
+    kPfnFieldNumber = 1,
+    kIInoFieldNumber = 2,
+    kIndexFieldNumber = 3,
+    kSDevFieldNumber = 4,
+    kPageFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmFilemapAddToPageCacheFtraceEvent"; }
+
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IIno =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_IIno kIIno{};
+  void set_i_ino(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IIno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SDev =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_SDev kSDev{};
+  void set_s_dev(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SDev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmFilemapAddToPageCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ftrace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_FTRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class FuncgraphExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FuncgraphExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FuncgraphExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FuncgraphExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_calltime() const { return at<1>().valid(); }
+  uint64_t calltime() const { return at<1>().as_uint64(); }
+  bool has_depth() const { return at<2>().valid(); }
+  int32_t depth() const { return at<2>().as_int32(); }
+  bool has_func() const { return at<3>().valid(); }
+  uint64_t func() const { return at<3>().as_uint64(); }
+  bool has_overrun() const { return at<4>().valid(); }
+  uint64_t overrun() const { return at<4>().as_uint64(); }
+  bool has_rettime() const { return at<5>().valid(); }
+  uint64_t rettime() const { return at<5>().as_uint64(); }
+};
+
+class FuncgraphExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FuncgraphExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kCalltimeFieldNumber = 1,
+    kDepthFieldNumber = 2,
+    kFuncFieldNumber = 3,
+    kOverrunFieldNumber = 4,
+    kRettimeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FuncgraphExitFtraceEvent"; }
+
+
+  using FieldMetadata_Calltime =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FuncgraphExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Calltime kCalltime{};
+  void set_calltime(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Calltime::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Depth =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FuncgraphExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Depth kDepth{};
+  void set_depth(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Depth::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Func =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FuncgraphExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Func kFunc{};
+  void set_func(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Func::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Overrun =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FuncgraphExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Overrun kOverrun{};
+  void set_overrun(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Overrun::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rettime =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FuncgraphExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Rettime kRettime{};
+  void set_rettime(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rettime::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class FuncgraphEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  FuncgraphEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit FuncgraphEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit FuncgraphEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_depth() const { return at<1>().valid(); }
+  int32_t depth() const { return at<1>().as_int32(); }
+  bool has_func() const { return at<2>().valid(); }
+  uint64_t func() const { return at<2>().as_uint64(); }
+};
+
+class FuncgraphEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = FuncgraphEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kDepthFieldNumber = 1,
+    kFuncFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.FuncgraphEntryFtraceEvent"; }
+
+
+  using FieldMetadata_Depth =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      FuncgraphEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Depth kDepth{};
+  void set_depth(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Depth::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Func =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      FuncgraphEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Func kFunc{};
+  void set_func(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Func::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PrintFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PrintFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PrintFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PrintFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ip() const { return at<1>().valid(); }
+  uint64_t ip() const { return at<1>().as_uint64(); }
+  bool has_buf() const { return at<2>().valid(); }
+  ::protozero::ConstChars buf() const { return at<2>().as_string(); }
+};
+
+class PrintFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = PrintFtraceEvent_Decoder;
+  enum : int32_t {
+    kIpFieldNumber = 1,
+    kBufFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PrintFtraceEvent"; }
+
+
+  using FieldMetadata_Ip =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PrintFtraceEvent>;
+
+  static constexpr FieldMetadata_Ip kIp{};
+  void set_ip(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ip::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Buf =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PrintFtraceEvent>;
+
+  static constexpr FieldMetadata_Buf kBuf{};
+  void set_buf(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Buf::kFieldId, data, size);
+  }
+  void set_buf(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Buf::kFieldId, chars.data, chars.size);
+  }
+  void set_buf(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Buf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/g2d.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_G2D_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_G2D_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class G2dTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  G2dTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit G2dTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit G2dTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars name() const { return at<4>().as_string(); }
+  bool has_type() const { return at<5>().valid(); }
+  uint32_t type() const { return at<5>().as_uint32(); }
+  bool has_value() const { return at<6>().valid(); }
+  int32_t value() const { return at<6>().as_int32(); }
+};
+
+class G2dTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = G2dTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kNameFieldNumber = 4,
+    kTypeFieldNumber = 5,
+    kValueFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.G2dTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      G2dTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      G2dTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      G2dTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      G2dTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/gpu_mem.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GPU_MEM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GPU_MEM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class GpuMemTotalFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuMemTotalFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuMemTotalFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuMemTotalFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gpu_id() const { return at<1>().valid(); }
+  uint32_t gpu_id() const { return at<1>().as_uint32(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_size() const { return at<3>().valid(); }
+  uint64_t size() const { return at<3>().as_uint64(); }
+};
+
+class GpuMemTotalFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuMemTotalFtraceEvent_Decoder;
+  enum : int32_t {
+    kGpuIdFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kSizeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuMemTotalFtraceEvent"; }
+
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuMemTotalFtraceEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuMemTotalFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuMemTotalFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/gpu_scheduler.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GPU_SCHEDULER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_GPU_SCHEDULER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class DrmSchedProcessJobFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DrmSchedProcessJobFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DrmSchedProcessJobFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DrmSchedProcessJobFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_fence() const { return at<1>().valid(); }
+  uint64_t fence() const { return at<1>().as_uint64(); }
+};
+
+class DrmSchedProcessJobFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DrmSchedProcessJobFtraceEvent_Decoder;
+  enum : int32_t {
+    kFenceFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DrmSchedProcessJobFtraceEvent"; }
+
+
+  using FieldMetadata_Fence =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmSchedProcessJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Fence kFence{};
+  void set_fence(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DrmRunJobFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DrmRunJobFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DrmRunJobFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DrmRunJobFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_entity() const { return at<1>().valid(); }
+  uint64_t entity() const { return at<1>().as_uint64(); }
+  bool has_fence() const { return at<2>().valid(); }
+  uint64_t fence() const { return at<2>().as_uint64(); }
+  bool has_hw_job_count() const { return at<3>().valid(); }
+  int32_t hw_job_count() const { return at<3>().as_int32(); }
+  bool has_id() const { return at<4>().valid(); }
+  uint64_t id() const { return at<4>().as_uint64(); }
+  bool has_job_count() const { return at<5>().valid(); }
+  uint32_t job_count() const { return at<5>().as_uint32(); }
+  bool has_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars name() const { return at<6>().as_string(); }
+};
+
+class DrmRunJobFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DrmRunJobFtraceEvent_Decoder;
+  enum : int32_t {
+    kEntityFieldNumber = 1,
+    kFenceFieldNumber = 2,
+    kHwJobCountFieldNumber = 3,
+    kIdFieldNumber = 4,
+    kJobCountFieldNumber = 5,
+    kNameFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DrmRunJobFtraceEvent"; }
+
+
+  using FieldMetadata_Entity =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Entity kEntity{};
+  void set_entity(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Entity::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fence =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Fence kFence{};
+  void set_fence(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HwJobCount =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_HwJobCount kHwJobCount{};
+  void set_hw_job_count(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwJobCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_JobCount =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_JobCount kJobCount{};
+  void set_job_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_JobCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DrmRunJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DrmSchedJobFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DrmSchedJobFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DrmSchedJobFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DrmSchedJobFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_entity() const { return at<1>().valid(); }
+  uint64_t entity() const { return at<1>().as_uint64(); }
+  bool has_fence() const { return at<2>().valid(); }
+  uint64_t fence() const { return at<2>().as_uint64(); }
+  bool has_hw_job_count() const { return at<3>().valid(); }
+  int32_t hw_job_count() const { return at<3>().as_int32(); }
+  bool has_id() const { return at<4>().valid(); }
+  uint64_t id() const { return at<4>().as_uint64(); }
+  bool has_job_count() const { return at<5>().valid(); }
+  uint32_t job_count() const { return at<5>().as_uint32(); }
+  bool has_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars name() const { return at<6>().as_string(); }
+};
+
+class DrmSchedJobFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DrmSchedJobFtraceEvent_Decoder;
+  enum : int32_t {
+    kEntityFieldNumber = 1,
+    kFenceFieldNumber = 2,
+    kHwJobCountFieldNumber = 3,
+    kIdFieldNumber = 4,
+    kJobCountFieldNumber = 5,
+    kNameFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DrmSchedJobFtraceEvent"; }
+
+
+  using FieldMetadata_Entity =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Entity kEntity{};
+  void set_entity(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Entity::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fence =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Fence kFence{};
+  void set_fence(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HwJobCount =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_HwJobCount kHwJobCount{};
+  void set_hw_job_count(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwJobCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_JobCount =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_JobCount kJobCount{};
+  void set_job_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_JobCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DrmSchedJobFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/hyp.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_HYP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_HYP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class HostMemAbortFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HostMemAbortFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HostMemAbortFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HostMemAbortFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_esr() const { return at<1>().valid(); }
+  uint64_t esr() const { return at<1>().as_uint64(); }
+  bool has_addr() const { return at<2>().valid(); }
+  uint64_t addr() const { return at<2>().as_uint64(); }
+};
+
+class HostMemAbortFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = HostMemAbortFtraceEvent_Decoder;
+  enum : int32_t {
+    kEsrFieldNumber = 1,
+    kAddrFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HostMemAbortFtraceEvent"; }
+
+
+  using FieldMetadata_Esr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HostMemAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Esr kEsr{};
+  void set_esr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Esr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HostMemAbortFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class HostSmcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HostSmcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HostSmcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HostSmcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_forwarded() const { return at<2>().valid(); }
+  uint32_t forwarded() const { return at<2>().as_uint32(); }
+};
+
+class HostSmcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = HostSmcFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kForwardedFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HostSmcFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HostSmcFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Forwarded =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HostSmcFtraceEvent>;
+
+  static constexpr FieldMetadata_Forwarded kForwarded{};
+  void set_forwarded(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Forwarded::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class HostHcallFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HostHcallFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HostHcallFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HostHcallFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint32_t id() const { return at<1>().as_uint32(); }
+  bool has_invalid() const { return at<2>().valid(); }
+  uint32_t invalid() const { return at<2>().as_uint32(); }
+};
+
+class HostHcallFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = HostHcallFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kInvalidFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HostHcallFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HostHcallFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Invalid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      HostHcallFtraceEvent>;
+
+  static constexpr FieldMetadata_Invalid kInvalid{};
+  void set_invalid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Invalid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class HypExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HypExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HypExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HypExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class HypExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = HypExitFtraceEvent_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.HypExitFtraceEvent"; }
+
+};
+
+class HypEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HypEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HypEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HypEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class HypEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = HypEnterFtraceEvent_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.HypEnterFtraceEvent"; }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/i2c.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_I2C_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_I2C_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SmbusReplyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SmbusReplyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmbusReplyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmbusReplyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_addr() const { return at<2>().valid(); }
+  uint32_t addr() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_command() const { return at<4>().valid(); }
+  uint32_t command() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+  bool has_protocol() const { return at<6>().valid(); }
+  uint32_t protocol() const { return at<6>().as_uint32(); }
+};
+
+class SmbusReplyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SmbusReplyFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kAddrFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kCommandFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kProtocolFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmbusReplyFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Command =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Command kCommand{};
+  void set_command(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Command::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SmbusResultFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SmbusResultFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmbusResultFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmbusResultFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_addr() const { return at<2>().valid(); }
+  uint32_t addr() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_read_write() const { return at<4>().valid(); }
+  uint32_t read_write() const { return at<4>().as_uint32(); }
+  bool has_command() const { return at<5>().valid(); }
+  uint32_t command() const { return at<5>().as_uint32(); }
+  bool has_res() const { return at<6>().valid(); }
+  int32_t res() const { return at<6>().as_int32(); }
+  bool has_protocol() const { return at<7>().valid(); }
+  uint32_t protocol() const { return at<7>().as_uint32(); }
+};
+
+class SmbusResultFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SmbusResultFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kAddrFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kReadWriteFieldNumber = 4,
+    kCommandFieldNumber = 5,
+    kResFieldNumber = 6,
+    kProtocolFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmbusResultFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReadWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_ReadWrite kReadWrite{};
+  void set_read_write(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadWrite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Command =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Command kCommand{};
+  void set_command(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Command::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Res =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Res kRes{};
+  void set_res(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Res::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SmbusWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SmbusWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmbusWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmbusWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_addr() const { return at<2>().valid(); }
+  uint32_t addr() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_command() const { return at<4>().valid(); }
+  uint32_t command() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+  bool has_protocol() const { return at<6>().valid(); }
+  uint32_t protocol() const { return at<6>().as_uint32(); }
+};
+
+class SmbusWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SmbusWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kAddrFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kCommandFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kProtocolFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmbusWriteFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Command =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Command kCommand{};
+  void set_command(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Command::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SmbusReadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SmbusReadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmbusReadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmbusReadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_addr() const { return at<3>().valid(); }
+  uint32_t addr() const { return at<3>().as_uint32(); }
+  bool has_command() const { return at<4>().valid(); }
+  uint32_t command() const { return at<4>().as_uint32(); }
+  bool has_protocol() const { return at<5>().valid(); }
+  uint32_t protocol() const { return at<5>().as_uint32(); }
+};
+
+class SmbusReadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SmbusReadFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kAddrFieldNumber = 3,
+    kCommandFieldNumber = 4,
+    kProtocolFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmbusReadFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SmbusReadFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Command =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Command kCommand{};
+  void set_command(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Command::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmbusReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class I2cReplyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  I2cReplyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit I2cReplyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit I2cReplyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_msg_nr() const { return at<2>().valid(); }
+  uint32_t msg_nr() const { return at<2>().as_uint32(); }
+  bool has_addr() const { return at<3>().valid(); }
+  uint32_t addr() const { return at<3>().as_uint32(); }
+  bool has_flags() const { return at<4>().valid(); }
+  uint32_t flags() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+  bool has_buf() const { return at<6>().valid(); }
+  uint32_t buf() const { return at<6>().as_uint32(); }
+};
+
+class I2cReplyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = I2cReplyFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kMsgNrFieldNumber = 2,
+    kAddrFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kBufFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.I2cReplyFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MsgNr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_MsgNr kMsgNr{};
+  void set_msg_nr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MsgNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Buf =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReplyFtraceEvent>;
+
+  static constexpr FieldMetadata_Buf kBuf{};
+  void set_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Buf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class I2cResultFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  I2cResultFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit I2cResultFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit I2cResultFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_nr_msgs() const { return at<2>().valid(); }
+  uint32_t nr_msgs() const { return at<2>().as_uint32(); }
+  bool has_ret() const { return at<3>().valid(); }
+  int32_t ret() const { return at<3>().as_int32(); }
+};
+
+class I2cResultFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = I2cResultFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kNrMsgsFieldNumber = 2,
+    kRetFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.I2cResultFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cResultFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrMsgs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cResultFtraceEvent>;
+
+  static constexpr FieldMetadata_NrMsgs kNrMsgs{};
+  void set_nr_msgs(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrMsgs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cResultFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class I2cWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  I2cWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit I2cWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit I2cWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_msg_nr() const { return at<2>().valid(); }
+  uint32_t msg_nr() const { return at<2>().as_uint32(); }
+  bool has_addr() const { return at<3>().valid(); }
+  uint32_t addr() const { return at<3>().as_uint32(); }
+  bool has_flags() const { return at<4>().valid(); }
+  uint32_t flags() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+  bool has_buf() const { return at<6>().valid(); }
+  uint32_t buf() const { return at<6>().as_uint32(); }
+};
+
+class I2cWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = I2cWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kMsgNrFieldNumber = 2,
+    kAddrFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kBufFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.I2cWriteFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MsgNr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_MsgNr kMsgNr{};
+  void set_msg_nr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MsgNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Buf =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Buf kBuf{};
+  void set_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Buf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class I2cReadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  I2cReadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit I2cReadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit I2cReadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_adapter_nr() const { return at<1>().valid(); }
+  int32_t adapter_nr() const { return at<1>().as_int32(); }
+  bool has_msg_nr() const { return at<2>().valid(); }
+  uint32_t msg_nr() const { return at<2>().as_uint32(); }
+  bool has_addr() const { return at<3>().valid(); }
+  uint32_t addr() const { return at<3>().as_uint32(); }
+  bool has_flags() const { return at<4>().valid(); }
+  uint32_t flags() const { return at<4>().as_uint32(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint32_t len() const { return at<5>().as_uint32(); }
+};
+
+class I2cReadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = I2cReadFtraceEvent_Decoder;
+  enum : int32_t {
+    kAdapterNrFieldNumber = 1,
+    kMsgNrFieldNumber = 2,
+    kAddrFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+    kLenFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.I2cReadFtraceEvent"; }
+
+
+  using FieldMetadata_AdapterNr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      I2cReadFtraceEvent>;
+
+  static constexpr FieldMetadata_AdapterNr kAdapterNr{};
+  void set_adapter_nr(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AdapterNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MsgNr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReadFtraceEvent>;
+
+  static constexpr FieldMetadata_MsgNr kMsgNr{};
+  void set_msg_nr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MsgNr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      I2cReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ion.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_ION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_ION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class IonStatFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonStatFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonStatFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonStatFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buffer_id() const { return at<1>().valid(); }
+  uint32_t buffer_id() const { return at<1>().as_uint32(); }
+  bool has_len() const { return at<2>().valid(); }
+  int64_t len() const { return at<2>().as_int64(); }
+  bool has_total_allocated() const { return at<3>().valid(); }
+  uint64_t total_allocated() const { return at<3>().as_uint64(); }
+};
+
+class IonStatFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonStatFtraceEvent_Decoder;
+  enum : int32_t {
+    kBufferIdFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTotalAllocatedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonStatFtraceEvent"; }
+
+
+  using FieldMetadata_BufferId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonStatFtraceEvent>;
+
+  static constexpr FieldMetadata_BufferId kBufferId{};
+  void set_buffer_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      IonStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonStatFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated{};
+  void set_total_allocated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalAllocated::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ipi.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_IPI_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_IPI_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class IpiRaiseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IpiRaiseFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IpiRaiseFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IpiRaiseFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_target_cpus() const { return at<1>().valid(); }
+  uint32_t target_cpus() const { return at<1>().as_uint32(); }
+  bool has_reason() const { return at<2>().valid(); }
+  ::protozero::ConstChars reason() const { return at<2>().as_string(); }
+};
+
+class IpiRaiseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IpiRaiseFtraceEvent_Decoder;
+  enum : int32_t {
+    kTargetCpusFieldNumber = 1,
+    kReasonFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IpiRaiseFtraceEvent"; }
+
+
+  using FieldMetadata_TargetCpus =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IpiRaiseFtraceEvent>;
+
+  static constexpr FieldMetadata_TargetCpus kTargetCpus{};
+  void set_target_cpus(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCpus::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IpiRaiseFtraceEvent>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, data, size);
+  }
+  void set_reason(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, chars.data, chars.size);
+  }
+  void set_reason(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IpiExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IpiExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IpiExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IpiExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_reason() const { return at<1>().valid(); }
+  ::protozero::ConstChars reason() const { return at<1>().as_string(); }
+};
+
+class IpiExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IpiExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kReasonFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IpiExitFtraceEvent"; }
+
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IpiExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, data, size);
+  }
+  void set_reason(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, chars.data, chars.size);
+  }
+  void set_reason(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IpiEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IpiEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IpiEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IpiEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_reason() const { return at<1>().valid(); }
+  ::protozero::ConstChars reason() const { return at<1>().as_string(); }
+};
+
+class IpiEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IpiEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kReasonFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IpiEntryFtraceEvent"; }
+
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IpiEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, data, size);
+  }
+  void set_reason(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Reason::kFieldId, chars.data, chars.size);
+  }
+  void set_reason(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/irq.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_IRQ_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_IRQ_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class IrqHandlerExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IrqHandlerExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IrqHandlerExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IrqHandlerExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  int32_t irq() const { return at<1>().as_int32(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int32_t ret() const { return at<2>().as_int32(); }
+};
+
+class IrqHandlerExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IrqHandlerExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+    kRetFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IrqHandlerExitFtraceEvent"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IrqHandlerExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IrqHandlerExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IrqHandlerEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IrqHandlerEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IrqHandlerEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IrqHandlerEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  int32_t irq() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_handler() const { return at<3>().valid(); }
+  uint32_t handler() const { return at<3>().as_uint32(); }
+};
+
+class IrqHandlerEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IrqHandlerEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kHandlerFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IrqHandlerEntryFtraceEvent"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IrqHandlerEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IrqHandlerEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Handler =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IrqHandlerEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Handler kHandler{};
+  void set_handler(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Handler::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SoftirqRaiseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SoftirqRaiseFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SoftirqRaiseFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SoftirqRaiseFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_vec() const { return at<1>().valid(); }
+  uint32_t vec() const { return at<1>().as_uint32(); }
+};
+
+class SoftirqRaiseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SoftirqRaiseFtraceEvent_Decoder;
+  enum : int32_t {
+    kVecFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SoftirqRaiseFtraceEvent"; }
+
+
+  using FieldMetadata_Vec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SoftirqRaiseFtraceEvent>;
+
+  static constexpr FieldMetadata_Vec kVec{};
+  void set_vec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vec::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SoftirqExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SoftirqExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SoftirqExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SoftirqExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_vec() const { return at<1>().valid(); }
+  uint32_t vec() const { return at<1>().as_uint32(); }
+};
+
+class SoftirqExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SoftirqExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kVecFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SoftirqExitFtraceEvent"; }
+
+
+  using FieldMetadata_Vec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SoftirqExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Vec kVec{};
+  void set_vec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vec::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SoftirqEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SoftirqEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SoftirqEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SoftirqEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_vec() const { return at<1>().valid(); }
+  uint32_t vec() const { return at<1>().as_uint32(); }
+};
+
+class SoftirqEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SoftirqEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kVecFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SoftirqEntryFtraceEvent"; }
+
+
+  using FieldMetadata_Vec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SoftirqEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Vec kVec{};
+  void set_vec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vec::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/kmem.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_KMEM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_KMEM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class IonBufferDestroyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonBufferDestroyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonBufferDestroyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonBufferDestroyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_addr() const { return at<1>().valid(); }
+  uint64_t addr() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+};
+
+class IonBufferDestroyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonBufferDestroyFtraceEvent_Decoder;
+  enum : int32_t {
+    kAddrFieldNumber = 1,
+    kLenFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonBufferDestroyFtraceEvent"; }
+
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonBufferDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonBufferDestroyFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonBufferCreateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonBufferCreateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonBufferCreateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonBufferCreateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_addr() const { return at<1>().valid(); }
+  uint64_t addr() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+};
+
+class IonBufferCreateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonBufferCreateFtraceEvent_Decoder;
+  enum : int32_t {
+    kAddrFieldNumber = 1,
+    kLenFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonBufferCreateFtraceEvent"; }
+
+
+  using FieldMetadata_Addr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonBufferCreateFtraceEvent>;
+
+  static constexpr FieldMetadata_Addr kAddr{};
+  void set_addr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Addr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonBufferCreateFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonHeapGrowFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonHeapGrowFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonHeapGrowFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonHeapGrowFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_heap_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<1>().as_string(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_total_allocated() const { return at<3>().valid(); }
+  int64_t total_allocated() const { return at<3>().as_int64(); }
+};
+
+class IonHeapGrowFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonHeapGrowFtraceEvent_Decoder;
+  enum : int32_t {
+    kHeapNameFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTotalAllocatedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonHeapGrowFtraceEvent"; }
+
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonHeapGrowFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonHeapGrowFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      IonHeapGrowFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated{};
+  void set_total_allocated(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalAllocated::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonHeapShrinkFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonHeapShrinkFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonHeapShrinkFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonHeapShrinkFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_heap_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<1>().as_string(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_total_allocated() const { return at<3>().valid(); }
+  int64_t total_allocated() const { return at<3>().as_int64(); }
+};
+
+class IonHeapShrinkFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonHeapShrinkFtraceEvent_Decoder;
+  enum : int32_t {
+    kHeapNameFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTotalAllocatedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonHeapShrinkFtraceEvent"; }
+
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonHeapShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonHeapShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      IonHeapShrinkFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalAllocated kTotalAllocated{};
+  void set_total_allocated(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalAllocated::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class RssStatFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RssStatFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RssStatFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RssStatFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_member() const { return at<1>().valid(); }
+  int32_t member() const { return at<1>().as_int32(); }
+  bool has_size() const { return at<2>().valid(); }
+  int64_t size() const { return at<2>().as_int64(); }
+  bool has_curr() const { return at<3>().valid(); }
+  uint32_t curr() const { return at<3>().as_uint32(); }
+  bool has_mm_id() const { return at<4>().valid(); }
+  uint32_t mm_id() const { return at<4>().as_uint32(); }
+};
+
+class RssStatFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RssStatFtraceEvent_Decoder;
+  enum : int32_t {
+    kMemberFieldNumber = 1,
+    kSizeFieldNumber = 2,
+    kCurrFieldNumber = 3,
+    kMmIdFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RssStatFtraceEvent"; }
+
+
+  using FieldMetadata_Member =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RssStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Member kMember{};
+  void set_member(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Member::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      RssStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Curr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RssStatFtraceEvent>;
+
+  static constexpr FieldMetadata_Curr kCurr{};
+  void set_curr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Curr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MmId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RssStatFtraceEvent>;
+
+  static constexpr FieldMetadata_MmId kMmId{};
+  void set_mm_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MmId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmPagePcpuDrainFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPagePcpuDrainFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPagePcpuDrainFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPagePcpuDrainFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_migratetype() const { return at<1>().valid(); }
+  int32_t migratetype() const { return at<1>().as_int32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+  bool has_page() const { return at<3>().valid(); }
+  uint64_t page() const { return at<3>().as_uint64(); }
+  bool has_pfn() const { return at<4>().valid(); }
+  uint64_t pfn() const { return at<4>().as_uint64(); }
+};
+
+class MmPagePcpuDrainFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPagePcpuDrainFtraceEvent_Decoder;
+  enum : int32_t {
+    kMigratetypeFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kPageFieldNumber = 3,
+    kPfnFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPagePcpuDrainFtraceEvent"; }
+
+
+  using FieldMetadata_Migratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPagePcpuDrainFtraceEvent>;
+
+  static constexpr FieldMetadata_Migratetype kMigratetype{};
+  void set_migratetype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Migratetype::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPagePcpuDrainFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPagePcpuDrainFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPagePcpuDrainFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmPageFreeBatchedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPageFreeBatchedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPageFreeBatchedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPageFreeBatchedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cold() const { return at<1>().valid(); }
+  int32_t cold() const { return at<1>().as_int32(); }
+  bool has_page() const { return at<2>().valid(); }
+  uint64_t page() const { return at<2>().as_uint64(); }
+  bool has_pfn() const { return at<3>().valid(); }
+  uint64_t pfn() const { return at<3>().as_uint64(); }
+};
+
+class MmPageFreeBatchedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPageFreeBatchedFtraceEvent_Decoder;
+  enum : int32_t {
+    kColdFieldNumber = 1,
+    kPageFieldNumber = 2,
+    kPfnFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPageFreeBatchedFtraceEvent"; }
+
+
+  using FieldMetadata_Cold =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageFreeBatchedFtraceEvent>;
+
+  static constexpr FieldMetadata_Cold kCold{};
+  void set_cold(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cold::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageFreeBatchedFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageFreeBatchedFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmPageFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPageFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPageFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPageFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_order() const { return at<1>().valid(); }
+  uint32_t order() const { return at<1>().as_uint32(); }
+  bool has_page() const { return at<2>().valid(); }
+  uint64_t page() const { return at<2>().as_uint64(); }
+  bool has_pfn() const { return at<3>().valid(); }
+  uint64_t pfn() const { return at<3>().as_uint64(); }
+};
+
+class MmPageFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPageFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kOrderFieldNumber = 1,
+    kPageFieldNumber = 2,
+    kPfnFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPageFreeFtraceEvent"; }
+
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPageFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmPageAllocZoneLockedFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPageAllocZoneLockedFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPageAllocZoneLockedFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPageAllocZoneLockedFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_migratetype() const { return at<1>().valid(); }
+  int32_t migratetype() const { return at<1>().as_int32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+  bool has_page() const { return at<3>().valid(); }
+  uint64_t page() const { return at<3>().as_uint64(); }
+  bool has_pfn() const { return at<4>().valid(); }
+  uint64_t pfn() const { return at<4>().as_uint64(); }
+};
+
+class MmPageAllocZoneLockedFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPageAllocZoneLockedFtraceEvent_Decoder;
+  enum : int32_t {
+    kMigratetypeFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kPageFieldNumber = 3,
+    kPfnFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPageAllocZoneLockedFtraceEvent"; }
+
+
+  using FieldMetadata_Migratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocZoneLockedFtraceEvent>;
+
+  static constexpr FieldMetadata_Migratetype kMigratetype{};
+  void set_migratetype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Migratetype::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPageAllocZoneLockedFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocZoneLockedFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocZoneLockedFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmPageAllocExtfragFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPageAllocExtfragFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPageAllocExtfragFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPageAllocExtfragFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_alloc_migratetype() const { return at<1>().valid(); }
+  int32_t alloc_migratetype() const { return at<1>().as_int32(); }
+  bool has_alloc_order() const { return at<2>().valid(); }
+  int32_t alloc_order() const { return at<2>().as_int32(); }
+  bool has_fallback_migratetype() const { return at<3>().valid(); }
+  int32_t fallback_migratetype() const { return at<3>().as_int32(); }
+  bool has_fallback_order() const { return at<4>().valid(); }
+  int32_t fallback_order() const { return at<4>().as_int32(); }
+  bool has_page() const { return at<5>().valid(); }
+  uint64_t page() const { return at<5>().as_uint64(); }
+  bool has_change_ownership() const { return at<6>().valid(); }
+  int32_t change_ownership() const { return at<6>().as_int32(); }
+  bool has_pfn() const { return at<7>().valid(); }
+  uint64_t pfn() const { return at<7>().as_uint64(); }
+};
+
+class MmPageAllocExtfragFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPageAllocExtfragFtraceEvent_Decoder;
+  enum : int32_t {
+    kAllocMigratetypeFieldNumber = 1,
+    kAllocOrderFieldNumber = 2,
+    kFallbackMigratetypeFieldNumber = 3,
+    kFallbackOrderFieldNumber = 4,
+    kPageFieldNumber = 5,
+    kChangeOwnershipFieldNumber = 6,
+    kPfnFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPageAllocExtfragFtraceEvent"; }
+
+
+  using FieldMetadata_AllocMigratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_AllocMigratetype kAllocMigratetype{};
+  void set_alloc_migratetype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocMigratetype::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllocOrder =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_AllocOrder kAllocOrder{};
+  void set_alloc_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocOrder::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FallbackMigratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_FallbackMigratetype kFallbackMigratetype{};
+  void set_fallback_migratetype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FallbackMigratetype::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FallbackOrder =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_FallbackOrder kFallbackOrder{};
+  void set_fallback_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FallbackOrder::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChangeOwnership =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_ChangeOwnership kChangeOwnership{};
+  void set_change_ownership(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChangeOwnership::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocExtfragFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmPageAllocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmPageAllocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmPageAllocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmPageAllocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_migratetype() const { return at<2>().valid(); }
+  int32_t migratetype() const { return at<2>().as_int32(); }
+  bool has_order() const { return at<3>().valid(); }
+  uint32_t order() const { return at<3>().as_uint32(); }
+  bool has_page() const { return at<4>().valid(); }
+  uint64_t page() const { return at<4>().as_uint64(); }
+  bool has_pfn() const { return at<5>().valid(); }
+  uint64_t pfn() const { return at<5>().as_uint64(); }
+};
+
+class MmPageAllocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmPageAllocFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kMigratetypeFieldNumber = 2,
+    kOrderFieldNumber = 3,
+    kPageFieldNumber = 4,
+    kPfnFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmPageAllocFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPageAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Migratetype =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmPageAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Migratetype kMigratetype{};
+  void set_migratetype(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Migratetype::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmPageAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Page =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Page kPage{};
+  void set_page(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Page::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pfn =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmPageAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Pfn kPfn{};
+  void set_pfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MigrateRetryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MigrateRetryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MigrateRetryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MigrateRetryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tries() const { return at<1>().valid(); }
+  int32_t tries() const { return at<1>().as_int32(); }
+};
+
+class MigrateRetryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MigrateRetryFtraceEvent_Decoder;
+  enum : int32_t {
+    kTriesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MigrateRetryFtraceEvent"; }
+
+
+  using FieldMetadata_Tries =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MigrateRetryFtraceEvent>;
+
+  static constexpr FieldMetadata_Tries kTries{};
+  void set_tries(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tries::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MigratePagesStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MigratePagesStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MigratePagesStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MigratePagesStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+};
+
+class MigratePagesStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MigratePagesStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MigratePagesStartFtraceEvent"; }
+
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MigratePagesStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MigratePagesEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MigratePagesEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MigratePagesEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MigratePagesEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mode() const { return at<1>().valid(); }
+  int32_t mode() const { return at<1>().as_int32(); }
+};
+
+class MigratePagesEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MigratePagesEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kModeFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MigratePagesEndFtraceEvent"; }
+
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MigratePagesEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KmemCacheFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KmemCacheFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KmemCacheFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KmemCacheFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_call_site() const { return at<1>().valid(); }
+  uint64_t call_site() const { return at<1>().as_uint64(); }
+  bool has_ptr() const { return at<2>().valid(); }
+  uint64_t ptr() const { return at<2>().as_uint64(); }
+};
+
+class KmemCacheFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KmemCacheFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kCallSiteFieldNumber = 1,
+    kPtrFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KmemCacheFreeFtraceEvent"; }
+
+
+  using FieldMetadata_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KmemCacheAllocNodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KmemCacheAllocNodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KmemCacheAllocNodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KmemCacheAllocNodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes_alloc() const { return at<1>().valid(); }
+  uint64_t bytes_alloc() const { return at<1>().as_uint64(); }
+  bool has_bytes_req() const { return at<2>().valid(); }
+  uint64_t bytes_req() const { return at<2>().as_uint64(); }
+  bool has_call_site() const { return at<3>().valid(); }
+  uint64_t call_site() const { return at<3>().as_uint64(); }
+  bool has_gfp_flags() const { return at<4>().valid(); }
+  uint32_t gfp_flags() const { return at<4>().as_uint32(); }
+  bool has_node() const { return at<5>().valid(); }
+  int32_t node() const { return at<5>().as_int32(); }
+  bool has_ptr() const { return at<6>().valid(); }
+  uint64_t ptr() const { return at<6>().as_uint64(); }
+};
+
+class KmemCacheAllocNodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KmemCacheAllocNodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesAllocFieldNumber = 1,
+    kBytesReqFieldNumber = 2,
+    kCallSiteFieldNumber = 3,
+    kGfpFlagsFieldNumber = 4,
+    kNodeFieldNumber = 5,
+    kPtrFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KmemCacheAllocNodeFtraceEvent"; }
+
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc{};
+  void set_bytes_alloc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesAlloc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BytesReq =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesReq kBytesReq{};
+  void set_bytes_req(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesReq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Node =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Node kNode{};
+  void set_node(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Node::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KmemCacheAllocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KmemCacheAllocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KmemCacheAllocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KmemCacheAllocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes_alloc() const { return at<1>().valid(); }
+  uint64_t bytes_alloc() const { return at<1>().as_uint64(); }
+  bool has_bytes_req() const { return at<2>().valid(); }
+  uint64_t bytes_req() const { return at<2>().as_uint64(); }
+  bool has_call_site() const { return at<3>().valid(); }
+  uint64_t call_site() const { return at<3>().as_uint64(); }
+  bool has_gfp_flags() const { return at<4>().valid(); }
+  uint32_t gfp_flags() const { return at<4>().as_uint32(); }
+  bool has_ptr() const { return at<5>().valid(); }
+  uint64_t ptr() const { return at<5>().as_uint64(); }
+};
+
+class KmemCacheAllocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KmemCacheAllocFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesAllocFieldNumber = 1,
+    kBytesReqFieldNumber = 2,
+    kCallSiteFieldNumber = 3,
+    kGfpFlagsFieldNumber = 4,
+    kPtrFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KmemCacheAllocFtraceEvent"; }
+
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc{};
+  void set_bytes_alloc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesAlloc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BytesReq =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesReq kBytesReq{};
+  void set_bytes_req(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesReq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KmemCacheAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmemCacheAllocFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KmallocNodeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KmallocNodeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KmallocNodeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KmallocNodeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes_alloc() const { return at<1>().valid(); }
+  uint64_t bytes_alloc() const { return at<1>().as_uint64(); }
+  bool has_bytes_req() const { return at<2>().valid(); }
+  uint64_t bytes_req() const { return at<2>().as_uint64(); }
+  bool has_call_site() const { return at<3>().valid(); }
+  uint64_t call_site() const { return at<3>().as_uint64(); }
+  bool has_gfp_flags() const { return at<4>().valid(); }
+  uint32_t gfp_flags() const { return at<4>().as_uint32(); }
+  bool has_node() const { return at<5>().valid(); }
+  int32_t node() const { return at<5>().as_int32(); }
+  bool has_ptr() const { return at<6>().valid(); }
+  uint64_t ptr() const { return at<6>().as_uint64(); }
+};
+
+class KmallocNodeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KmallocNodeFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesAllocFieldNumber = 1,
+    kBytesReqFieldNumber = 2,
+    kCallSiteFieldNumber = 3,
+    kGfpFlagsFieldNumber = 4,
+    kNodeFieldNumber = 5,
+    kPtrFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KmallocNodeFtraceEvent"; }
+
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc{};
+  void set_bytes_alloc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesAlloc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BytesReq =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesReq kBytesReq{};
+  void set_bytes_req(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesReq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Node =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Node kNode{};
+  void set_node(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Node::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocNodeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KmallocFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KmallocFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KmallocFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KmallocFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytes_alloc() const { return at<1>().valid(); }
+  uint64_t bytes_alloc() const { return at<1>().as_uint64(); }
+  bool has_bytes_req() const { return at<2>().valid(); }
+  uint64_t bytes_req() const { return at<2>().as_uint64(); }
+  bool has_call_site() const { return at<3>().valid(); }
+  uint64_t call_site() const { return at<3>().as_uint64(); }
+  bool has_gfp_flags() const { return at<4>().valid(); }
+  uint32_t gfp_flags() const { return at<4>().as_uint32(); }
+  bool has_ptr() const { return at<5>().valid(); }
+  uint64_t ptr() const { return at<5>().as_uint64(); }
+};
+
+class KmallocFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KmallocFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesAllocFieldNumber = 1,
+    kBytesReqFieldNumber = 2,
+    kCallSiteFieldNumber = 3,
+    kGfpFlagsFieldNumber = 4,
+    kPtrFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KmallocFtraceEvent"; }
+
+
+  using FieldMetadata_BytesAlloc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesAlloc kBytesAlloc{};
+  void set_bytes_alloc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesAlloc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BytesReq =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocFtraceEvent>;
+
+  static constexpr FieldMetadata_BytesReq kBytesReq{};
+  void set_bytes_req(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BytesReq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KmallocFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KmallocFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KfreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KfreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KfreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KfreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_call_site() const { return at<1>().valid(); }
+  uint64_t call_site() const { return at<1>().as_uint64(); }
+  bool has_ptr() const { return at<2>().valid(); }
+  uint64_t ptr() const { return at<2>().as_uint64(); }
+};
+
+class KfreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KfreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kCallSiteFieldNumber = 1,
+    kPtrFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KfreeFtraceEvent"; }
+
+
+  using FieldMetadata_CallSite =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KfreeFtraceEvent>;
+
+  static constexpr FieldMetadata_CallSite kCallSite{};
+  void set_call_site(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallSite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ptr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KfreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Ptr kPtr{};
+  void set_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ptr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonSecureCmaShrinkPoolStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaShrinkPoolStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaShrinkPoolStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaShrinkPoolStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_drained_size() const { return at<1>().valid(); }
+  uint64_t drained_size() const { return at<1>().as_uint64(); }
+  bool has_skipped_size() const { return at<2>().valid(); }
+  uint64_t skipped_size() const { return at<2>().as_uint64(); }
+};
+
+class IonSecureCmaShrinkPoolStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaShrinkPoolStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kDrainedSizeFieldNumber = 1,
+    kSkippedSizeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaShrinkPoolStartFtraceEvent"; }
+
+
+  using FieldMetadata_DrainedSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaShrinkPoolStartFtraceEvent>;
+
+  static constexpr FieldMetadata_DrainedSize kDrainedSize{};
+  void set_drained_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DrainedSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SkippedSize =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaShrinkPoolStartFtraceEvent>;
+
+  static constexpr FieldMetadata_SkippedSize kSkippedSize{};
+  void set_skipped_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkippedSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonSecureCmaShrinkPoolEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaShrinkPoolEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaShrinkPoolEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaShrinkPoolEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_drained_size() const { return at<1>().valid(); }
+  uint64_t drained_size() const { return at<1>().as_uint64(); }
+  bool has_skipped_size() const { return at<2>().valid(); }
+  uint64_t skipped_size() const { return at<2>().as_uint64(); }
+};
+
+class IonSecureCmaShrinkPoolEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaShrinkPoolEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kDrainedSizeFieldNumber = 1,
+    kSkippedSizeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaShrinkPoolEndFtraceEvent"; }
+
+
+  using FieldMetadata_DrainedSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaShrinkPoolEndFtraceEvent>;
+
+  static constexpr FieldMetadata_DrainedSize kDrainedSize{};
+  void set_drained_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DrainedSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SkippedSize =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaShrinkPoolEndFtraceEvent>;
+
+  static constexpr FieldMetadata_SkippedSize kSkippedSize{};
+  void set_skipped_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkippedSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonSecureCmaAllocateStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaAllocateStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaAllocateStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaAllocateStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint64_t align() const { return at<1>().as_uint64(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint64_t flags() const { return at<2>().as_uint64(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+};
+
+class IonSecureCmaAllocateStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaAllocateStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaAllocateStartFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonSecureCmaAllocateStartFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonSecureCmaAllocateEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaAllocateEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaAllocateEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaAllocateEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint64_t align() const { return at<1>().as_uint64(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint64_t flags() const { return at<2>().as_uint64(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+};
+
+class IonSecureCmaAllocateEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaAllocateEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaAllocateEndFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonSecureCmaAllocateEndFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAllocateEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonSecureCmaAddToPoolStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaAddToPoolStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaAddToPoolStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaAddToPoolStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_is_prefetch() const { return at<1>().valid(); }
+  uint32_t is_prefetch() const { return at<1>().as_uint32(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_pool_total() const { return at<3>().valid(); }
+  int32_t pool_total() const { return at<3>().as_int32(); }
+};
+
+class IonSecureCmaAddToPoolStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaAddToPoolStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kIsPrefetchFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kPoolTotalFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaAddToPoolStartFtraceEvent"; }
+
+
+  using FieldMetadata_IsPrefetch =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonSecureCmaAddToPoolStartFtraceEvent>;
+
+  static constexpr FieldMetadata_IsPrefetch kIsPrefetch{};
+  void set_is_prefetch(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsPrefetch::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAddToPoolStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PoolTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IonSecureCmaAddToPoolStartFtraceEvent>;
+
+  static constexpr FieldMetadata_PoolTotal kPoolTotal{};
+  void set_pool_total(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PoolTotal::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonSecureCmaAddToPoolEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonSecureCmaAddToPoolEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonSecureCmaAddToPoolEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonSecureCmaAddToPoolEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_is_prefetch() const { return at<1>().valid(); }
+  uint32_t is_prefetch() const { return at<1>().as_uint32(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_pool_total() const { return at<3>().valid(); }
+  int32_t pool_total() const { return at<3>().as_int32(); }
+};
+
+class IonSecureCmaAddToPoolEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonSecureCmaAddToPoolEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kIsPrefetchFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kPoolTotalFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonSecureCmaAddToPoolEndFtraceEvent"; }
+
+
+  using FieldMetadata_IsPrefetch =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonSecureCmaAddToPoolEndFtraceEvent>;
+
+  static constexpr FieldMetadata_IsPrefetch kIsPrefetch{};
+  void set_is_prefetch(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsPrefetch::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonSecureCmaAddToPoolEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PoolTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IonSecureCmaAddToPoolEndFtraceEvent>;
+
+  static constexpr FieldMetadata_PoolTotal kPoolTotal{};
+  void set_pool_total(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PoolTotal::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonPrefetchingFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonPrefetchingFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonPrefetchingFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonPrefetchingFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint64_t len() const { return at<1>().as_uint64(); }
+};
+
+class IonPrefetchingFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonPrefetchingFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonPrefetchingFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonPrefetchingFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonCpSecureBufferStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonCpSecureBufferStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonCpSecureBufferStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonCpSecureBufferStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint64_t align() const { return at<1>().as_uint64(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint64_t flags() const { return at<2>().as_uint64(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+};
+
+class IonCpSecureBufferStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonCpSecureBufferStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonCpSecureBufferStartFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonCpSecureBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonCpSecureBufferEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonCpSecureBufferEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonCpSecureBufferEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonCpSecureBufferEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_align() const { return at<1>().valid(); }
+  uint64_t align() const { return at<1>().as_uint64(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint64_t flags() const { return at<2>().as_uint64(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+};
+
+class IonCpSecureBufferEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonCpSecureBufferEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kAlignFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonCpSecureBufferEndFtraceEvent"; }
+
+
+  using FieldMetadata_Align =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Align kAlign{};
+  void set_align(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Align::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonCpSecureBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonCpSecureBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonCpAllocRetryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonCpAllocRetryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonCpAllocRetryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonCpAllocRetryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tries() const { return at<1>().valid(); }
+  int32_t tries() const { return at<1>().as_int32(); }
+};
+
+class IonCpAllocRetryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonCpAllocRetryFtraceEvent_Decoder;
+  enum : int32_t {
+    kTriesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonCpAllocRetryFtraceEvent"; }
+
+
+  using FieldMetadata_Tries =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IonCpAllocRetryFtraceEvent>;
+
+  static constexpr FieldMetadata_Tries kTries{};
+  void set_tries(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tries::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonAllocBufferStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonAllocBufferStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonAllocBufferStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonAllocBufferStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars client_name() const { return at<1>().as_string(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+  bool has_mask() const { return at<5>().valid(); }
+  uint32_t mask() const { return at<5>().as_uint32(); }
+};
+
+class IonAllocBufferStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonAllocBufferStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kClientNameFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kMaskFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonAllocBufferStartFtraceEvent"; }
+
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_ClientName kClientName{};
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, size);
+  }
+  void set_client_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, chars.data, chars.size);
+  }
+  void set_client_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonAllocBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mask =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Mask kMask{};
+  void set_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonAllocBufferFallbackFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonAllocBufferFallbackFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonAllocBufferFallbackFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonAllocBufferFallbackFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars client_name() const { return at<1>().as_string(); }
+  bool has_error() const { return at<2>().valid(); }
+  int64_t error() const { return at<2>().as_int64(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_heap_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<4>().as_string(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint64_t len() const { return at<5>().as_uint64(); }
+  bool has_mask() const { return at<6>().valid(); }
+  uint32_t mask() const { return at<6>().as_uint32(); }
+};
+
+class IonAllocBufferFallbackFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonAllocBufferFallbackFtraceEvent_Decoder;
+  enum : int32_t {
+    kClientNameFieldNumber = 1,
+    kErrorFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kHeapNameFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kMaskFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonAllocBufferFallbackFtraceEvent"; }
+
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_ClientName kClientName{};
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, size);
+  }
+  void set_client_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, chars.data, chars.size);
+  }
+  void set_client_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mask =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferFallbackFtraceEvent>;
+
+  static constexpr FieldMetadata_Mask kMask{};
+  void set_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonAllocBufferFailFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonAllocBufferFailFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonAllocBufferFailFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonAllocBufferFailFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars client_name() const { return at<1>().as_string(); }
+  bool has_error() const { return at<2>().valid(); }
+  int64_t error() const { return at<2>().as_int64(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_heap_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<4>().as_string(); }
+  bool has_len() const { return at<5>().valid(); }
+  uint64_t len() const { return at<5>().as_uint64(); }
+  bool has_mask() const { return at<6>().valid(); }
+  uint32_t mask() const { return at<6>().as_uint32(); }
+};
+
+class IonAllocBufferFailFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonAllocBufferFailFtraceEvent_Decoder;
+  enum : int32_t {
+    kClientNameFieldNumber = 1,
+    kErrorFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kHeapNameFieldNumber = 4,
+    kLenFieldNumber = 5,
+    kMaskFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonAllocBufferFailFtraceEvent"; }
+
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_ClientName kClientName{};
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, size);
+  }
+  void set_client_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, chars.data, chars.size);
+  }
+  void set_client_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mask =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Mask kMask{};
+  void set_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IonAllocBufferEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IonAllocBufferEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IonAllocBufferEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IonAllocBufferEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars client_name() const { return at<1>().as_string(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_heap_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<3>().as_string(); }
+  bool has_len() const { return at<4>().valid(); }
+  uint64_t len() const { return at<4>().as_uint64(); }
+  bool has_mask() const { return at<5>().valid(); }
+  uint32_t mask() const { return at<5>().as_uint32(); }
+};
+
+class IonAllocBufferEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IonAllocBufferEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kClientNameFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kHeapNameFieldNumber = 3,
+    kLenFieldNumber = 4,
+    kMaskFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IonAllocBufferEndFtraceEvent"; }
+
+
+  using FieldMetadata_ClientName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_ClientName kClientName{};
+  void set_client_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, data, size);
+  }
+  void set_client_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ClientName::kFieldId, chars.data, chars.size);
+  }
+  void set_client_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      IonAllocBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IonAllocBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mask =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IonAllocBufferEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Mask kMask{};
+  void set_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IommuSecPtblMapRangeStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IommuSecPtblMapRangeStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IommuSecPtblMapRangeStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IommuSecPtblMapRangeStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint64_t len() const { return at<1>().as_uint64(); }
+  bool has_num() const { return at<2>().valid(); }
+  int32_t num() const { return at<2>().as_int32(); }
+  bool has_pa() const { return at<3>().valid(); }
+  uint32_t pa() const { return at<3>().as_uint32(); }
+  bool has_sec_id() const { return at<4>().valid(); }
+  int32_t sec_id() const { return at<4>().as_int32(); }
+  bool has_va() const { return at<5>().valid(); }
+  uint64_t va() const { return at<5>().as_uint64(); }
+};
+
+class IommuSecPtblMapRangeStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IommuSecPtblMapRangeStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kNumFieldNumber = 2,
+    kPaFieldNumber = 3,
+    kSecIdFieldNumber = 4,
+    kVaFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IommuSecPtblMapRangeStartFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Num kNum{};
+  void set_num(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Num::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pa =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Pa kPa{};
+  void set_pa(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pa::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SecId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  static constexpr FieldMetadata_SecId kSecId{};
+  void set_sec_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SecId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Va =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuSecPtblMapRangeStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Va kVa{};
+  void set_va(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Va::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IommuSecPtblMapRangeEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IommuSecPtblMapRangeEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IommuSecPtblMapRangeEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IommuSecPtblMapRangeEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint64_t len() const { return at<1>().as_uint64(); }
+  bool has_num() const { return at<2>().valid(); }
+  int32_t num() const { return at<2>().as_int32(); }
+  bool has_pa() const { return at<3>().valid(); }
+  uint32_t pa() const { return at<3>().as_uint32(); }
+  bool has_sec_id() const { return at<4>().valid(); }
+  int32_t sec_id() const { return at<4>().as_int32(); }
+  bool has_va() const { return at<5>().valid(); }
+  uint64_t va() const { return at<5>().as_uint64(); }
+};
+
+class IommuSecPtblMapRangeEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IommuSecPtblMapRangeEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kNumFieldNumber = 2,
+    kPaFieldNumber = 3,
+    kSecIdFieldNumber = 4,
+    kVaFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IommuSecPtblMapRangeEndFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Num kNum{};
+  void set_num(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Num::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pa =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Pa kPa{};
+  void set_pa(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pa::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SecId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  static constexpr FieldMetadata_SecId kSecId{};
+  void set_sec_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SecId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Va =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuSecPtblMapRangeEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Va kVa{};
+  void set_va(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Va::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class IommuMapRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  IommuMapRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit IommuMapRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit IommuMapRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chunk_size() const { return at<1>().valid(); }
+  uint64_t chunk_size() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_pa() const { return at<3>().valid(); }
+  uint64_t pa() const { return at<3>().as_uint64(); }
+  bool has_va() const { return at<4>().valid(); }
+  uint64_t va() const { return at<4>().as_uint64(); }
+};
+
+class IommuMapRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = IommuMapRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kChunkSizeFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kPaFieldNumber = 3,
+    kVaFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.IommuMapRangeFtraceEvent"; }
+
+
+  using FieldMetadata_ChunkSize =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuMapRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_ChunkSize kChunkSize{};
+  void set_chunk_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChunkSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuMapRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pa =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuMapRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Pa kPa{};
+  void set_pa(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pa::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Va =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      IommuMapRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Va kVa{};
+  void set_va(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Va::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DmaAllocContiguousRetryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DmaAllocContiguousRetryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DmaAllocContiguousRetryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DmaAllocContiguousRetryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tries() const { return at<1>().valid(); }
+  int32_t tries() const { return at<1>().as_int32(); }
+};
+
+class DmaAllocContiguousRetryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DmaAllocContiguousRetryFtraceEvent_Decoder;
+  enum : int32_t {
+    kTriesFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DmaAllocContiguousRetryFtraceEvent"; }
+
+
+  using FieldMetadata_Tries =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      DmaAllocContiguousRetryFtraceEvent>;
+
+  static constexpr FieldMetadata_Tries kTries{};
+  void set_tries(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tries::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AllocPagesSysStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesSysStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesSysStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesSysStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesSysStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesSysStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesSysStartFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysStartFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AllocPagesSysFailFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesSysFailFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesSysFailFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesSysFailFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesSysFailFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesSysFailFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesSysFailFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysFailFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AllocPagesSysEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesSysEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesSysEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesSysEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesSysEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesSysEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesSysEndFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysEndFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesSysEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AllocPagesIommuStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesIommuStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesIommuStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesIommuStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesIommuStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesIommuStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesIommuStartFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuStartFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AllocPagesIommuFailFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesIommuFailFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesIommuFailFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesIommuFailFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesIommuFailFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesIommuFailFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesIommuFailFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuFailFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuFailFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class AllocPagesIommuEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AllocPagesIommuEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AllocPagesIommuEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AllocPagesIommuEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfp_flags() const { return at<1>().valid(); }
+  uint32_t gfp_flags() const { return at<1>().as_uint32(); }
+  bool has_order() const { return at<2>().valid(); }
+  uint32_t order() const { return at<2>().as_uint32(); }
+};
+
+class AllocPagesIommuEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = AllocPagesIommuEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfpFlagsFieldNumber = 1,
+    kOrderFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AllocPagesIommuEndFtraceEvent"; }
+
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuEndFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      AllocPagesIommuEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/kvm.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_KVM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_KVM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class VgicUpdateIrqPendingFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VgicUpdateIrqPendingFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VgicUpdateIrqPendingFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VgicUpdateIrqPendingFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  uint32_t irq() const { return at<1>().as_uint32(); }
+  bool has_level() const { return at<2>().valid(); }
+  uint32_t level() const { return at<2>().as_uint32(); }
+  bool has_vcpu_id() const { return at<3>().valid(); }
+  uint64_t vcpu_id() const { return at<3>().as_uint64(); }
+};
+
+class VgicUpdateIrqPendingFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VgicUpdateIrqPendingFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+    kLevelFieldNumber = 2,
+    kVcpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VgicUpdateIrqPendingFtraceEvent"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VgicUpdateIrqPendingFtraceEvent>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VgicUpdateIrqPendingFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VgicUpdateIrqPendingFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuId kVcpuId{};
+  void set_vcpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrapRegFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrapRegFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrapRegFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrapRegFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_fn() const { return at<1>().valid(); }
+  ::protozero::ConstChars fn() const { return at<1>().as_string(); }
+  bool has_is_write() const { return at<2>().valid(); }
+  uint32_t is_write() const { return at<2>().as_uint32(); }
+  bool has_reg() const { return at<3>().valid(); }
+  int32_t reg() const { return at<3>().as_int32(); }
+  bool has_write_value() const { return at<4>().valid(); }
+  uint64_t write_value() const { return at<4>().as_uint64(); }
+};
+
+class TrapRegFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrapRegFtraceEvent_Decoder;
+  enum : int32_t {
+    kFnFieldNumber = 1,
+    kIsWriteFieldNumber = 2,
+    kRegFieldNumber = 3,
+    kWriteValueFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrapRegFtraceEvent"; }
+
+
+  using FieldMetadata_Fn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrapRegFtraceEvent>;
+
+  static constexpr FieldMetadata_Fn kFn{};
+  void set_fn(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Fn::kFieldId, data, size);
+  }
+  void set_fn(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Fn::kFieldId, chars.data, chars.size);
+  }
+  void set_fn(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrapRegFtraceEvent>;
+
+  static constexpr FieldMetadata_IsWrite kIsWrite{};
+  void set_is_write(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsWrite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Reg =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrapRegFtraceEvent>;
+
+  static constexpr FieldMetadata_Reg kReg{};
+  void set_reg(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WriteValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrapRegFtraceEvent>;
+
+  static constexpr FieldMetadata_WriteValue kWriteValue{};
+  void set_write_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriteValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmWfxArm64FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmWfxArm64FtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmWfxArm64FtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmWfxArm64FtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_is_wfe() const { return at<1>().valid(); }
+  uint32_t is_wfe() const { return at<1>().as_uint32(); }
+  bool has_vcpu_pc() const { return at<2>().valid(); }
+  uint64_t vcpu_pc() const { return at<2>().as_uint64(); }
+};
+
+class KvmWfxArm64FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmWfxArm64FtraceEvent_Decoder;
+  enum : int32_t {
+    kIsWfeFieldNumber = 1,
+    kVcpuPcFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmWfxArm64FtraceEvent"; }
+
+
+  using FieldMetadata_IsWfe =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmWfxArm64FtraceEvent>;
+
+  static constexpr FieldMetadata_IsWfe kIsWfe{};
+  void set_is_wfe(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsWfe::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmWfxArm64FtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmVcpuWakeupFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmVcpuWakeupFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmVcpuWakeupFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmVcpuWakeupFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ns() const { return at<1>().valid(); }
+  uint64_t ns() const { return at<1>().as_uint64(); }
+  bool has_valid() const { return at<2>().valid(); }
+  uint32_t valid() const { return at<2>().as_uint32(); }
+  bool has_waited() const { return at<3>().valid(); }
+  uint32_t waited() const { return at<3>().as_uint32(); }
+};
+
+class KvmVcpuWakeupFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmVcpuWakeupFtraceEvent_Decoder;
+  enum : int32_t {
+    kNsFieldNumber = 1,
+    kValidFieldNumber = 2,
+    kWaitedFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmVcpuWakeupFtraceEvent"; }
+
+
+  using FieldMetadata_Ns =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmVcpuWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Ns kNs{};
+  void set_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ns::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Valid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmVcpuWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Valid kValid{};
+  void set_valid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Valid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Waited =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmVcpuWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Waited kWaited{};
+  void set_waited(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Waited::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmUserspaceExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmUserspaceExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmUserspaceExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmUserspaceExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_reason() const { return at<1>().valid(); }
+  uint32_t reason() const { return at<1>().as_uint32(); }
+};
+
+class KvmUserspaceExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmUserspaceExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kReasonFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmUserspaceExitFtraceEvent"; }
+
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmUserspaceExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmUnmapHvaRangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmUnmapHvaRangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmUnmapHvaRangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmUnmapHvaRangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_end() const { return at<1>().valid(); }
+  uint64_t end() const { return at<1>().as_uint64(); }
+  bool has_start() const { return at<2>().valid(); }
+  uint64_t start() const { return at<2>().as_uint64(); }
+};
+
+class KvmUnmapHvaRangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmUnmapHvaRangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kEndFieldNumber = 1,
+    kStartFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmUnmapHvaRangeFtraceEvent"; }
+
+
+  using FieldMetadata_End =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmUnmapHvaRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmUnmapHvaRangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmToggleCacheFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmToggleCacheFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmToggleCacheFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmToggleCacheFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_now() const { return at<1>().valid(); }
+  uint32_t now() const { return at<1>().as_uint32(); }
+  bool has_vcpu_pc() const { return at<2>().valid(); }
+  uint64_t vcpu_pc() const { return at<2>().as_uint64(); }
+  bool has_was() const { return at<3>().valid(); }
+  uint32_t was() const { return at<3>().as_uint32(); }
+};
+
+class KvmToggleCacheFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmToggleCacheFtraceEvent_Decoder;
+  enum : int32_t {
+    kNowFieldNumber = 1,
+    kVcpuPcFieldNumber = 2,
+    kWasFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmToggleCacheFtraceEvent"; }
+
+
+  using FieldMetadata_Now =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmToggleCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Now kNow{};
+  void set_now(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Now::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmToggleCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Was =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmToggleCacheFtraceEvent>;
+
+  static constexpr FieldMetadata_Was kWas{};
+  void set_was(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Was::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmTimerUpdateIrqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTimerUpdateIrqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTimerUpdateIrqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTimerUpdateIrqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  uint32_t irq() const { return at<1>().as_uint32(); }
+  bool has_level() const { return at<2>().valid(); }
+  int32_t level() const { return at<2>().as_int32(); }
+  bool has_vcpu_id() const { return at<3>().valid(); }
+  uint64_t vcpu_id() const { return at<3>().as_uint64(); }
+};
+
+class KvmTimerUpdateIrqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTimerUpdateIrqFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+    kLevelFieldNumber = 2,
+    kVcpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTimerUpdateIrqFtraceEvent"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmTimerUpdateIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmTimerUpdateIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTimerUpdateIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuId kVcpuId{};
+  void set_vcpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmTimerSaveStateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTimerSaveStateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTimerSaveStateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTimerSaveStateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl() const { return at<1>().valid(); }
+  uint64_t ctl() const { return at<1>().as_uint64(); }
+  bool has_cval() const { return at<2>().valid(); }
+  uint64_t cval() const { return at<2>().as_uint64(); }
+  bool has_timer_idx() const { return at<3>().valid(); }
+  int32_t timer_idx() const { return at<3>().as_int32(); }
+};
+
+class KvmTimerSaveStateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTimerSaveStateFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlFieldNumber = 1,
+    kCvalFieldNumber = 2,
+    kTimerIdxFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTimerSaveStateFtraceEvent"; }
+
+
+  using FieldMetadata_Ctl =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTimerSaveStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctl kCtl{};
+  void set_ctl(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctl::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cval =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTimerSaveStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Cval kCval{};
+  void set_cval(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cval::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimerIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmTimerSaveStateFtraceEvent>;
+
+  static constexpr FieldMetadata_TimerIdx kTimerIdx{};
+  void set_timer_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimerIdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmTimerRestoreStateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTimerRestoreStateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTimerRestoreStateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTimerRestoreStateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl() const { return at<1>().valid(); }
+  uint64_t ctl() const { return at<1>().as_uint64(); }
+  bool has_cval() const { return at<2>().valid(); }
+  uint64_t cval() const { return at<2>().as_uint64(); }
+  bool has_timer_idx() const { return at<3>().valid(); }
+  int32_t timer_idx() const { return at<3>().as_int32(); }
+};
+
+class KvmTimerRestoreStateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTimerRestoreStateFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlFieldNumber = 1,
+    kCvalFieldNumber = 2,
+    kTimerIdxFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTimerRestoreStateFtraceEvent"; }
+
+
+  using FieldMetadata_Ctl =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTimerRestoreStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctl kCtl{};
+  void set_ctl(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctl::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cval =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTimerRestoreStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Cval kCval{};
+  void set_cval(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cval::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimerIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmTimerRestoreStateFtraceEvent>;
+
+  static constexpr FieldMetadata_TimerIdx kTimerIdx{};
+  void set_timer_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimerIdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmTimerHrtimerExpireFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTimerHrtimerExpireFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTimerHrtimerExpireFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTimerHrtimerExpireFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timer_idx() const { return at<1>().valid(); }
+  int32_t timer_idx() const { return at<1>().as_int32(); }
+};
+
+class KvmTimerHrtimerExpireFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTimerHrtimerExpireFtraceEvent_Decoder;
+  enum : int32_t {
+    kTimerIdxFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTimerHrtimerExpireFtraceEvent"; }
+
+
+  using FieldMetadata_TimerIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmTimerHrtimerExpireFtraceEvent>;
+
+  static constexpr FieldMetadata_TimerIdx kTimerIdx{};
+  void set_timer_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimerIdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmTimerEmulateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTimerEmulateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTimerEmulateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTimerEmulateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_should_fire() const { return at<1>().valid(); }
+  uint32_t should_fire() const { return at<1>().as_uint32(); }
+  bool has_timer_idx() const { return at<2>().valid(); }
+  int32_t timer_idx() const { return at<2>().as_int32(); }
+};
+
+class KvmTimerEmulateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTimerEmulateFtraceEvent_Decoder;
+  enum : int32_t {
+    kShouldFireFieldNumber = 1,
+    kTimerIdxFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTimerEmulateFtraceEvent"; }
+
+
+  using FieldMetadata_ShouldFire =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmTimerEmulateFtraceEvent>;
+
+  static constexpr FieldMetadata_ShouldFire kShouldFire{};
+  void set_should_fire(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShouldFire::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimerIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmTimerEmulateFtraceEvent>;
+
+  static constexpr FieldMetadata_TimerIdx kTimerIdx{};
+  void set_timer_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimerIdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmTestAgeHvaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmTestAgeHvaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmTestAgeHvaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmTestAgeHvaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_hva() const { return at<1>().valid(); }
+  uint64_t hva() const { return at<1>().as_uint64(); }
+};
+
+class KvmTestAgeHvaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmTestAgeHvaFtraceEvent_Decoder;
+  enum : int32_t {
+    kHvaFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmTestAgeHvaFtraceEvent"; }
+
+
+  using FieldMetadata_Hva =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmTestAgeHvaFtraceEvent>;
+
+  static constexpr FieldMetadata_Hva kHva{};
+  void set_hva(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hva::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmSysAccessFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmSysAccessFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmSysAccessFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmSysAccessFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_crm() const { return at<1>().valid(); }
+  uint32_t crm() const { return at<1>().as_uint32(); }
+  bool has_crn() const { return at<2>().valid(); }
+  uint32_t crn() const { return at<2>().as_uint32(); }
+  bool has_op0() const { return at<3>().valid(); }
+  uint32_t op0() const { return at<3>().as_uint32(); }
+  bool has_op1() const { return at<4>().valid(); }
+  uint32_t op1() const { return at<4>().as_uint32(); }
+  bool has_op2() const { return at<5>().valid(); }
+  uint32_t op2() const { return at<5>().as_uint32(); }
+  bool has_is_write() const { return at<6>().valid(); }
+  uint32_t is_write() const { return at<6>().as_uint32(); }
+  bool has_name() const { return at<7>().valid(); }
+  ::protozero::ConstChars name() const { return at<7>().as_string(); }
+  bool has_vcpu_pc() const { return at<8>().valid(); }
+  uint64_t vcpu_pc() const { return at<8>().as_uint64(); }
+};
+
+class KvmSysAccessFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmSysAccessFtraceEvent_Decoder;
+  enum : int32_t {
+    kCRmFieldNumber = 1,
+    kCRnFieldNumber = 2,
+    kOp0FieldNumber = 3,
+    kOp1FieldNumber = 4,
+    kOp2FieldNumber = 5,
+    kIsWriteFieldNumber = 6,
+    kNameFieldNumber = 7,
+    kVcpuPcFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmSysAccessFtraceEvent"; }
+
+
+  using FieldMetadata_CRm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_CRm kCRm{};
+  void set_crm(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CRm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CRn =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_CRn kCRn{};
+  void set_crn(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CRn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Op0 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_Op0 kOp0{};
+  void set_op0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Op0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Op1 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_Op1 kOp1{};
+  void set_op1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Op1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Op2 =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_Op2 kOp2{};
+  void set_op2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Op2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsWrite =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_IsWrite kIsWrite{};
+  void set_is_write(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsWrite::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmSysAccessFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmSetWayFlushFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmSetWayFlushFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmSetWayFlushFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmSetWayFlushFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cache() const { return at<1>().valid(); }
+  uint32_t cache() const { return at<1>().as_uint32(); }
+  bool has_vcpu_pc() const { return at<2>().valid(); }
+  uint64_t vcpu_pc() const { return at<2>().as_uint64(); }
+};
+
+class KvmSetWayFlushFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmSetWayFlushFtraceEvent_Decoder;
+  enum : int32_t {
+    kCacheFieldNumber = 1,
+    kVcpuPcFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmSetWayFlushFtraceEvent"; }
+
+
+  using FieldMetadata_Cache =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSetWayFlushFtraceEvent>;
+
+  static constexpr FieldMetadata_Cache kCache{};
+  void set_cache(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cache::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmSetWayFlushFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmSetSpteHvaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmSetSpteHvaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmSetSpteHvaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmSetSpteHvaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_hva() const { return at<1>().valid(); }
+  uint64_t hva() const { return at<1>().as_uint64(); }
+};
+
+class KvmSetSpteHvaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmSetSpteHvaFtraceEvent_Decoder;
+  enum : int32_t {
+    kHvaFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmSetSpteHvaFtraceEvent"; }
+
+
+  using FieldMetadata_Hva =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmSetSpteHvaFtraceEvent>;
+
+  static constexpr FieldMetadata_Hva kHva{};
+  void set_hva(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hva::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmSetIrqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmSetIrqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmSetIrqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmSetIrqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gsi() const { return at<1>().valid(); }
+  uint32_t gsi() const { return at<1>().as_uint32(); }
+  bool has_irq_source_id() const { return at<2>().valid(); }
+  int32_t irq_source_id() const { return at<2>().as_int32(); }
+  bool has_level() const { return at<3>().valid(); }
+  int32_t level() const { return at<3>().as_int32(); }
+};
+
+class KvmSetIrqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmSetIrqFtraceEvent_Decoder;
+  enum : int32_t {
+    kGsiFieldNumber = 1,
+    kIrqSourceIdFieldNumber = 2,
+    kLevelFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmSetIrqFtraceEvent"; }
+
+
+  using FieldMetadata_Gsi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSetIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Gsi kGsi{};
+  void set_gsi(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Gsi::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IrqSourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmSetIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_IrqSourceId kIrqSourceId{};
+  void set_irq_source_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IrqSourceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmSetIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmSetGuestDebugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmSetGuestDebugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmSetGuestDebugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmSetGuestDebugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_guest_debug() const { return at<1>().valid(); }
+  uint32_t guest_debug() const { return at<1>().as_uint32(); }
+  bool has_vcpu() const { return at<2>().valid(); }
+  uint64_t vcpu() const { return at<2>().as_uint64(); }
+};
+
+class KvmSetGuestDebugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmSetGuestDebugFtraceEvent_Decoder;
+  enum : int32_t {
+    kGuestDebugFieldNumber = 1,
+    kVcpuFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmSetGuestDebugFtraceEvent"; }
+
+
+  using FieldMetadata_GuestDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmSetGuestDebugFtraceEvent>;
+
+  static constexpr FieldMetadata_GuestDebug kGuestDebug{};
+  void set_guest_debug(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GuestDebug::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Vcpu =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmSetGuestDebugFtraceEvent>;
+
+  static constexpr FieldMetadata_Vcpu kVcpu{};
+  void set_vcpu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vcpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmMmioEmulateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmMmioEmulateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmMmioEmulateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmMmioEmulateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpsr() const { return at<1>().valid(); }
+  uint64_t cpsr() const { return at<1>().as_uint64(); }
+  bool has_instr() const { return at<2>().valid(); }
+  uint64_t instr() const { return at<2>().as_uint64(); }
+  bool has_vcpu_pc() const { return at<3>().valid(); }
+  uint64_t vcpu_pc() const { return at<3>().as_uint64(); }
+};
+
+class KvmMmioEmulateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmMmioEmulateFtraceEvent_Decoder;
+  enum : int32_t {
+    kCpsrFieldNumber = 1,
+    kInstrFieldNumber = 2,
+    kVcpuPcFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmMmioEmulateFtraceEvent"; }
+
+
+  using FieldMetadata_Cpsr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmMmioEmulateFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpsr kCpsr{};
+  void set_cpsr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpsr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Instr =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmMmioEmulateFtraceEvent>;
+
+  static constexpr FieldMetadata_Instr kInstr{};
+  void set_instr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Instr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmMmioEmulateFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmMmioFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmMmioFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmMmioFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmMmioFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gpa() const { return at<1>().valid(); }
+  uint64_t gpa() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint32_t len() const { return at<2>().as_uint32(); }
+  bool has_type() const { return at<3>().valid(); }
+  uint32_t type() const { return at<3>().as_uint32(); }
+  bool has_val() const { return at<4>().valid(); }
+  uint64_t val() const { return at<4>().as_uint64(); }
+};
+
+class KvmMmioFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmMmioFtraceEvent_Decoder;
+  enum : int32_t {
+    kGpaFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kValFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmMmioFtraceEvent"; }
+
+
+  using FieldMetadata_Gpa =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmMmioFtraceEvent>;
+
+  static constexpr FieldMetadata_Gpa kGpa{};
+  void set_gpa(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Gpa::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmMmioFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmMmioFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Val =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmMmioFtraceEvent>;
+
+  static constexpr FieldMetadata_Val kVal{};
+  void set_val(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Val::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmIrqLineFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmIrqLineFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmIrqLineFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmIrqLineFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq_num() const { return at<1>().valid(); }
+  int32_t irq_num() const { return at<1>().as_int32(); }
+  bool has_level() const { return at<2>().valid(); }
+  int32_t level() const { return at<2>().as_int32(); }
+  bool has_type() const { return at<3>().valid(); }
+  uint32_t type() const { return at<3>().as_uint32(); }
+  bool has_vcpu_idx() const { return at<4>().valid(); }
+  int32_t vcpu_idx() const { return at<4>().as_int32(); }
+};
+
+class KvmIrqLineFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmIrqLineFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqNumFieldNumber = 1,
+    kLevelFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kVcpuIdxFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmIrqLineFtraceEvent"; }
+
+
+  using FieldMetadata_IrqNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmIrqLineFtraceEvent>;
+
+  static constexpr FieldMetadata_IrqNum kIrqNum{};
+  void set_irq_num(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IrqNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmIrqLineFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmIrqLineFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuIdx =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmIrqLineFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuIdx kVcpuIdx{};
+  void set_vcpu_idx(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuIdx::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmHvcArm64FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmHvcArm64FtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmHvcArm64FtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmHvcArm64FtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_imm() const { return at<1>().valid(); }
+  uint64_t imm() const { return at<1>().as_uint64(); }
+  bool has_r0() const { return at<2>().valid(); }
+  uint64_t r0() const { return at<2>().as_uint64(); }
+  bool has_vcpu_pc() const { return at<3>().valid(); }
+  uint64_t vcpu_pc() const { return at<3>().as_uint64(); }
+};
+
+class KvmHvcArm64FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmHvcArm64FtraceEvent_Decoder;
+  enum : int32_t {
+    kImmFieldNumber = 1,
+    kR0FieldNumber = 2,
+    kVcpuPcFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmHvcArm64FtraceEvent"; }
+
+
+  using FieldMetadata_Imm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmHvcArm64FtraceEvent>;
+
+  static constexpr FieldMetadata_Imm kImm{};
+  void set_imm(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Imm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_R0 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmHvcArm64FtraceEvent>;
+
+  static constexpr FieldMetadata_R0 kR0{};
+  void set_r0(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmHvcArm64FtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmHandleSysRegFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmHandleSysRegFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmHandleSysRegFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmHandleSysRegFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_hsr() const { return at<1>().valid(); }
+  uint64_t hsr() const { return at<1>().as_uint64(); }
+};
+
+class KvmHandleSysRegFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmHandleSysRegFtraceEvent_Decoder;
+  enum : int32_t {
+    kHsrFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmHandleSysRegFtraceEvent"; }
+
+
+  using FieldMetadata_Hsr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmHandleSysRegFtraceEvent>;
+
+  static constexpr FieldMetadata_Hsr kHsr{};
+  void set_hsr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hsr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmGuestFaultFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmGuestFaultFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmGuestFaultFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmGuestFaultFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_hsr() const { return at<1>().valid(); }
+  uint64_t hsr() const { return at<1>().as_uint64(); }
+  bool has_hxfar() const { return at<2>().valid(); }
+  uint64_t hxfar() const { return at<2>().as_uint64(); }
+  bool has_ipa() const { return at<3>().valid(); }
+  uint64_t ipa() const { return at<3>().as_uint64(); }
+  bool has_vcpu_pc() const { return at<4>().valid(); }
+  uint64_t vcpu_pc() const { return at<4>().as_uint64(); }
+};
+
+class KvmGuestFaultFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmGuestFaultFtraceEvent_Decoder;
+  enum : int32_t {
+    kHsrFieldNumber = 1,
+    kHxfarFieldNumber = 2,
+    kIpaFieldNumber = 3,
+    kVcpuPcFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmGuestFaultFtraceEvent"; }
+
+
+  using FieldMetadata_Hsr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmGuestFaultFtraceEvent>;
+
+  static constexpr FieldMetadata_Hsr kHsr{};
+  void set_hsr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hsr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Hxfar =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmGuestFaultFtraceEvent>;
+
+  static constexpr FieldMetadata_Hxfar kHxfar{};
+  void set_hxfar(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hxfar::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ipa =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmGuestFaultFtraceEvent>;
+
+  static constexpr FieldMetadata_Ipa kIpa{};
+  void set_ipa(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ipa::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmGuestFaultFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmGetTimerMapFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmGetTimerMapFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmGetTimerMapFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmGetTimerMapFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_direct_ptimer() const { return at<1>().valid(); }
+  int32_t direct_ptimer() const { return at<1>().as_int32(); }
+  bool has_direct_vtimer() const { return at<2>().valid(); }
+  int32_t direct_vtimer() const { return at<2>().as_int32(); }
+  bool has_emul_ptimer() const { return at<3>().valid(); }
+  int32_t emul_ptimer() const { return at<3>().as_int32(); }
+  bool has_vcpu_id() const { return at<4>().valid(); }
+  uint64_t vcpu_id() const { return at<4>().as_uint64(); }
+};
+
+class KvmGetTimerMapFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmGetTimerMapFtraceEvent_Decoder;
+  enum : int32_t {
+    kDirectPtimerFieldNumber = 1,
+    kDirectVtimerFieldNumber = 2,
+    kEmulPtimerFieldNumber = 3,
+    kVcpuIdFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmGetTimerMapFtraceEvent"; }
+
+
+  using FieldMetadata_DirectPtimer =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmGetTimerMapFtraceEvent>;
+
+  static constexpr FieldMetadata_DirectPtimer kDirectPtimer{};
+  void set_direct_ptimer(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DirectPtimer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DirectVtimer =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmGetTimerMapFtraceEvent>;
+
+  static constexpr FieldMetadata_DirectVtimer kDirectVtimer{};
+  void set_direct_vtimer(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DirectVtimer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EmulPtimer =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmGetTimerMapFtraceEvent>;
+
+  static constexpr FieldMetadata_EmulPtimer kEmulPtimer{};
+  void set_emul_ptimer(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EmulPtimer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmGetTimerMapFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuId kVcpuId{};
+  void set_vcpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmFpuFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmFpuFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmFpuFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmFpuFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_load() const { return at<1>().valid(); }
+  uint32_t load() const { return at<1>().as_uint32(); }
+};
+
+class KvmFpuFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmFpuFtraceEvent_Decoder;
+  enum : int32_t {
+    kLoadFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmFpuFtraceEvent"; }
+
+
+  using FieldMetadata_Load =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmFpuFtraceEvent>;
+
+  static constexpr FieldMetadata_Load kLoad{};
+  void set_load(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Load::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_esr_ec() const { return at<1>().valid(); }
+  uint32_t esr_ec() const { return at<1>().as_uint32(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int32_t ret() const { return at<2>().as_int32(); }
+  bool has_vcpu_pc() const { return at<3>().valid(); }
+  uint64_t vcpu_pc() const { return at<3>().as_uint64(); }
+};
+
+class KvmExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kEsrEcFieldNumber = 1,
+    kRetFieldNumber = 2,
+    kVcpuPcFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmExitFtraceEvent"; }
+
+
+  using FieldMetadata_EsrEc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmExitFtraceEvent>;
+
+  static constexpr FieldMetadata_EsrEc kEsrEc{};
+  void set_esr_ec(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EsrEc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmExitFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_vcpu_pc() const { return at<1>().valid(); }
+  uint64_t vcpu_pc() const { return at<1>().as_uint64(); }
+};
+
+class KvmEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kVcpuPcFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmEntryFtraceEvent"; }
+
+
+  using FieldMetadata_VcpuPc =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_VcpuPc kVcpuPc{};
+  void set_vcpu_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VcpuPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmArmSetupDebugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmArmSetupDebugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmArmSetupDebugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmArmSetupDebugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_guest_debug() const { return at<1>().valid(); }
+  uint32_t guest_debug() const { return at<1>().as_uint32(); }
+  bool has_vcpu() const { return at<2>().valid(); }
+  uint64_t vcpu() const { return at<2>().as_uint64(); }
+};
+
+class KvmArmSetupDebugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmArmSetupDebugFtraceEvent_Decoder;
+  enum : int32_t {
+    kGuestDebugFieldNumber = 1,
+    kVcpuFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmArmSetupDebugFtraceEvent"; }
+
+
+  using FieldMetadata_GuestDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmArmSetupDebugFtraceEvent>;
+
+  static constexpr FieldMetadata_GuestDebug kGuestDebug{};
+  void set_guest_debug(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GuestDebug::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Vcpu =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmArmSetupDebugFtraceEvent>;
+
+  static constexpr FieldMetadata_Vcpu kVcpu{};
+  void set_vcpu(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vcpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmArmSetRegsetFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmArmSetRegsetFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmArmSetRegsetFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmArmSetRegsetFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  int32_t len() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class KvmArmSetRegsetFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmArmSetRegsetFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmArmSetRegsetFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      KvmArmSetRegsetFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      KvmArmSetRegsetFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmArmSetDreg32FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmArmSetDreg32FtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmArmSetDreg32FtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmArmSetDreg32FtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  uint32_t value() const { return at<2>().as_uint32(); }
+};
+
+class KvmArmSetDreg32FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmArmSetDreg32FtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmArmSetDreg32FtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      KvmArmSetDreg32FtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmArmSetDreg32FtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmArmClearDebugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmArmClearDebugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmArmClearDebugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmArmClearDebugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_guest_debug() const { return at<1>().valid(); }
+  uint32_t guest_debug() const { return at<1>().as_uint32(); }
+};
+
+class KvmArmClearDebugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmArmClearDebugFtraceEvent_Decoder;
+  enum : int32_t {
+    kGuestDebugFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmArmClearDebugFtraceEvent"; }
+
+
+  using FieldMetadata_GuestDebug =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmArmClearDebugFtraceEvent>;
+
+  static constexpr FieldMetadata_GuestDebug kGuestDebug{};
+  void set_guest_debug(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GuestDebug::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmAgePageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmAgePageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmAgePageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmAgePageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gfn() const { return at<1>().valid(); }
+  uint64_t gfn() const { return at<1>().as_uint64(); }
+  bool has_hva() const { return at<2>().valid(); }
+  uint64_t hva() const { return at<2>().as_uint64(); }
+  bool has_level() const { return at<3>().valid(); }
+  uint32_t level() const { return at<3>().as_uint32(); }
+  bool has_referenced() const { return at<4>().valid(); }
+  uint32_t referenced() const { return at<4>().as_uint32(); }
+};
+
+class KvmAgePageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmAgePageFtraceEvent_Decoder;
+  enum : int32_t {
+    kGfnFieldNumber = 1,
+    kHvaFieldNumber = 2,
+    kLevelFieldNumber = 3,
+    kReferencedFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmAgePageFtraceEvent"; }
+
+
+  using FieldMetadata_Gfn =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmAgePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Gfn kGfn{};
+  void set_gfn(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Gfn::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Hva =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmAgePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Hva kHva{};
+  void set_hva(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hva::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Level =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmAgePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Level kLevel{};
+  void set_level(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Level::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Referenced =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmAgePageFtraceEvent>;
+
+  static constexpr FieldMetadata_Referenced kReferenced{};
+  void set_referenced(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Referenced::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmAgeHvaFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmAgeHvaFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmAgeHvaFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmAgeHvaFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_end() const { return at<1>().valid(); }
+  uint64_t end() const { return at<1>().as_uint64(); }
+  bool has_start() const { return at<2>().valid(); }
+  uint64_t start() const { return at<2>().as_uint64(); }
+};
+
+class KvmAgeHvaFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmAgeHvaFtraceEvent_Decoder;
+  enum : int32_t {
+    kEndFieldNumber = 1,
+    kStartFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmAgeHvaFtraceEvent"; }
+
+
+  using FieldMetadata_End =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmAgeHvaFtraceEvent>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmAgeHvaFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmAckIrqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmAckIrqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmAckIrqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmAckIrqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irqchip() const { return at<1>().valid(); }
+  uint32_t irqchip() const { return at<1>().as_uint32(); }
+  bool has_pin() const { return at<2>().valid(); }
+  uint32_t pin() const { return at<2>().as_uint32(); }
+};
+
+class KvmAckIrqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmAckIrqFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqchipFieldNumber = 1,
+    kPinFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmAckIrqFtraceEvent"; }
+
+
+  using FieldMetadata_Irqchip =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmAckIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Irqchip kIrqchip{};
+  void set_irqchip(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irqchip::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pin =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KvmAckIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Pin kPin{};
+  void set_pin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pin::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class KvmAccessFaultFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KvmAccessFaultFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KvmAccessFaultFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KvmAccessFaultFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ipa() const { return at<1>().valid(); }
+  uint64_t ipa() const { return at<1>().as_uint64(); }
+};
+
+class KvmAccessFaultFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KvmAccessFaultFtraceEvent_Decoder;
+  enum : int32_t {
+    kIpaFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KvmAccessFaultFtraceEvent"; }
+
+
+  using FieldMetadata_Ipa =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KvmAccessFaultFtraceEvent>;
+
+  static constexpr FieldMetadata_Ipa kIpa{};
+  void set_ipa(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ipa::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_LOWMEMORYKILLER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_LOWMEMORYKILLER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class LowmemoryKillFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LowmemoryKillFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LowmemoryKillFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LowmemoryKillFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_pagecache_size() const { return at<3>().valid(); }
+  int64_t pagecache_size() const { return at<3>().as_int64(); }
+  bool has_pagecache_limit() const { return at<4>().valid(); }
+  int64_t pagecache_limit() const { return at<4>().as_int64(); }
+  bool has_free() const { return at<5>().valid(); }
+  int64_t free() const { return at<5>().as_int64(); }
+};
+
+class LowmemoryKillFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = LowmemoryKillFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPagecacheSizeFieldNumber = 3,
+    kPagecacheLimitFieldNumber = 4,
+    kFreeFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LowmemoryKillFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LowmemoryKillFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LowmemoryKillFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PagecacheSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      LowmemoryKillFtraceEvent>;
+
+  static constexpr FieldMetadata_PagecacheSize kPagecacheSize{};
+  void set_pagecache_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagecacheSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PagecacheLimit =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      LowmemoryKillFtraceEvent>;
+
+  static constexpr FieldMetadata_PagecacheLimit kPagecacheLimit{};
+  void set_pagecache_limit(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PagecacheLimit::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Free =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      LowmemoryKillFtraceEvent>;
+
+  static constexpr FieldMetadata_Free kFree{};
+  void set_free(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Free::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/lwis.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_LWIS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_LWIS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class LwisTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LwisTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LwisTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LwisTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_lwis_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars lwis_name() const { return at<1>().as_string(); }
+  bool has_type() const { return at<2>().valid(); }
+  uint32_t type() const { return at<2>().as_uint32(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+  bool has_func_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars func_name() const { return at<4>().as_string(); }
+  bool has_value() const { return at<5>().valid(); }
+  int64_t value() const { return at<5>().as_int64(); }
+};
+
+class LwisTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = LwisTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kLwisNameFieldNumber = 1,
+    kTypeFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kFuncNameFieldNumber = 4,
+    kValueFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LwisTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_LwisName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LwisTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_LwisName kLwisName{};
+  void set_lwis_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LwisName::kFieldId, data, size);
+  }
+  void set_lwis_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LwisName::kFieldId, chars.data, chars.size);
+  }
+  void set_lwis_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LwisName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      LwisTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      LwisTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FuncName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LwisTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_FuncName kFuncName{};
+  void set_func_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FuncName::kFieldId, data, size);
+  }
+  void set_func_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FuncName::kFieldId, chars.data, chars.size);
+  }
+  void set_func_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FuncName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      LwisTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/mali.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MALI_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MALI_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class MaliMaliCSFINTERRUPTENDFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliCSFINTERRUPTENDFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliCSFINTERRUPTENDFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliCSFINTERRUPTENDFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_kctx_tgid() const { return at<1>().valid(); }
+  int32_t kctx_tgid() const { return at<1>().as_int32(); }
+  bool has_kctx_id() const { return at<2>().valid(); }
+  uint32_t kctx_id() const { return at<2>().as_uint32(); }
+  bool has_info_val() const { return at<3>().valid(); }
+  uint64_t info_val() const { return at<3>().as_uint64(); }
+};
+
+class MaliMaliCSFINTERRUPTENDFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliCSFINTERRUPTENDFtraceEvent_Decoder;
+  enum : int32_t {
+    kKctxTgidFieldNumber = 1,
+    kKctxIdFieldNumber = 2,
+    kInfoValFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliCSFINTERRUPTENDFtraceEvent"; }
+
+
+  using FieldMetadata_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliCSFINTERRUPTENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliCSFINTERRUPTENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliCSFINTERRUPTENDFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal kInfoVal{};
+  void set_info_val(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MaliMaliCSFINTERRUPTSTARTFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliCSFINTERRUPTSTARTFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliCSFINTERRUPTSTARTFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliCSFINTERRUPTSTARTFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_kctx_tgid() const { return at<1>().valid(); }
+  int32_t kctx_tgid() const { return at<1>().as_int32(); }
+  bool has_kctx_id() const { return at<2>().valid(); }
+  uint32_t kctx_id() const { return at<2>().as_uint32(); }
+  bool has_info_val() const { return at<3>().valid(); }
+  uint64_t info_val() const { return at<3>().as_uint64(); }
+};
+
+class MaliMaliCSFINTERRUPTSTARTFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliCSFINTERRUPTSTARTFtraceEvent_Decoder;
+  enum : int32_t {
+    kKctxTgidFieldNumber = 1,
+    kKctxIdFieldNumber = 2,
+    kInfoValFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliCSFINTERRUPTSTARTFtraceEvent"; }
+
+
+  using FieldMetadata_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliCSFINTERRUPTSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliCSFINTERRUPTSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliCSFINTERRUPTSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal kInfoVal{};
+  void set_info_val(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MaliMaliKCPUFENCEWAITENDFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUFENCEWAITENDFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUFENCEWAITENDFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUFENCEWAITENDFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_info_val1() const { return at<1>().valid(); }
+  uint64_t info_val1() const { return at<1>().as_uint64(); }
+  bool has_info_val2() const { return at<2>().valid(); }
+  uint64_t info_val2() const { return at<2>().as_uint64(); }
+  bool has_kctx_tgid() const { return at<3>().valid(); }
+  int32_t kctx_tgid() const { return at<3>().as_int32(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_id() const { return at<5>().valid(); }
+  uint32_t id() const { return at<5>().as_uint32(); }
+};
+
+class MaliMaliKCPUFENCEWAITENDFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUFENCEWAITENDFtraceEvent_Decoder;
+  enum : int32_t {
+    kInfoVal1FieldNumber = 1,
+    kInfoVal2FieldNumber = 2,
+    kKctxTgidFieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kIdFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUFENCEWAITENDFtraceEvent"; }
+
+
+  using FieldMetadata_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCEWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MaliMaliKCPUFENCEWAITSTARTFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUFENCEWAITSTARTFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUFENCEWAITSTARTFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUFENCEWAITSTARTFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_info_val1() const { return at<1>().valid(); }
+  uint64_t info_val1() const { return at<1>().as_uint64(); }
+  bool has_info_val2() const { return at<2>().valid(); }
+  uint64_t info_val2() const { return at<2>().as_uint64(); }
+  bool has_kctx_tgid() const { return at<3>().valid(); }
+  int32_t kctx_tgid() const { return at<3>().as_int32(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_id() const { return at<5>().valid(); }
+  uint32_t id() const { return at<5>().as_uint32(); }
+};
+
+class MaliMaliKCPUFENCEWAITSTARTFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUFENCEWAITSTARTFtraceEvent_Decoder;
+  enum : int32_t {
+    kInfoVal1FieldNumber = 1,
+    kInfoVal2FieldNumber = 2,
+    kKctxTgidFieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kIdFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUFENCEWAITSTARTFtraceEvent"; }
+
+
+  using FieldMetadata_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCEWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MaliMaliKCPUFENCESIGNALFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUFENCESIGNALFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUFENCESIGNALFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUFENCESIGNALFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_info_val1() const { return at<1>().valid(); }
+  uint64_t info_val1() const { return at<1>().as_uint64(); }
+  bool has_info_val2() const { return at<2>().valid(); }
+  uint64_t info_val2() const { return at<2>().as_uint64(); }
+  bool has_kctx_tgid() const { return at<3>().valid(); }
+  int32_t kctx_tgid() const { return at<3>().as_int32(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_id() const { return at<5>().valid(); }
+  uint32_t id() const { return at<5>().as_uint32(); }
+};
+
+class MaliMaliKCPUFENCESIGNALFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUFENCESIGNALFtraceEvent_Decoder;
+  enum : int32_t {
+    kInfoVal1FieldNumber = 1,
+    kInfoVal2FieldNumber = 2,
+    kKctxTgidFieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kIdFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUFENCESIGNALFtraceEvent"; }
+
+
+  using FieldMetadata_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCESIGNALFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUFENCESIGNALFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUFENCESIGNALFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCESIGNALFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUFENCESIGNALFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MaliMaliKCPUCQSWAITENDFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUCQSWAITENDFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUCQSWAITENDFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUCQSWAITENDFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint32_t id() const { return at<1>().as_uint32(); }
+  bool has_info_val1() const { return at<2>().valid(); }
+  uint64_t info_val1() const { return at<2>().as_uint64(); }
+  bool has_info_val2() const { return at<3>().valid(); }
+  uint64_t info_val2() const { return at<3>().as_uint64(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_kctx_tgid() const { return at<5>().valid(); }
+  int32_t kctx_tgid() const { return at<5>().as_int32(); }
+};
+
+class MaliMaliKCPUCQSWAITENDFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUCQSWAITENDFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kInfoVal1FieldNumber = 2,
+    kInfoVal2FieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kKctxTgidFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUCQSWAITENDFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUCQSWAITENDFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MaliMaliKCPUCQSWAITSTARTFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUCQSWAITSTARTFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUCQSWAITSTARTFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUCQSWAITSTARTFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint32_t id() const { return at<1>().as_uint32(); }
+  bool has_info_val1() const { return at<2>().valid(); }
+  uint64_t info_val1() const { return at<2>().as_uint64(); }
+  bool has_info_val2() const { return at<3>().valid(); }
+  uint64_t info_val2() const { return at<3>().as_uint64(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_kctx_tgid() const { return at<5>().valid(); }
+  int32_t kctx_tgid() const { return at<5>().as_int32(); }
+};
+
+class MaliMaliKCPUCQSWAITSTARTFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUCQSWAITSTARTFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kInfoVal1FieldNumber = 2,
+    kInfoVal2FieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kKctxTgidFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUCQSWAITSTARTFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUCQSWAITSTARTFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MaliMaliKCPUCQSSETFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliMaliKCPUCQSSETFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliMaliKCPUCQSSETFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliMaliKCPUCQSSETFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint32_t id() const { return at<1>().as_uint32(); }
+  bool has_info_val1() const { return at<2>().valid(); }
+  uint64_t info_val1() const { return at<2>().as_uint64(); }
+  bool has_info_val2() const { return at<3>().valid(); }
+  uint64_t info_val2() const { return at<3>().as_uint64(); }
+  bool has_kctx_id() const { return at<4>().valid(); }
+  uint32_t kctx_id() const { return at<4>().as_uint32(); }
+  bool has_kctx_tgid() const { return at<5>().valid(); }
+  int32_t kctx_tgid() const { return at<5>().as_int32(); }
+};
+
+class MaliMaliKCPUCQSSETFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliMaliKCPUCQSSETFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kInfoVal1FieldNumber = 2,
+    kInfoVal2FieldNumber = 3,
+    kKctxIdFieldNumber = 4,
+    kKctxTgidFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliMaliKCPUCQSSETFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSSETFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSSETFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal1 kInfoVal1{};
+  void set_info_val1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InfoVal2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MaliMaliKCPUCQSSETFtraceEvent>;
+
+  static constexpr FieldMetadata_InfoVal2 kInfoVal2{};
+  void set_info_val2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_InfoVal2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliMaliKCPUCQSSETFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxId kKctxId{};
+  void set_kctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KctxTgid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliMaliKCPUCQSSETFtraceEvent>;
+
+  static constexpr FieldMetadata_KctxTgid kKctxTgid{};
+  void set_kctx_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KctxTgid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MaliTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MaliTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MaliTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MaliTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_type() const { return at<3>().valid(); }
+  uint32_t type() const { return at<3>().as_uint32(); }
+  bool has_value() const { return at<4>().valid(); }
+  int32_t value() const { return at<4>().as_int32(); }
+};
+
+class MaliTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MaliTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTypeFieldNumber = 3,
+    kValueFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MaliTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MaliTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MaliTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MaliTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/mdss.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MDSS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MDSS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class RotatorBwAoAsContextFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RotatorBwAoAsContextFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RotatorBwAoAsContextFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RotatorBwAoAsContextFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_state() const { return at<1>().valid(); }
+  uint32_t state() const { return at<1>().as_uint32(); }
+};
+
+class RotatorBwAoAsContextFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RotatorBwAoAsContextFtraceEvent_Decoder;
+  enum : int32_t {
+    kStateFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RotatorBwAoAsContextFtraceEvent"; }
+
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RotatorBwAoAsContextFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpPerfUpdateBusFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfUpdateBusFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfUpdateBusFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfUpdateBusFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_client() const { return at<1>().valid(); }
+  int32_t client() const { return at<1>().as_int32(); }
+  bool has_ab_quota() const { return at<2>().valid(); }
+  uint64_t ab_quota() const { return at<2>().as_uint64(); }
+  bool has_ib_quota() const { return at<3>().valid(); }
+  uint64_t ib_quota() const { return at<3>().as_uint64(); }
+};
+
+class MdpPerfUpdateBusFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfUpdateBusFtraceEvent_Decoder;
+  enum : int32_t {
+    kClientFieldNumber = 1,
+    kAbQuotaFieldNumber = 2,
+    kIbQuotaFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfUpdateBusFtraceEvent"; }
+
+
+  using FieldMetadata_Client =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpPerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_Client kClient{};
+  void set_client(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Client::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AbQuota =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpPerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_AbQuota kAbQuota{};
+  void set_ab_quota(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AbQuota::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IbQuota =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpPerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_IbQuota kIbQuota{};
+  void set_ib_quota(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IbQuota::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpPerfPrefillCalcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfPrefillCalcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfPrefillCalcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfPrefillCalcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pnum() const { return at<1>().valid(); }
+  uint32_t pnum() const { return at<1>().as_uint32(); }
+  bool has_latency_buf() const { return at<2>().valid(); }
+  uint32_t latency_buf() const { return at<2>().as_uint32(); }
+  bool has_ot() const { return at<3>().valid(); }
+  uint32_t ot() const { return at<3>().as_uint32(); }
+  bool has_y_buf() const { return at<4>().valid(); }
+  uint32_t y_buf() const { return at<4>().as_uint32(); }
+  bool has_y_scaler() const { return at<5>().valid(); }
+  uint32_t y_scaler() const { return at<5>().as_uint32(); }
+  bool has_pp_lines() const { return at<6>().valid(); }
+  uint32_t pp_lines() const { return at<6>().as_uint32(); }
+  bool has_pp_bytes() const { return at<7>().valid(); }
+  uint32_t pp_bytes() const { return at<7>().as_uint32(); }
+  bool has_post_sc() const { return at<8>().valid(); }
+  uint32_t post_sc() const { return at<8>().as_uint32(); }
+  bool has_fbc_bytes() const { return at<9>().valid(); }
+  uint32_t fbc_bytes() const { return at<9>().as_uint32(); }
+  bool has_prefill_bytes() const { return at<10>().valid(); }
+  uint32_t prefill_bytes() const { return at<10>().as_uint32(); }
+};
+
+class MdpPerfPrefillCalcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfPrefillCalcFtraceEvent_Decoder;
+  enum : int32_t {
+    kPnumFieldNumber = 1,
+    kLatencyBufFieldNumber = 2,
+    kOtFieldNumber = 3,
+    kYBufFieldNumber = 4,
+    kYScalerFieldNumber = 5,
+    kPpLinesFieldNumber = 6,
+    kPpBytesFieldNumber = 7,
+    kPostScFieldNumber = 8,
+    kFbcBytesFieldNumber = 9,
+    kPrefillBytesFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfPrefillCalcFtraceEvent"; }
+
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LatencyBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_LatencyBuf kLatencyBuf{};
+  void set_latency_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LatencyBuf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ot =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_Ot kOt{};
+  void set_ot(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ot::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_YBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_YBuf kYBuf{};
+  void set_y_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_YBuf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_YScaler =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_YScaler kYScaler{};
+  void set_y_scaler(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_YScaler::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PpLines =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_PpLines kPpLines{};
+  void set_pp_lines(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PpLines::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PpBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_PpBytes kPpBytes{};
+  void set_pp_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PpBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PostSc =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_PostSc kPostSc{};
+  void set_post_sc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PostSc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FbcBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_FbcBytes kFbcBytes{};
+  void set_fbc_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FbcBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrefillBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfPrefillCalcFtraceEvent>;
+
+  static constexpr FieldMetadata_PrefillBytes kPrefillBytes{};
+  void set_prefill_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrefillBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpCmdWaitPingpongFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCmdWaitPingpongFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCmdWaitPingpongFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCmdWaitPingpongFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+  bool has_kickoff_cnt() const { return at<2>().valid(); }
+  int32_t kickoff_cnt() const { return at<2>().as_int32(); }
+};
+
+class MdpCmdWaitPingpongFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCmdWaitPingpongFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+    kKickoffCntFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCmdWaitPingpongFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdWaitPingpongFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KickoffCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpCmdWaitPingpongFtraceEvent>;
+
+  static constexpr FieldMetadata_KickoffCnt kKickoffCnt{};
+  void set_kickoff_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KickoffCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpVideoUnderrunDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpVideoUnderrunDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpVideoUnderrunDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpVideoUnderrunDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+  bool has_underrun_cnt() const { return at<2>().valid(); }
+  uint32_t underrun_cnt() const { return at<2>().as_uint32(); }
+};
+
+class MdpVideoUnderrunDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpVideoUnderrunDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+    kUnderrunCntFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpVideoUnderrunDoneFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpVideoUnderrunDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UnderrunCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpVideoUnderrunDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_UnderrunCnt kUnderrunCnt{};
+  void set_underrun_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnderrunCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpPerfSetWmLevelsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfSetWmLevelsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfSetWmLevelsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfSetWmLevelsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pnum() const { return at<1>().valid(); }
+  uint32_t pnum() const { return at<1>().as_uint32(); }
+  bool has_use_space() const { return at<2>().valid(); }
+  uint32_t use_space() const { return at<2>().as_uint32(); }
+  bool has_priority_bytes() const { return at<3>().valid(); }
+  uint32_t priority_bytes() const { return at<3>().as_uint32(); }
+  bool has_wm0() const { return at<4>().valid(); }
+  uint32_t wm0() const { return at<4>().as_uint32(); }
+  bool has_wm1() const { return at<5>().valid(); }
+  uint32_t wm1() const { return at<5>().as_uint32(); }
+  bool has_wm2() const { return at<6>().valid(); }
+  uint32_t wm2() const { return at<6>().as_uint32(); }
+  bool has_mb_cnt() const { return at<7>().valid(); }
+  uint32_t mb_cnt() const { return at<7>().as_uint32(); }
+  bool has_mb_size() const { return at<8>().valid(); }
+  uint32_t mb_size() const { return at<8>().as_uint32(); }
+};
+
+class MdpPerfSetWmLevelsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfSetWmLevelsFtraceEvent_Decoder;
+  enum : int32_t {
+    kPnumFieldNumber = 1,
+    kUseSpaceFieldNumber = 2,
+    kPriorityBytesFieldNumber = 3,
+    kWm0FieldNumber = 4,
+    kWm1FieldNumber = 5,
+    kWm2FieldNumber = 6,
+    kMbCntFieldNumber = 7,
+    kMbSizeFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfSetWmLevelsFtraceEvent"; }
+
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UseSpace =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_UseSpace kUseSpace{};
+  void set_use_space(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UseSpace::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PriorityBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_PriorityBytes kPriorityBytes{};
+  void set_priority_bytes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PriorityBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Wm0 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_Wm0 kWm0{};
+  void set_wm0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Wm0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Wm1 =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_Wm1 kWm1{};
+  void set_wm1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Wm1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Wm2 =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_Wm2 kWm2{};
+  void set_wm2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Wm2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MbCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_MbCnt kMbCnt{};
+  void set_mb_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MbCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MbSize =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetWmLevelsFtraceEvent>;
+
+  static constexpr FieldMetadata_MbSize kMbSize{};
+  void set_mb_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MbSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpMixerUpdateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpMixerUpdateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpMixerUpdateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpMixerUpdateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_mixer_num() const { return at<1>().valid(); }
+  uint32_t mixer_num() const { return at<1>().as_uint32(); }
+};
+
+class MdpMixerUpdateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpMixerUpdateFtraceEvent_Decoder;
+  enum : int32_t {
+    kMixerNumFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpMixerUpdateFtraceEvent"; }
+
+
+  using FieldMetadata_MixerNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpMixerUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_MixerNum kMixerNum{};
+  void set_mixer_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MixerNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpCmdReleaseBwFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCmdReleaseBwFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCmdReleaseBwFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCmdReleaseBwFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+};
+
+class MdpCmdReleaseBwFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCmdReleaseBwFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCmdReleaseBwFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdReleaseBwFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpTraceCounterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpTraceCounterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpTraceCounterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpTraceCounterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_counter_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars counter_name() const { return at<2>().as_string(); }
+  bool has_value() const { return at<3>().valid(); }
+  int32_t value() const { return at<3>().as_int32(); }
+};
+
+class MdpTraceCounterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpTraceCounterFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kCounterNameFieldNumber = 2,
+    kValueFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpTraceCounterFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpTraceCounterFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CounterName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MdpTraceCounterFtraceEvent>;
+
+  static constexpr FieldMetadata_CounterName kCounterName{};
+  void set_counter_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, data, size);
+  }
+  void set_counter_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, chars.data, chars.size);
+  }
+  void set_counter_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpTraceCounterFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpPerfSetQosLutsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfSetQosLutsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfSetQosLutsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfSetQosLutsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pnum() const { return at<1>().valid(); }
+  uint32_t pnum() const { return at<1>().as_uint32(); }
+  bool has_fmt() const { return at<2>().valid(); }
+  uint32_t fmt() const { return at<2>().as_uint32(); }
+  bool has_intf() const { return at<3>().valid(); }
+  uint32_t intf() const { return at<3>().as_uint32(); }
+  bool has_rot() const { return at<4>().valid(); }
+  uint32_t rot() const { return at<4>().as_uint32(); }
+  bool has_fl() const { return at<5>().valid(); }
+  uint32_t fl() const { return at<5>().as_uint32(); }
+  bool has_lut() const { return at<6>().valid(); }
+  uint32_t lut() const { return at<6>().as_uint32(); }
+  bool has_linear() const { return at<7>().valid(); }
+  uint32_t linear() const { return at<7>().as_uint32(); }
+};
+
+class MdpPerfSetQosLutsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfSetQosLutsFtraceEvent_Decoder;
+  enum : int32_t {
+    kPnumFieldNumber = 1,
+    kFmtFieldNumber = 2,
+    kIntfFieldNumber = 3,
+    kRotFieldNumber = 4,
+    kFlFieldNumber = 5,
+    kLutFieldNumber = 6,
+    kLinearFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfSetQosLutsFtraceEvent"; }
+
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fmt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Fmt kFmt{};
+  void set_fmt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fmt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Intf =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Intf kIntf{};
+  void set_intf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Intf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rot =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Rot kRot{};
+  void set_rot(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rot::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fl =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Fl kFl{};
+  void set_fl(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fl::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lut =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Lut kLut{};
+  void set_lut(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lut::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Linear =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Linear kLinear{};
+  void set_linear(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Linear::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpMisrCrcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpMisrCrcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpMisrCrcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpMisrCrcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_block_id() const { return at<1>().valid(); }
+  uint32_t block_id() const { return at<1>().as_uint32(); }
+  bool has_vsync_cnt() const { return at<2>().valid(); }
+  uint32_t vsync_cnt() const { return at<2>().as_uint32(); }
+  bool has_crc() const { return at<3>().valid(); }
+  uint32_t crc() const { return at<3>().as_uint32(); }
+};
+
+class MdpMisrCrcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpMisrCrcFtraceEvent_Decoder;
+  enum : int32_t {
+    kBlockIdFieldNumber = 1,
+    kVsyncCntFieldNumber = 2,
+    kCrcFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpMisrCrcFtraceEvent"; }
+
+
+  using FieldMetadata_BlockId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpMisrCrcFtraceEvent>;
+
+  static constexpr FieldMetadata_BlockId kBlockId{};
+  void set_block_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BlockId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VsyncCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpMisrCrcFtraceEvent>;
+
+  static constexpr FieldMetadata_VsyncCnt kVsyncCnt{};
+  void set_vsync_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VsyncCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Crc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpMisrCrcFtraceEvent>;
+
+  static constexpr FieldMetadata_Crc kCrc{};
+  void set_crc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Crc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpCmdReadptrDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCmdReadptrDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCmdReadptrDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCmdReadptrDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+  bool has_koff_cnt() const { return at<2>().valid(); }
+  int32_t koff_cnt() const { return at<2>().as_int32(); }
+};
+
+class MdpCmdReadptrDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCmdReadptrDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+    kKoffCntFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCmdReadptrDoneFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdReadptrDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KoffCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpCmdReadptrDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_KoffCnt kKoffCnt{};
+  void set_koff_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KoffCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpSsppSetFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/16, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpSsppSetFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpSsppSetFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpSsppSetFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_num() const { return at<1>().valid(); }
+  uint32_t num() const { return at<1>().as_uint32(); }
+  bool has_play_cnt() const { return at<2>().valid(); }
+  uint32_t play_cnt() const { return at<2>().as_uint32(); }
+  bool has_mixer() const { return at<3>().valid(); }
+  uint32_t mixer() const { return at<3>().as_uint32(); }
+  bool has_stage() const { return at<4>().valid(); }
+  uint32_t stage() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+  bool has_format() const { return at<6>().valid(); }
+  uint32_t format() const { return at<6>().as_uint32(); }
+  bool has_img_w() const { return at<7>().valid(); }
+  uint32_t img_w() const { return at<7>().as_uint32(); }
+  bool has_img_h() const { return at<8>().valid(); }
+  uint32_t img_h() const { return at<8>().as_uint32(); }
+  bool has_src_x() const { return at<9>().valid(); }
+  uint32_t src_x() const { return at<9>().as_uint32(); }
+  bool has_src_y() const { return at<10>().valid(); }
+  uint32_t src_y() const { return at<10>().as_uint32(); }
+  bool has_src_w() const { return at<11>().valid(); }
+  uint32_t src_w() const { return at<11>().as_uint32(); }
+  bool has_src_h() const { return at<12>().valid(); }
+  uint32_t src_h() const { return at<12>().as_uint32(); }
+  bool has_dst_x() const { return at<13>().valid(); }
+  uint32_t dst_x() const { return at<13>().as_uint32(); }
+  bool has_dst_y() const { return at<14>().valid(); }
+  uint32_t dst_y() const { return at<14>().as_uint32(); }
+  bool has_dst_w() const { return at<15>().valid(); }
+  uint32_t dst_w() const { return at<15>().as_uint32(); }
+  bool has_dst_h() const { return at<16>().valid(); }
+  uint32_t dst_h() const { return at<16>().as_uint32(); }
+};
+
+class MdpSsppSetFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpSsppSetFtraceEvent_Decoder;
+  enum : int32_t {
+    kNumFieldNumber = 1,
+    kPlayCntFieldNumber = 2,
+    kMixerFieldNumber = 3,
+    kStageFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+    kFormatFieldNumber = 6,
+    kImgWFieldNumber = 7,
+    kImgHFieldNumber = 8,
+    kSrcXFieldNumber = 9,
+    kSrcYFieldNumber = 10,
+    kSrcWFieldNumber = 11,
+    kSrcHFieldNumber = 12,
+    kDstXFieldNumber = 13,
+    kDstYFieldNumber = 14,
+    kDstWFieldNumber = 15,
+    kDstHFieldNumber = 16,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpSsppSetFtraceEvent"; }
+
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_Num kNum{};
+  void set_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Num::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PlayCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_PlayCnt kPlayCnt{};
+  void set_play_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PlayCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mixer =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_Mixer kMixer{};
+  void set_mixer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mixer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Stage =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_Stage kStage{};
+  void set_stage(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Stage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Format =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_Format kFormat{};
+  void set_format(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Format::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ImgW =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_ImgW kImgW{};
+  void set_img_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ImgW::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ImgH =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_ImgH kImgH{};
+  void set_img_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ImgH::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrcX =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcX kSrcX{};
+  void set_src_x(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcX::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrcY =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcY kSrcY{};
+  void set_src_y(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcY::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrcW =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcW kSrcW{};
+  void set_src_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcW::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrcH =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcH kSrcH{};
+  void set_src_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcH::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstX =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_DstX kDstX{};
+  void set_dst_x(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstX::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstY =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_DstY kDstY{};
+  void set_dst_y(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstY::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstW =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_DstW kDstW{};
+  void set_dst_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstW::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstH =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppSetFtraceEvent>;
+
+  static constexpr FieldMetadata_DstH kDstH{};
+  void set_dst_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstH::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpPerfSetPanicLutsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfSetPanicLutsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfSetPanicLutsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfSetPanicLutsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pnum() const { return at<1>().valid(); }
+  uint32_t pnum() const { return at<1>().as_uint32(); }
+  bool has_fmt() const { return at<2>().valid(); }
+  uint32_t fmt() const { return at<2>().as_uint32(); }
+  bool has_mode() const { return at<3>().valid(); }
+  uint32_t mode() const { return at<3>().as_uint32(); }
+  bool has_panic_lut() const { return at<4>().valid(); }
+  uint32_t panic_lut() const { return at<4>().as_uint32(); }
+  bool has_robust_lut() const { return at<5>().valid(); }
+  uint32_t robust_lut() const { return at<5>().as_uint32(); }
+};
+
+class MdpPerfSetPanicLutsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfSetPanicLutsFtraceEvent_Decoder;
+  enum : int32_t {
+    kPnumFieldNumber = 1,
+    kFmtFieldNumber = 2,
+    kModeFieldNumber = 3,
+    kPanicLutFieldNumber = 4,
+    kRobustLutFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfSetPanicLutsFtraceEvent"; }
+
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fmt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Fmt kFmt{};
+  void set_fmt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fmt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mode =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Mode kMode{};
+  void set_mode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PanicLut =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_PanicLut kPanicLut{};
+  void set_panic_lut(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PanicLut::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RobustLut =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetPanicLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_RobustLut kRobustLut{};
+  void set_robust_lut(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RobustLut::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpCompareBwFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCompareBwFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCompareBwFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCompareBwFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_new_ab() const { return at<1>().valid(); }
+  uint64_t new_ab() const { return at<1>().as_uint64(); }
+  bool has_new_ib() const { return at<2>().valid(); }
+  uint64_t new_ib() const { return at<2>().as_uint64(); }
+  bool has_new_wb() const { return at<3>().valid(); }
+  uint64_t new_wb() const { return at<3>().as_uint64(); }
+  bool has_old_ab() const { return at<4>().valid(); }
+  uint64_t old_ab() const { return at<4>().as_uint64(); }
+  bool has_old_ib() const { return at<5>().valid(); }
+  uint64_t old_ib() const { return at<5>().as_uint64(); }
+  bool has_old_wb() const { return at<6>().valid(); }
+  uint64_t old_wb() const { return at<6>().as_uint64(); }
+  bool has_params_changed() const { return at<7>().valid(); }
+  uint32_t params_changed() const { return at<7>().as_uint32(); }
+  bool has_update_bw() const { return at<8>().valid(); }
+  uint32_t update_bw() const { return at<8>().as_uint32(); }
+};
+
+class MdpCompareBwFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCompareBwFtraceEvent_Decoder;
+  enum : int32_t {
+    kNewAbFieldNumber = 1,
+    kNewIbFieldNumber = 2,
+    kNewWbFieldNumber = 3,
+    kOldAbFieldNumber = 4,
+    kOldIbFieldNumber = 5,
+    kOldWbFieldNumber = 6,
+    kParamsChangedFieldNumber = 7,
+    kUpdateBwFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCompareBwFtraceEvent"; }
+
+
+  using FieldMetadata_NewAb =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_NewAb kNewAb{};
+  void set_new_ab(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewAb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NewIb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_NewIb kNewIb{};
+  void set_new_ib(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewIb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NewWb =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_NewWb kNewWb{};
+  void set_new_wb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewWb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldAb =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_OldAb kOldAb{};
+  void set_old_ab(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldAb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldIb =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_OldIb kOldIb{};
+  void set_old_ib(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldIb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldWb =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_OldWb kOldWb{};
+  void set_old_wb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldWb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ParamsChanged =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_ParamsChanged kParamsChanged{};
+  void set_params_changed(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParamsChanged::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UpdateBw =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCompareBwFtraceEvent>;
+
+  static constexpr FieldMetadata_UpdateBw kUpdateBw{};
+  void set_update_bw(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UpdateBw::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpCmdPingpongDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCmdPingpongDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCmdPingpongDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCmdPingpongDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+  bool has_intf_num() const { return at<2>().valid(); }
+  uint32_t intf_num() const { return at<2>().as_uint32(); }
+  bool has_pp_num() const { return at<3>().valid(); }
+  uint32_t pp_num() const { return at<3>().as_uint32(); }
+  bool has_koff_cnt() const { return at<4>().valid(); }
+  int32_t koff_cnt() const { return at<4>().as_int32(); }
+};
+
+class MdpCmdPingpongDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCmdPingpongDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+    kIntfNumFieldNumber = 2,
+    kPpNumFieldNumber = 3,
+    kKoffCntFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCmdPingpongDoneFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdPingpongDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntfNum =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdPingpongDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_IntfNum kIntfNum{};
+  void set_intf_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntfNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PpNum =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdPingpongDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_PpNum kPpNum{};
+  void set_pp_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PpNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KoffCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpCmdPingpongDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_KoffCnt kKoffCnt{};
+  void set_koff_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KoffCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_trace_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars trace_name() const { return at<2>().as_string(); }
+  bool has_trace_begin() const { return at<3>().valid(); }
+  uint32_t trace_begin() const { return at<3>().as_uint32(); }
+};
+
+class TracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTraceNameFieldNumber = 2,
+    kTraceBeginFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceName kTraceName{};
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, size);
+  }
+  void set_trace_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceBegin kTraceBegin{};
+  void set_trace_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceBegin::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpSsppChangeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/16, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpSsppChangeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpSsppChangeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpSsppChangeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_num() const { return at<1>().valid(); }
+  uint32_t num() const { return at<1>().as_uint32(); }
+  bool has_play_cnt() const { return at<2>().valid(); }
+  uint32_t play_cnt() const { return at<2>().as_uint32(); }
+  bool has_mixer() const { return at<3>().valid(); }
+  uint32_t mixer() const { return at<3>().as_uint32(); }
+  bool has_stage() const { return at<4>().valid(); }
+  uint32_t stage() const { return at<4>().as_uint32(); }
+  bool has_flags() const { return at<5>().valid(); }
+  uint32_t flags() const { return at<5>().as_uint32(); }
+  bool has_format() const { return at<6>().valid(); }
+  uint32_t format() const { return at<6>().as_uint32(); }
+  bool has_img_w() const { return at<7>().valid(); }
+  uint32_t img_w() const { return at<7>().as_uint32(); }
+  bool has_img_h() const { return at<8>().valid(); }
+  uint32_t img_h() const { return at<8>().as_uint32(); }
+  bool has_src_x() const { return at<9>().valid(); }
+  uint32_t src_x() const { return at<9>().as_uint32(); }
+  bool has_src_y() const { return at<10>().valid(); }
+  uint32_t src_y() const { return at<10>().as_uint32(); }
+  bool has_src_w() const { return at<11>().valid(); }
+  uint32_t src_w() const { return at<11>().as_uint32(); }
+  bool has_src_h() const { return at<12>().valid(); }
+  uint32_t src_h() const { return at<12>().as_uint32(); }
+  bool has_dst_x() const { return at<13>().valid(); }
+  uint32_t dst_x() const { return at<13>().as_uint32(); }
+  bool has_dst_y() const { return at<14>().valid(); }
+  uint32_t dst_y() const { return at<14>().as_uint32(); }
+  bool has_dst_w() const { return at<15>().valid(); }
+  uint32_t dst_w() const { return at<15>().as_uint32(); }
+  bool has_dst_h() const { return at<16>().valid(); }
+  uint32_t dst_h() const { return at<16>().as_uint32(); }
+};
+
+class MdpSsppChangeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpSsppChangeFtraceEvent_Decoder;
+  enum : int32_t {
+    kNumFieldNumber = 1,
+    kPlayCntFieldNumber = 2,
+    kMixerFieldNumber = 3,
+    kStageFieldNumber = 4,
+    kFlagsFieldNumber = 5,
+    kFormatFieldNumber = 6,
+    kImgWFieldNumber = 7,
+    kImgHFieldNumber = 8,
+    kSrcXFieldNumber = 9,
+    kSrcYFieldNumber = 10,
+    kSrcWFieldNumber = 11,
+    kSrcHFieldNumber = 12,
+    kDstXFieldNumber = 13,
+    kDstYFieldNumber = 14,
+    kDstWFieldNumber = 15,
+    kDstHFieldNumber = 16,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpSsppChangeFtraceEvent"; }
+
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Num kNum{};
+  void set_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Num::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PlayCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_PlayCnt kPlayCnt{};
+  void set_play_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PlayCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Mixer =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Mixer kMixer{};
+  void set_mixer(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Mixer::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Stage =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Stage kStage{};
+  void set_stage(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Stage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Format =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_Format kFormat{};
+  void set_format(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Format::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ImgW =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_ImgW kImgW{};
+  void set_img_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ImgW::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ImgH =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_ImgH kImgH{};
+  void set_img_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ImgH::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrcX =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcX kSrcX{};
+  void set_src_x(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcX::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrcY =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcY kSrcY{};
+  void set_src_y(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcY::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrcW =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcW kSrcW{};
+  void set_src_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcW::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrcH =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_SrcH kSrcH{};
+  void set_src_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrcH::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstX =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_DstX kDstX{};
+  void set_dst_x(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstX::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstY =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_DstY kDstY{};
+  void set_dst_y(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstY::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstW =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_DstW kDstW{};
+  void set_dst_w(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstW::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DstH =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpSsppChangeFtraceEvent>;
+
+  static constexpr FieldMetadata_DstH kDstH{};
+  void set_dst_h(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DstH::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpPerfSetOtFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpPerfSetOtFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpPerfSetOtFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpPerfSetOtFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pnum() const { return at<1>().valid(); }
+  uint32_t pnum() const { return at<1>().as_uint32(); }
+  bool has_xin_id() const { return at<2>().valid(); }
+  uint32_t xin_id() const { return at<2>().as_uint32(); }
+  bool has_rd_lim() const { return at<3>().valid(); }
+  uint32_t rd_lim() const { return at<3>().as_uint32(); }
+  bool has_is_vbif_rt() const { return at<4>().valid(); }
+  uint32_t is_vbif_rt() const { return at<4>().as_uint32(); }
+};
+
+class MdpPerfSetOtFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpPerfSetOtFtraceEvent_Decoder;
+  enum : int32_t {
+    kPnumFieldNumber = 1,
+    kXinIdFieldNumber = 2,
+    kRdLimFieldNumber = 3,
+    kIsVbifRtFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpPerfSetOtFtraceEvent"; }
+
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetOtFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_XinId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetOtFtraceEvent>;
+
+  static constexpr FieldMetadata_XinId kXinId{};
+  void set_xin_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_XinId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RdLim =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetOtFtraceEvent>;
+
+  static constexpr FieldMetadata_RdLim kRdLim{};
+  void set_rd_lim(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RdLim::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsVbifRt =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpPerfSetOtFtraceEvent>;
+
+  static constexpr FieldMetadata_IsVbifRt kIsVbifRt{};
+  void set_is_vbif_rt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsVbifRt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpCommitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCommitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCommitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCommitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_num() const { return at<1>().valid(); }
+  uint32_t num() const { return at<1>().as_uint32(); }
+  bool has_play_cnt() const { return at<2>().valid(); }
+  uint32_t play_cnt() const { return at<2>().as_uint32(); }
+  bool has_clk_rate() const { return at<3>().valid(); }
+  uint32_t clk_rate() const { return at<3>().as_uint32(); }
+  bool has_bandwidth() const { return at<4>().valid(); }
+  uint64_t bandwidth() const { return at<4>().as_uint64(); }
+};
+
+class MdpCommitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCommitFtraceEvent_Decoder;
+  enum : int32_t {
+    kNumFieldNumber = 1,
+    kPlayCntFieldNumber = 2,
+    kClkRateFieldNumber = 3,
+    kBandwidthFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCommitFtraceEvent"; }
+
+
+  using FieldMetadata_Num =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCommitFtraceEvent>;
+
+  static constexpr FieldMetadata_Num kNum{};
+  void set_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Num::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PlayCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCommitFtraceEvent>;
+
+  static constexpr FieldMetadata_PlayCnt kPlayCnt{};
+  void set_play_cnt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PlayCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ClkRate =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCommitFtraceEvent>;
+
+  static constexpr FieldMetadata_ClkRate kClkRate{};
+  void set_clk_rate(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClkRate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Bandwidth =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MdpCommitFtraceEvent>;
+
+  static constexpr FieldMetadata_Bandwidth kBandwidth{};
+  void set_bandwidth(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bandwidth::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MdpCmdKickoffFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MdpCmdKickoffFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MdpCmdKickoffFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MdpCmdKickoffFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctl_num() const { return at<1>().valid(); }
+  uint32_t ctl_num() const { return at<1>().as_uint32(); }
+  bool has_kickoff_cnt() const { return at<2>().valid(); }
+  int32_t kickoff_cnt() const { return at<2>().as_int32(); }
+};
+
+class MdpCmdKickoffFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MdpCmdKickoffFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtlNumFieldNumber = 1,
+    kKickoffCntFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MdpCmdKickoffFtraceEvent"; }
+
+
+  using FieldMetadata_CtlNum =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MdpCmdKickoffFtraceEvent>;
+
+  static constexpr FieldMetadata_CtlNum kCtlNum{};
+  void set_ctl_num(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtlNum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KickoffCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MdpCmdKickoffFtraceEvent>;
+
+  static constexpr FieldMetadata_KickoffCnt kKickoffCnt{};
+  void set_kickoff_cnt(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KickoffCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/mm_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MM_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_MM_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class MmEventRecordFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmEventRecordFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmEventRecordFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmEventRecordFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_avg_lat() const { return at<1>().valid(); }
+  uint32_t avg_lat() const { return at<1>().as_uint32(); }
+  bool has_count() const { return at<2>().valid(); }
+  uint32_t count() const { return at<2>().as_uint32(); }
+  bool has_max_lat() const { return at<3>().valid(); }
+  uint32_t max_lat() const { return at<3>().as_uint32(); }
+  bool has_type() const { return at<4>().valid(); }
+  uint32_t type() const { return at<4>().as_uint32(); }
+};
+
+class MmEventRecordFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmEventRecordFtraceEvent_Decoder;
+  enum : int32_t {
+    kAvgLatFieldNumber = 1,
+    kCountFieldNumber = 2,
+    kMaxLatFieldNumber = 3,
+    kTypeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmEventRecordFtraceEvent"; }
+
+
+  using FieldMetadata_AvgLat =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmEventRecordFtraceEvent>;
+
+  static constexpr FieldMetadata_AvgLat kAvgLat{};
+  void set_avg_lat(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AvgLat::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmEventRecordFtraceEvent>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxLat =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmEventRecordFtraceEvent>;
+
+  static constexpr FieldMetadata_MaxLat kMaxLat{};
+  void set_max_lat(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxLat::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmEventRecordFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/net.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_NET_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_NET_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class NapiGroReceiveExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NapiGroReceiveExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NapiGroReceiveExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NapiGroReceiveExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ret() const { return at<1>().valid(); }
+  int32_t ret() const { return at<1>().as_int32(); }
+};
+
+class NapiGroReceiveExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = NapiGroReceiveExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kRetFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NapiGroReceiveExitFtraceEvent"; }
+
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      NapiGroReceiveExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class NapiGroReceiveEntryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NapiGroReceiveEntryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NapiGroReceiveEntryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NapiGroReceiveEntryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_data_len() const { return at<1>().valid(); }
+  uint32_t data_len() const { return at<1>().as_uint32(); }
+  bool has_gso_size() const { return at<2>().valid(); }
+  uint32_t gso_size() const { return at<2>().as_uint32(); }
+  bool has_gso_type() const { return at<3>().valid(); }
+  uint32_t gso_type() const { return at<3>().as_uint32(); }
+  bool has_hash() const { return at<4>().valid(); }
+  uint32_t hash() const { return at<4>().as_uint32(); }
+  bool has_ip_summed() const { return at<5>().valid(); }
+  uint32_t ip_summed() const { return at<5>().as_uint32(); }
+  bool has_l4_hash() const { return at<6>().valid(); }
+  uint32_t l4_hash() const { return at<6>().as_uint32(); }
+  bool has_len() const { return at<7>().valid(); }
+  uint32_t len() const { return at<7>().as_uint32(); }
+  bool has_mac_header() const { return at<8>().valid(); }
+  int32_t mac_header() const { return at<8>().as_int32(); }
+  bool has_mac_header_valid() const { return at<9>().valid(); }
+  uint32_t mac_header_valid() const { return at<9>().as_uint32(); }
+  bool has_name() const { return at<10>().valid(); }
+  ::protozero::ConstChars name() const { return at<10>().as_string(); }
+  bool has_napi_id() const { return at<11>().valid(); }
+  uint32_t napi_id() const { return at<11>().as_uint32(); }
+  bool has_nr_frags() const { return at<12>().valid(); }
+  uint32_t nr_frags() const { return at<12>().as_uint32(); }
+  bool has_protocol() const { return at<13>().valid(); }
+  uint32_t protocol() const { return at<13>().as_uint32(); }
+  bool has_queue_mapping() const { return at<14>().valid(); }
+  uint32_t queue_mapping() const { return at<14>().as_uint32(); }
+  bool has_skbaddr() const { return at<15>().valid(); }
+  uint64_t skbaddr() const { return at<15>().as_uint64(); }
+  bool has_truesize() const { return at<16>().valid(); }
+  uint32_t truesize() const { return at<16>().as_uint32(); }
+  bool has_vlan_proto() const { return at<17>().valid(); }
+  uint32_t vlan_proto() const { return at<17>().as_uint32(); }
+  bool has_vlan_tagged() const { return at<18>().valid(); }
+  uint32_t vlan_tagged() const { return at<18>().as_uint32(); }
+  bool has_vlan_tci() const { return at<19>().valid(); }
+  uint32_t vlan_tci() const { return at<19>().as_uint32(); }
+};
+
+class NapiGroReceiveEntryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = NapiGroReceiveEntryFtraceEvent_Decoder;
+  enum : int32_t {
+    kDataLenFieldNumber = 1,
+    kGsoSizeFieldNumber = 2,
+    kGsoTypeFieldNumber = 3,
+    kHashFieldNumber = 4,
+    kIpSummedFieldNumber = 5,
+    kL4HashFieldNumber = 6,
+    kLenFieldNumber = 7,
+    kMacHeaderFieldNumber = 8,
+    kMacHeaderValidFieldNumber = 9,
+    kNameFieldNumber = 10,
+    kNapiIdFieldNumber = 11,
+    kNrFragsFieldNumber = 12,
+    kProtocolFieldNumber = 13,
+    kQueueMappingFieldNumber = 14,
+    kSkbaddrFieldNumber = 15,
+    kTruesizeFieldNumber = 16,
+    kVlanProtoFieldNumber = 17,
+    kVlanTaggedFieldNumber = 18,
+    kVlanTciFieldNumber = 19,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NapiGroReceiveEntryFtraceEvent"; }
+
+
+  using FieldMetadata_DataLen =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_DataLen kDataLen{};
+  void set_data_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GsoSize =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_GsoSize kGsoSize{};
+  void set_gso_size(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GsoSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GsoType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_GsoType kGsoType{};
+  void set_gso_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GsoType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Hash =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Hash kHash{};
+  void set_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Hash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IpSummed =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_IpSummed kIpSummed{};
+  void set_ip_summed(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IpSummed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_L4Hash =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_L4Hash kL4Hash{};
+  void set_l4_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_L4Hash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MacHeader =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_MacHeader kMacHeader{};
+  void set_mac_header(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MacHeader::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MacHeaderValid =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_MacHeaderValid kMacHeaderValid{};
+  void set_mac_header_valid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MacHeaderValid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NapiId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_NapiId kNapiId{};
+  void set_napi_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NapiId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrFrags =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_NrFrags kNrFrags{};
+  void set_nr_frags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrFrags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_QueueMapping =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_QueueMapping kQueueMapping{};
+  void set_queue_mapping(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_QueueMapping::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Skbaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Skbaddr kSkbaddr{};
+  void set_skbaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skbaddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Truesize =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_Truesize kTruesize{};
+  void set_truesize(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Truesize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VlanProto =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_VlanProto kVlanProto{};
+  void set_vlan_proto(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VlanProto::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VlanTagged =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_VlanTagged kVlanTagged{};
+  void set_vlan_tagged(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VlanTagged::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VlanTci =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NapiGroReceiveEntryFtraceEvent>;
+
+  static constexpr FieldMetadata_VlanTci kVlanTci{};
+  void set_vlan_tci(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VlanTci::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class NetDevXmitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetDevXmitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetDevXmitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetDevXmitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint32_t len() const { return at<1>().as_uint32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_rc() const { return at<3>().valid(); }
+  int32_t rc() const { return at<3>().as_int32(); }
+  bool has_skbaddr() const { return at<4>().valid(); }
+  uint64_t skbaddr() const { return at<4>().as_uint64(); }
+};
+
+class NetDevXmitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = NetDevXmitFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kRcFieldNumber = 3,
+    kSkbaddrFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetDevXmitFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetDevXmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      NetDevXmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      NetDevXmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Rc kRc{};
+  void set_rc(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Skbaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetDevXmitFtraceEvent>;
+
+  static constexpr FieldMetadata_Skbaddr kSkbaddr{};
+  void set_skbaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skbaddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class NetifReceiveSkbFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  NetifReceiveSkbFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit NetifReceiveSkbFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit NetifReceiveSkbFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint32_t len() const { return at<1>().as_uint32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_skbaddr() const { return at<3>().valid(); }
+  uint64_t skbaddr() const { return at<3>().as_uint64(); }
+};
+
+class NetifReceiveSkbFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = NetifReceiveSkbFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kSkbaddrFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.NetifReceiveSkbFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      NetifReceiveSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      NetifReceiveSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Skbaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      NetifReceiveSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Skbaddr kSkbaddr{};
+  void set_skbaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skbaddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/oom.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_OOM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_OOM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class MarkVictimFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MarkVictimFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MarkVictimFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MarkVictimFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+};
+
+class MarkVictimFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MarkVictimFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MarkVictimFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MarkVictimFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class OomScoreAdjUpdateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  OomScoreAdjUpdateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit OomScoreAdjUpdateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit OomScoreAdjUpdateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_oom_score_adj() const { return at<2>().valid(); }
+  int32_t oom_score_adj() const { return at<2>().as_int32(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+};
+
+class OomScoreAdjUpdateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = OomScoreAdjUpdateFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kOomScoreAdjFieldNumber = 2,
+    kPidFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.OomScoreAdjUpdateFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      OomScoreAdjUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OomScoreAdj =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      OomScoreAdjUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj{};
+  void set_oom_score_adj(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OomScoreAdj::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      OomScoreAdjUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/panel.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PANEL_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PANEL_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class DsiTxFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DsiTxFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DsiTxFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DsiTxFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_last() const { return at<1>().valid(); }
+  uint32_t last() const { return at<1>().as_uint32(); }
+  bool has_tx_buf() const { return at<2>().valid(); }
+  uint32_t tx_buf() const { return at<2>().as_uint32(); }
+  bool has_type() const { return at<3>().valid(); }
+  uint32_t type() const { return at<3>().as_uint32(); }
+};
+
+class DsiTxFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DsiTxFtraceEvent_Decoder;
+  enum : int32_t {
+    kLastFieldNumber = 1,
+    kTxBufFieldNumber = 2,
+    kTypeFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DsiTxFtraceEvent"; }
+
+
+  using FieldMetadata_Last =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiTxFtraceEvent>;
+
+  static constexpr FieldMetadata_Last kLast{};
+  void set_last(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Last::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TxBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiTxFtraceEvent>;
+
+  static constexpr FieldMetadata_TxBuf kTxBuf{};
+  void set_tx_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TxBuf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiTxFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DsiRxFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DsiRxFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DsiRxFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DsiRxFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cmd() const { return at<1>().valid(); }
+  uint32_t cmd() const { return at<1>().as_uint32(); }
+  bool has_rx_buf() const { return at<2>().valid(); }
+  uint32_t rx_buf() const { return at<2>().as_uint32(); }
+};
+
+class DsiRxFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DsiRxFtraceEvent_Decoder;
+  enum : int32_t {
+    kCmdFieldNumber = 1,
+    kRxBufFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DsiRxFtraceEvent"; }
+
+
+  using FieldMetadata_Cmd =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiRxFtraceEvent>;
+
+  static constexpr FieldMetadata_Cmd kCmd{};
+  void set_cmd(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RxBuf =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiRxFtraceEvent>;
+
+  static constexpr FieldMetadata_RxBuf kRxBuf{};
+  void set_rx_buf(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RxBuf::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class DsiCmdFifoStatusFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  DsiCmdFifoStatusFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DsiCmdFifoStatusFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DsiCmdFifoStatusFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_header() const { return at<1>().valid(); }
+  uint32_t header() const { return at<1>().as_uint32(); }
+  bool has_payload() const { return at<2>().valid(); }
+  uint32_t payload() const { return at<2>().as_uint32(); }
+};
+
+class DsiCmdFifoStatusFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = DsiCmdFifoStatusFtraceEvent_Decoder;
+  enum : int32_t {
+    kHeaderFieldNumber = 1,
+    kPayloadFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DsiCmdFifoStatusFtraceEvent"; }
+
+
+  using FieldMetadata_Header =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiCmdFifoStatusFtraceEvent>;
+
+  static constexpr FieldMetadata_Header kHeader{};
+  void set_header(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Header::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Payload =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      DsiCmdFifoStatusFtraceEvent>;
+
+  static constexpr FieldMetadata_Payload kPayload{};
+  void set_payload(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Payload::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/perf_trace_counters.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PERF_TRACE_COUNTERS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PERF_TRACE_COUNTERS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SchedSwitchWithCtrsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/17, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedSwitchWithCtrsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedSwitchWithCtrsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedSwitchWithCtrsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_old_pid() const { return at<1>().valid(); }
+  int32_t old_pid() const { return at<1>().as_int32(); }
+  bool has_new_pid() const { return at<2>().valid(); }
+  int32_t new_pid() const { return at<2>().as_int32(); }
+  bool has_cctr() const { return at<3>().valid(); }
+  uint32_t cctr() const { return at<3>().as_uint32(); }
+  bool has_ctr0() const { return at<4>().valid(); }
+  uint32_t ctr0() const { return at<4>().as_uint32(); }
+  bool has_ctr1() const { return at<5>().valid(); }
+  uint32_t ctr1() const { return at<5>().as_uint32(); }
+  bool has_ctr2() const { return at<6>().valid(); }
+  uint32_t ctr2() const { return at<6>().as_uint32(); }
+  bool has_ctr3() const { return at<7>().valid(); }
+  uint32_t ctr3() const { return at<7>().as_uint32(); }
+  bool has_lctr0() const { return at<8>().valid(); }
+  uint32_t lctr0() const { return at<8>().as_uint32(); }
+  bool has_lctr1() const { return at<9>().valid(); }
+  uint32_t lctr1() const { return at<9>().as_uint32(); }
+  bool has_ctr4() const { return at<10>().valid(); }
+  uint32_t ctr4() const { return at<10>().as_uint32(); }
+  bool has_ctr5() const { return at<11>().valid(); }
+  uint32_t ctr5() const { return at<11>().as_uint32(); }
+  bool has_prev_comm() const { return at<12>().valid(); }
+  ::protozero::ConstChars prev_comm() const { return at<12>().as_string(); }
+  bool has_prev_pid() const { return at<13>().valid(); }
+  int32_t prev_pid() const { return at<13>().as_int32(); }
+  bool has_cyc() const { return at<14>().valid(); }
+  uint32_t cyc() const { return at<14>().as_uint32(); }
+  bool has_inst() const { return at<15>().valid(); }
+  uint32_t inst() const { return at<15>().as_uint32(); }
+  bool has_stallbm() const { return at<16>().valid(); }
+  uint32_t stallbm() const { return at<16>().as_uint32(); }
+  bool has_l3dm() const { return at<17>().valid(); }
+  uint32_t l3dm() const { return at<17>().as_uint32(); }
+};
+
+class SchedSwitchWithCtrsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedSwitchWithCtrsFtraceEvent_Decoder;
+  enum : int32_t {
+    kOldPidFieldNumber = 1,
+    kNewPidFieldNumber = 2,
+    kCctrFieldNumber = 3,
+    kCtr0FieldNumber = 4,
+    kCtr1FieldNumber = 5,
+    kCtr2FieldNumber = 6,
+    kCtr3FieldNumber = 7,
+    kLctr0FieldNumber = 8,
+    kLctr1FieldNumber = 9,
+    kCtr4FieldNumber = 10,
+    kCtr5FieldNumber = 11,
+    kPrevCommFieldNumber = 12,
+    kPrevPidFieldNumber = 13,
+    kCycFieldNumber = 14,
+    kInstFieldNumber = 15,
+    kStallbmFieldNumber = 16,
+    kL3dmFieldNumber = 17,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedSwitchWithCtrsFtraceEvent"; }
+
+
+  using FieldMetadata_OldPid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_OldPid kOldPid{};
+  void set_old_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NewPid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_NewPid kNewPid{};
+  void set_new_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cctr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Cctr kCctr{};
+  void set_cctr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cctr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ctr0 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr0 kCtr0{};
+  void set_ctr0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ctr1 =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr1 kCtr1{};
+  void set_ctr1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ctr2 =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr2 kCtr2{};
+  void set_ctr2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ctr3 =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr3 kCtr3{};
+  void set_ctr3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lctr0 =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Lctr0 kLctr0{};
+  void set_lctr0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lctr0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lctr1 =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Lctr1 kLctr1{};
+  void set_lctr1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lctr1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ctr4 =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr4 kCtr4{};
+  void set_ctr4(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr4::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ctr5 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Ctr5 kCtr5{};
+  void set_ctr5(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ctr5::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrevComm =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevComm kPrevComm{};
+  void set_prev_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PrevComm::kFieldId, data, size);
+  }
+  void set_prev_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PrevComm::kFieldId, chars.data, chars.size);
+  }
+  void set_prev_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevComm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrevPid =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevPid kPrevPid{};
+  void set_prev_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cyc =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Cyc kCyc{};
+  void set_cyc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cyc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Inst =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Inst kInst{};
+  void set_inst(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Inst::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Stallbm =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_Stallbm kStallbm{};
+  void set_stallbm(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Stallbm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_L3dm =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedSwitchWithCtrsFtraceEvent>;
+
+  static constexpr FieldMetadata_L3dm kL3dm{};
+  void set_l3dm(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_L3dm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/power.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_POWER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_POWER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class GpuWorkPeriodFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuWorkPeriodFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuWorkPeriodFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuWorkPeriodFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gpu_id() const { return at<1>().valid(); }
+  uint32_t gpu_id() const { return at<1>().as_uint32(); }
+  bool has_uid() const { return at<2>().valid(); }
+  uint32_t uid() const { return at<2>().as_uint32(); }
+  bool has_start_time_ns() const { return at<3>().valid(); }
+  uint64_t start_time_ns() const { return at<3>().as_uint64(); }
+  bool has_end_time_ns() const { return at<4>().valid(); }
+  uint64_t end_time_ns() const { return at<4>().as_uint64(); }
+  bool has_total_active_duration_ns() const { return at<5>().valid(); }
+  uint64_t total_active_duration_ns() const { return at<5>().as_uint64(); }
+};
+
+class GpuWorkPeriodFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuWorkPeriodFtraceEvent_Decoder;
+  enum : int32_t {
+    kGpuIdFieldNumber = 1,
+    kUidFieldNumber = 2,
+    kStartTimeNsFieldNumber = 3,
+    kEndTimeNsFieldNumber = 4,
+    kTotalActiveDurationNsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuWorkPeriodFtraceEvent"; }
+
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuWorkPeriodFtraceEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuWorkPeriodFtraceEvent>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuWorkPeriodFtraceEvent>;
+
+  static constexpr FieldMetadata_StartTimeNs kStartTimeNs{};
+  void set_start_time_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EndTimeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuWorkPeriodFtraceEvent>;
+
+  static constexpr FieldMetadata_EndTimeNs kEndTimeNs{};
+  void set_end_time_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EndTimeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalActiveDurationNs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuWorkPeriodFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalActiveDurationNs kTotalActiveDurationNs{};
+  void set_total_active_duration_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalActiveDurationNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class WakeupSourceDeactivateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WakeupSourceDeactivateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WakeupSourceDeactivateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WakeupSourceDeactivateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_state() const { return at<2>().valid(); }
+  uint64_t state() const { return at<2>().as_uint64(); }
+};
+
+class WakeupSourceDeactivateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WakeupSourceDeactivateFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WakeupSourceDeactivateFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      WakeupSourceDeactivateFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WakeupSourceDeactivateFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class WakeupSourceActivateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WakeupSourceActivateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WakeupSourceActivateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WakeupSourceActivateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_state() const { return at<2>().valid(); }
+  uint64_t state() const { return at<2>().as_uint64(); }
+};
+
+class WakeupSourceActivateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WakeupSourceActivateFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WakeupSourceActivateFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      WakeupSourceActivateFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WakeupSourceActivateFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class GpuFrequencyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuFrequencyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuFrequencyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuFrequencyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_gpu_id() const { return at<1>().valid(); }
+  uint32_t gpu_id() const { return at<1>().as_uint32(); }
+  bool has_state() const { return at<2>().valid(); }
+  uint32_t state() const { return at<2>().as_uint32(); }
+};
+
+class GpuFrequencyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuFrequencyFtraceEvent_Decoder;
+  enum : int32_t {
+    kGpuIdFieldNumber = 1,
+    kStateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuFrequencyFtraceEvent"; }
+
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuFrequencyFtraceEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuFrequencyFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SuspendResumeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SuspendResumeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SuspendResumeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SuspendResumeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_action() const { return at<1>().valid(); }
+  ::protozero::ConstChars action() const { return at<1>().as_string(); }
+  bool has_val() const { return at<2>().valid(); }
+  int32_t val() const { return at<2>().as_int32(); }
+  bool has_start() const { return at<3>().valid(); }
+  uint32_t start() const { return at<3>().as_uint32(); }
+};
+
+class SuspendResumeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SuspendResumeFtraceEvent_Decoder;
+  enum : int32_t {
+    kActionFieldNumber = 1,
+    kValFieldNumber = 2,
+    kStartFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SuspendResumeFtraceEvent"; }
+
+
+  using FieldMetadata_Action =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SuspendResumeFtraceEvent>;
+
+  static constexpr FieldMetadata_Action kAction{};
+  void set_action(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Action::kFieldId, data, size);
+  }
+  void set_action(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Action::kFieldId, chars.data, chars.size);
+  }
+  void set_action(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Action::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Val =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SuspendResumeFtraceEvent>;
+
+  static constexpr FieldMetadata_Val kVal{};
+  void set_val(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Val::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SuspendResumeFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ClockSetRateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClockSetRateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClockSetRateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClockSetRateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_state() const { return at<2>().valid(); }
+  uint64_t state() const { return at<2>().as_uint64(); }
+  bool has_cpu_id() const { return at<3>().valid(); }
+  uint64_t cpu_id() const { return at<3>().as_uint64(); }
+};
+
+class ClockSetRateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClockSetRateFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+    kCpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClockSetRateFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClockSetRateFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockSetRateFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockSetRateFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ClockDisableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClockDisableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClockDisableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClockDisableFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_state() const { return at<2>().valid(); }
+  uint64_t state() const { return at<2>().as_uint64(); }
+  bool has_cpu_id() const { return at<3>().valid(); }
+  uint64_t cpu_id() const { return at<3>().as_uint64(); }
+};
+
+class ClockDisableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClockDisableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+    kCpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClockDisableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClockDisableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockDisableFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockDisableFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ClockEnableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ClockEnableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ClockEnableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ClockEnableFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_state() const { return at<2>().valid(); }
+  uint64_t state() const { return at<2>().as_uint64(); }
+  bool has_cpu_id() const { return at<3>().valid(); }
+  uint64_t cpu_id() const { return at<3>().as_uint64(); }
+};
+
+class ClockEnableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ClockEnableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+    kCpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ClockEnableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ClockEnableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockEnableFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ClockEnableFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CpuIdleFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuIdleFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuIdleFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuIdleFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_state() const { return at<1>().valid(); }
+  uint32_t state() const { return at<1>().as_uint32(); }
+  bool has_cpu_id() const { return at<2>().valid(); }
+  uint32_t cpu_id() const { return at<2>().as_uint32(); }
+};
+
+class CpuIdleFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuIdleFtraceEvent_Decoder;
+  enum : int32_t {
+    kStateFieldNumber = 1,
+    kCpuIdFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuIdleFtraceEvent"; }
+
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuIdleFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuIdleFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CpuFrequencyLimitsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuFrequencyLimitsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuFrequencyLimitsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuFrequencyLimitsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_min_freq() const { return at<1>().valid(); }
+  uint32_t min_freq() const { return at<1>().as_uint32(); }
+  bool has_max_freq() const { return at<2>().valid(); }
+  uint32_t max_freq() const { return at<2>().as_uint32(); }
+  bool has_cpu_id() const { return at<3>().valid(); }
+  uint32_t cpu_id() const { return at<3>().as_uint32(); }
+};
+
+class CpuFrequencyLimitsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuFrequencyLimitsFtraceEvent_Decoder;
+  enum : int32_t {
+    kMinFreqFieldNumber = 1,
+    kMaxFreqFieldNumber = 2,
+    kCpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuFrequencyLimitsFtraceEvent"; }
+
+
+  using FieldMetadata_MinFreq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyLimitsFtraceEvent>;
+
+  static constexpr FieldMetadata_MinFreq kMinFreq{};
+  void set_min_freq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MinFreq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxFreq =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyLimitsFtraceEvent>;
+
+  static constexpr FieldMetadata_MaxFreq kMaxFreq{};
+  void set_max_freq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxFreq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyLimitsFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class CpuFrequencyFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CpuFrequencyFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuFrequencyFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuFrequencyFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_state() const { return at<1>().valid(); }
+  uint32_t state() const { return at<1>().as_uint32(); }
+  bool has_cpu_id() const { return at<2>().valid(); }
+  uint32_t cpu_id() const { return at<2>().as_uint32(); }
+};
+
+class CpuFrequencyFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CpuFrequencyFtraceEvent_Decoder;
+  enum : int32_t {
+    kStateFieldNumber = 1,
+    kCpuIdFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuFrequencyFtraceEvent"; }
+
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuFrequencyFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/printk.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PRINTK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_PRINTK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ConsoleFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ConsoleFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ConsoleFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ConsoleFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_msg() const { return at<1>().valid(); }
+  ::protozero::ConstChars msg() const { return at<1>().as_string(); }
+};
+
+class ConsoleFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ConsoleFtraceEvent_Decoder;
+  enum : int32_t {
+    kMsgFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ConsoleFtraceEvent"; }
+
+
+  using FieldMetadata_Msg =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ConsoleFtraceEvent>;
+
+  static constexpr FieldMetadata_Msg kMsg{};
+  void set_msg(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Msg::kFieldId, data, size);
+  }
+  void set_msg(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Msg::kFieldId, chars.data, chars.size);
+  }
+  void set_msg(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Msg::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_RAW_SYSCALLS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_RAW_SYSCALLS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SysExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int64_t id() const { return at<1>().as_int64(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int64_t ret() const { return at<2>().as_int64(); }
+};
+
+class SysExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SysExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kRetFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysExitFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SysExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SysExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SysEnterFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SysEnterFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysEnterFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysEnterFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int64_t id() const { return at<1>().as_int64(); }
+  bool has_args() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> args() const { return GetRepeated<uint64_t>(2); }
+};
+
+class SysEnterFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SysEnterFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kArgsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysEnterFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SysEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Args =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysEnterFtraceEvent>;
+
+  static constexpr FieldMetadata_Args kArgs{};
+  void add_args(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Args::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/regulator.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_REGULATOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_REGULATOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class RegulatorSetVoltageCompleteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorSetVoltageCompleteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorSetVoltageCompleteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorSetVoltageCompleteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_val() const { return at<2>().valid(); }
+  uint32_t val() const { return at<2>().as_uint32(); }
+};
+
+class RegulatorSetVoltageCompleteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorSetVoltageCompleteFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorSetVoltageCompleteFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorSetVoltageCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Val =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RegulatorSetVoltageCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Val kVal{};
+  void set_val(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Val::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class RegulatorSetVoltageFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorSetVoltageFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorSetVoltageFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorSetVoltageFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_min() const { return at<2>().valid(); }
+  int32_t min() const { return at<2>().as_int32(); }
+  bool has_max() const { return at<3>().valid(); }
+  int32_t max() const { return at<3>().as_int32(); }
+};
+
+class RegulatorSetVoltageFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorSetVoltageFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kMinFieldNumber = 2,
+    kMaxFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorSetVoltageFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorSetVoltageFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Min =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RegulatorSetVoltageFtraceEvent>;
+
+  static constexpr FieldMetadata_Min kMin{};
+  void set_min(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Min::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Max =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RegulatorSetVoltageFtraceEvent>;
+
+  static constexpr FieldMetadata_Max kMax{};
+  void set_max(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Max::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class RegulatorEnableDelayFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorEnableDelayFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorEnableDelayFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorEnableDelayFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+};
+
+class RegulatorEnableDelayFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorEnableDelayFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorEnableDelayFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorEnableDelayFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class RegulatorEnableCompleteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorEnableCompleteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorEnableCompleteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorEnableCompleteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+};
+
+class RegulatorEnableCompleteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorEnableCompleteFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorEnableCompleteFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorEnableCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class RegulatorEnableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorEnableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorEnableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorEnableFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+};
+
+class RegulatorEnableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorEnableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorEnableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorEnableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class RegulatorDisableCompleteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorDisableCompleteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorDisableCompleteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorDisableCompleteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+};
+
+class RegulatorDisableCompleteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorDisableCompleteFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorDisableCompleteFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorDisableCompleteFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class RegulatorDisableFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RegulatorDisableFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RegulatorDisableFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RegulatorDisableFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+};
+
+class RegulatorDisableFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RegulatorDisableFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RegulatorDisableFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      RegulatorDisableFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/samsung.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SAMSUNG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SAMSUNG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SamsungTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SamsungTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SamsungTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SamsungTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_trace_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars trace_name() const { return at<2>().as_string(); }
+  bool has_trace_begin() const { return at<3>().valid(); }
+  uint32_t trace_begin() const { return at<3>().as_uint32(); }
+  bool has_trace_type() const { return at<4>().valid(); }
+  uint32_t trace_type() const { return at<4>().as_uint32(); }
+  bool has_value() const { return at<5>().valid(); }
+  int32_t value() const { return at<5>().as_int32(); }
+};
+
+class SamsungTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SamsungTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTraceNameFieldNumber = 2,
+    kTraceBeginFieldNumber = 3,
+    kTraceTypeFieldNumber = 4,
+    kValueFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SamsungTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SamsungTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SamsungTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceName kTraceName{};
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, size);
+  }
+  void set_trace_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SamsungTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceBegin kTraceBegin{};
+  void set_trace_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceBegin::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SamsungTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceType kTraceType{};
+  void set_trace_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SamsungTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/sched.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SCHED_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SCHED_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SchedCpuUtilCfsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedCpuUtilCfsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedCpuUtilCfsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedCpuUtilCfsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_active() const { return at<1>().valid(); }
+  int32_t active() const { return at<1>().as_int32(); }
+  bool has_capacity() const { return at<2>().valid(); }
+  uint64_t capacity() const { return at<2>().as_uint64(); }
+  bool has_capacity_orig() const { return at<3>().valid(); }
+  uint64_t capacity_orig() const { return at<3>().as_uint64(); }
+  bool has_cpu() const { return at<4>().valid(); }
+  uint32_t cpu() const { return at<4>().as_uint32(); }
+  bool has_cpu_importance() const { return at<5>().valid(); }
+  uint64_t cpu_importance() const { return at<5>().as_uint64(); }
+  bool has_cpu_util() const { return at<6>().valid(); }
+  uint64_t cpu_util() const { return at<6>().as_uint64(); }
+  bool has_exit_lat() const { return at<7>().valid(); }
+  uint32_t exit_lat() const { return at<7>().as_uint32(); }
+  bool has_group_capacity() const { return at<8>().valid(); }
+  uint64_t group_capacity() const { return at<8>().as_uint64(); }
+  bool has_grp_overutilized() const { return at<9>().valid(); }
+  uint32_t grp_overutilized() const { return at<9>().as_uint32(); }
+  bool has_idle_cpu() const { return at<10>().valid(); }
+  uint32_t idle_cpu() const { return at<10>().as_uint32(); }
+  bool has_nr_running() const { return at<11>().valid(); }
+  uint32_t nr_running() const { return at<11>().as_uint32(); }
+  bool has_spare_cap() const { return at<12>().valid(); }
+  int64_t spare_cap() const { return at<12>().as_int64(); }
+  bool has_task_fits() const { return at<13>().valid(); }
+  uint32_t task_fits() const { return at<13>().as_uint32(); }
+  bool has_wake_group_util() const { return at<14>().valid(); }
+  uint64_t wake_group_util() const { return at<14>().as_uint64(); }
+  bool has_wake_util() const { return at<15>().valid(); }
+  uint64_t wake_util() const { return at<15>().as_uint64(); }
+};
+
+class SchedCpuUtilCfsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedCpuUtilCfsFtraceEvent_Decoder;
+  enum : int32_t {
+    kActiveFieldNumber = 1,
+    kCapacityFieldNumber = 2,
+    kCapacityOrigFieldNumber = 3,
+    kCpuFieldNumber = 4,
+    kCpuImportanceFieldNumber = 5,
+    kCpuUtilFieldNumber = 6,
+    kExitLatFieldNumber = 7,
+    kGroupCapacityFieldNumber = 8,
+    kGrpOverutilizedFieldNumber = 9,
+    kIdleCpuFieldNumber = 10,
+    kNrRunningFieldNumber = 11,
+    kSpareCapFieldNumber = 12,
+    kTaskFitsFieldNumber = 13,
+    kWakeGroupUtilFieldNumber = 14,
+    kWakeUtilFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedCpuUtilCfsFtraceEvent"; }
+
+
+  using FieldMetadata_Active =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_Active kActive{};
+  void set_active(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Active::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Capacity =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_Capacity kCapacity{};
+  void set_capacity(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Capacity::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CapacityOrig =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_CapacityOrig kCapacityOrig{};
+  void set_capacity_orig(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CapacityOrig::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuImportance =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuImportance kCpuImportance{};
+  void set_cpu_importance(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuImportance::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuUtil =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_CpuUtil kCpuUtil{};
+  void set_cpu_util(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuUtil::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExitLat =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_ExitLat kExitLat{};
+  void set_exit_lat(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExitLat::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GroupCapacity =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_GroupCapacity kGroupCapacity{};
+  void set_group_capacity(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GroupCapacity::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GrpOverutilized =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_GrpOverutilized kGrpOverutilized{};
+  void set_grp_overutilized(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GrpOverutilized::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IdleCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_IdleCpu kIdleCpu{};
+  void set_idle_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IdleCpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrRunning =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_NrRunning kNrRunning{};
+  void set_nr_running(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrRunning::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SpareCap =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_SpareCap kSpareCap{};
+  void set_spare_cap(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SpareCap::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TaskFits =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_TaskFits kTaskFits{};
+  void set_task_fits(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TaskFits::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WakeGroupUtil =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_WakeGroupUtil kWakeGroupUtil{};
+  void set_wake_group_util(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WakeGroupUtil::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WakeUtil =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedCpuUtilCfsFtraceEvent>;
+
+  static constexpr FieldMetadata_WakeUtil kWakeUtil{};
+  void set_wake_util(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WakeUtil::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedPiSetprioFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedPiSetprioFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedPiSetprioFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedPiSetprioFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_newprio() const { return at<2>().valid(); }
+  int32_t newprio() const { return at<2>().as_int32(); }
+  bool has_oldprio() const { return at<3>().valid(); }
+  int32_t oldprio() const { return at<3>().as_int32(); }
+  bool has_pid() const { return at<4>().valid(); }
+  int32_t pid() const { return at<4>().as_int32(); }
+};
+
+class SchedPiSetprioFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedPiSetprioFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kNewprioFieldNumber = 2,
+    kOldprioFieldNumber = 3,
+    kPidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedPiSetprioFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedPiSetprioFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Newprio =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedPiSetprioFtraceEvent>;
+
+  static constexpr FieldMetadata_Newprio kNewprio{};
+  void set_newprio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Newprio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Oldprio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedPiSetprioFtraceEvent>;
+
+  static constexpr FieldMetadata_Oldprio kOldprio{};
+  void set_oldprio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Oldprio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedPiSetprioFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedProcessWaitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessWaitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessWaitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessWaitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+};
+
+class SchedProcessWaitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessWaitFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessWaitFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedProcessHangFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessHangFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessHangFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessHangFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+};
+
+class SchedProcessHangFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessHangFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessHangFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessHangFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessHangFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedProcessFreeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessFreeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessFreeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessFreeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+};
+
+class SchedProcessFreeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessFreeFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessFreeFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessFreeFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedProcessForkFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessForkFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessForkFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessForkFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_parent_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars parent_comm() const { return at<1>().as_string(); }
+  bool has_parent_pid() const { return at<2>().valid(); }
+  int32_t parent_pid() const { return at<2>().as_int32(); }
+  bool has_child_comm() const { return at<3>().valid(); }
+  ::protozero::ConstChars child_comm() const { return at<3>().as_string(); }
+  bool has_child_pid() const { return at<4>().valid(); }
+  int32_t child_pid() const { return at<4>().as_int32(); }
+};
+
+class SchedProcessForkFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessForkFtraceEvent_Decoder;
+  enum : int32_t {
+    kParentCommFieldNumber = 1,
+    kParentPidFieldNumber = 2,
+    kChildCommFieldNumber = 3,
+    kChildPidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessForkFtraceEvent"; }
+
+
+  using FieldMetadata_ParentComm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessForkFtraceEvent>;
+
+  static constexpr FieldMetadata_ParentComm kParentComm{};
+  void set_parent_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ParentComm::kFieldId, data, size);
+  }
+  void set_parent_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ParentComm::kFieldId, chars.data, chars.size);
+  }
+  void set_parent_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParentComm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ParentPid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessForkFtraceEvent>;
+
+  static constexpr FieldMetadata_ParentPid kParentPid{};
+  void set_parent_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ParentPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChildComm =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessForkFtraceEvent>;
+
+  static constexpr FieldMetadata_ChildComm kChildComm{};
+  void set_child_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ChildComm::kFieldId, data, size);
+  }
+  void set_child_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ChildComm::kFieldId, chars.data, chars.size);
+  }
+  void set_child_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChildComm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChildPid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessForkFtraceEvent>;
+
+  static constexpr FieldMetadata_ChildPid kChildPid{};
+  void set_child_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChildPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedProcessExitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessExitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessExitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessExitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_tgid() const { return at<3>().valid(); }
+  int32_t tgid() const { return at<3>().as_int32(); }
+  bool has_prio() const { return at<4>().valid(); }
+  int32_t prio() const { return at<4>().as_int32(); }
+};
+
+class SchedProcessExitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessExitFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTgidFieldNumber = 3,
+    kPrioFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessExitFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tgid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Tgid kTgid{};
+  void set_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tgid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessExitFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedProcessExecFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedProcessExecFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedProcessExecFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedProcessExecFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_filename() const { return at<1>().valid(); }
+  ::protozero::ConstChars filename() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_old_pid() const { return at<3>().valid(); }
+  int32_t old_pid() const { return at<3>().as_int32(); }
+};
+
+class SchedProcessExecFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedProcessExecFtraceEvent_Decoder;
+  enum : int32_t {
+    kFilenameFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kOldPidFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedProcessExecFtraceEvent"; }
+
+
+  using FieldMetadata_Filename =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedProcessExecFtraceEvent>;
+
+  static constexpr FieldMetadata_Filename kFilename{};
+  void set_filename(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Filename::kFieldId, data, size);
+  }
+  void set_filename(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Filename::kFieldId, chars.data, chars.size);
+  }
+  void set_filename(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Filename::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessExecFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OldPid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedProcessExecFtraceEvent>;
+
+  static constexpr FieldMetadata_OldPid kOldPid{};
+  void set_old_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OldPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedWakeupNewFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedWakeupNewFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedWakeupNewFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedWakeupNewFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+  bool has_success() const { return at<4>().valid(); }
+  int32_t success() const { return at<4>().as_int32(); }
+  bool has_target_cpu() const { return at<5>().valid(); }
+  int32_t target_cpu() const { return at<5>().as_int32(); }
+};
+
+class SchedWakeupNewFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedWakeupNewFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+    kSuccessFieldNumber = 4,
+    kTargetCpuFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedWakeupNewFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedWakeupNewFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupNewFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupNewFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Success =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupNewFtraceEvent>;
+
+  static constexpr FieldMetadata_Success kSuccess{};
+  void set_success(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Success::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupNewFtraceEvent>;
+
+  static constexpr FieldMetadata_TargetCpu kTargetCpu{};
+  void set_target_cpu(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedWakingFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedWakingFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedWakingFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedWakingFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+  bool has_success() const { return at<4>().valid(); }
+  int32_t success() const { return at<4>().as_int32(); }
+  bool has_target_cpu() const { return at<5>().valid(); }
+  int32_t target_cpu() const { return at<5>().as_int32(); }
+};
+
+class SchedWakingFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedWakingFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+    kSuccessFieldNumber = 4,
+    kTargetCpuFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedWakingFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedWakingFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakingFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakingFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Success =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakingFtraceEvent>;
+
+  static constexpr FieldMetadata_Success kSuccess{};
+  void set_success(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Success::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakingFtraceEvent>;
+
+  static constexpr FieldMetadata_TargetCpu kTargetCpu{};
+  void set_target_cpu(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedCpuHotplugFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedCpuHotplugFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedCpuHotplugFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedCpuHotplugFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_affected_cpu() const { return at<1>().valid(); }
+  int32_t affected_cpu() const { return at<1>().as_int32(); }
+  bool has_error() const { return at<2>().valid(); }
+  int32_t error() const { return at<2>().as_int32(); }
+  bool has_status() const { return at<3>().valid(); }
+  int32_t status() const { return at<3>().as_int32(); }
+};
+
+class SchedCpuHotplugFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedCpuHotplugFtraceEvent_Decoder;
+  enum : int32_t {
+    kAffectedCpuFieldNumber = 1,
+    kErrorFieldNumber = 2,
+    kStatusFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedCpuHotplugFtraceEvent"; }
+
+
+  using FieldMetadata_AffectedCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedCpuHotplugFtraceEvent>;
+
+  static constexpr FieldMetadata_AffectedCpu kAffectedCpu{};
+  void set_affected_cpu(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AffectedCpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Error =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedCpuHotplugFtraceEvent>;
+
+  static constexpr FieldMetadata_Error kError{};
+  void set_error(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Error::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedCpuHotplugFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedBlockedReasonFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedBlockedReasonFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedBlockedReasonFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedBlockedReasonFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_caller() const { return at<2>().valid(); }
+  uint64_t caller() const { return at<2>().as_uint64(); }
+  bool has_io_wait() const { return at<3>().valid(); }
+  uint32_t io_wait() const { return at<3>().as_uint32(); }
+};
+
+class SchedBlockedReasonFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedBlockedReasonFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kCallerFieldNumber = 2,
+    kIoWaitFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedBlockedReasonFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedBlockedReasonFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Caller =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SchedBlockedReasonFtraceEvent>;
+
+  static constexpr FieldMetadata_Caller kCaller{};
+  void set_caller(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Caller::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IoWait =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SchedBlockedReasonFtraceEvent>;
+
+  static constexpr FieldMetadata_IoWait kIoWait{};
+  void set_io_wait(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IoWait::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedWakeupFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedWakeupFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedWakeupFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedWakeupFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars comm() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+  bool has_success() const { return at<4>().valid(); }
+  int32_t success() const { return at<4>().as_int32(); }
+  bool has_target_cpu() const { return at<5>().valid(); }
+  int32_t target_cpu() const { return at<5>().as_int32(); }
+};
+
+class SchedWakeupFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedWakeupFtraceEvent_Decoder;
+  enum : int32_t {
+    kCommFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+    kSuccessFieldNumber = 4,
+    kTargetCpuFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedWakeupFtraceEvent"; }
+
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Success =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_Success kSuccess{};
+  void set_success(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Success::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedWakeupFtraceEvent>;
+
+  static constexpr FieldMetadata_TargetCpu kTargetCpu{};
+  void set_target_cpu(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetCpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SchedSwitchFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SchedSwitchFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SchedSwitchFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SchedSwitchFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_prev_comm() const { return at<1>().valid(); }
+  ::protozero::ConstChars prev_comm() const { return at<1>().as_string(); }
+  bool has_prev_pid() const { return at<2>().valid(); }
+  int32_t prev_pid() const { return at<2>().as_int32(); }
+  bool has_prev_prio() const { return at<3>().valid(); }
+  int32_t prev_prio() const { return at<3>().as_int32(); }
+  bool has_prev_state() const { return at<4>().valid(); }
+  int64_t prev_state() const { return at<4>().as_int64(); }
+  bool has_next_comm() const { return at<5>().valid(); }
+  ::protozero::ConstChars next_comm() const { return at<5>().as_string(); }
+  bool has_next_pid() const { return at<6>().valid(); }
+  int32_t next_pid() const { return at<6>().as_int32(); }
+  bool has_next_prio() const { return at<7>().valid(); }
+  int32_t next_prio() const { return at<7>().as_int32(); }
+};
+
+class SchedSwitchFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SchedSwitchFtraceEvent_Decoder;
+  enum : int32_t {
+    kPrevCommFieldNumber = 1,
+    kPrevPidFieldNumber = 2,
+    kPrevPrioFieldNumber = 3,
+    kPrevStateFieldNumber = 4,
+    kNextCommFieldNumber = 5,
+    kNextPidFieldNumber = 6,
+    kNextPrioFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SchedSwitchFtraceEvent"; }
+
+
+  using FieldMetadata_PrevComm =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevComm kPrevComm{};
+  void set_prev_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PrevComm::kFieldId, data, size);
+  }
+  void set_prev_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PrevComm::kFieldId, chars.data, chars.size);
+  }
+  void set_prev_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevComm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrevPid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevPid kPrevPid{};
+  void set_prev_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrevPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevPrio kPrevPrio{};
+  void set_prev_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevPrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrevState =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_PrevState kPrevState{};
+  void set_prev_state(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrevState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NextComm =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_NextComm kNextComm{};
+  void set_next_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_NextComm::kFieldId, data, size);
+  }
+  void set_next_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_NextComm::kFieldId, chars.data, chars.size);
+  }
+  void set_next_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_NextComm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NextPid =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_NextPid kNextPid{};
+  void set_next_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NextPid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NextPrio =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SchedSwitchFtraceEvent>;
+
+  static constexpr FieldMetadata_NextPrio kNextPrio{};
+  void set_next_prio(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NextPrio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/scm.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SCM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SCM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ScmCallEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ScmCallEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ScmCallEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ScmCallEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class ScmCallEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ScmCallEndFtraceEvent_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.ScmCallEndFtraceEvent"; }
+
+};
+
+class ScmCallStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ScmCallStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ScmCallStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ScmCallStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_arginfo() const { return at<1>().valid(); }
+  uint32_t arginfo() const { return at<1>().as_uint32(); }
+  bool has_x0() const { return at<2>().valid(); }
+  uint64_t x0() const { return at<2>().as_uint64(); }
+  bool has_x5() const { return at<3>().valid(); }
+  uint64_t x5() const { return at<3>().as_uint64(); }
+};
+
+class ScmCallStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ScmCallStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kArginfoFieldNumber = 1,
+    kX0FieldNumber = 2,
+    kX5FieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ScmCallStartFtraceEvent"; }
+
+
+  using FieldMetadata_Arginfo =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ScmCallStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Arginfo kArginfo{};
+  void set_arginfo(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Arginfo::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_X0 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ScmCallStartFtraceEvent>;
+
+  static constexpr FieldMetadata_X0 kX0{};
+  void set_x0(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_X0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_X5 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ScmCallStartFtraceEvent>;
+
+  static constexpr FieldMetadata_X5 kX5{};
+  void set_x5(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_X5::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/sde.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SDE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SDE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SdeSdePerfUpdateBusFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeSdePerfUpdateBusFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeSdePerfUpdateBusFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeSdePerfUpdateBusFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ab_quota() const { return at<1>().valid(); }
+  uint64_t ab_quota() const { return at<1>().as_uint64(); }
+  bool has_bus_id() const { return at<2>().valid(); }
+  uint32_t bus_id() const { return at<2>().as_uint32(); }
+  bool has_client() const { return at<3>().valid(); }
+  int32_t client() const { return at<3>().as_int32(); }
+  bool has_ib_quota() const { return at<4>().valid(); }
+  uint64_t ib_quota() const { return at<4>().as_uint64(); }
+};
+
+class SdeSdePerfUpdateBusFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeSdePerfUpdateBusFtraceEvent_Decoder;
+  enum : int32_t {
+    kAbQuotaFieldNumber = 1,
+    kBusIdFieldNumber = 2,
+    kClientFieldNumber = 3,
+    kIbQuotaFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeSdePerfUpdateBusFtraceEvent"; }
+
+
+  using FieldMetadata_AbQuota =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_AbQuota kAbQuota{};
+  void set_ab_quota(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AbQuota::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BusId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_BusId kBusId{};
+  void set_bus_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BusId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Client =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeSdePerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_Client kClient{};
+  void set_client(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Client::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IbQuota =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfUpdateBusFtraceEvent>;
+
+  static constexpr FieldMetadata_IbQuota kIbQuota{};
+  void set_ib_quota(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IbQuota::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SdeSdePerfSetQosLutsFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeSdePerfSetQosLutsFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeSdePerfSetQosLutsFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeSdePerfSetQosLutsFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_fl() const { return at<1>().valid(); }
+  uint32_t fl() const { return at<1>().as_uint32(); }
+  bool has_fmt() const { return at<2>().valid(); }
+  uint32_t fmt() const { return at<2>().as_uint32(); }
+  bool has_lut() const { return at<3>().valid(); }
+  uint64_t lut() const { return at<3>().as_uint64(); }
+  bool has_lut_usage() const { return at<4>().valid(); }
+  uint32_t lut_usage() const { return at<4>().as_uint32(); }
+  bool has_pnum() const { return at<5>().valid(); }
+  uint32_t pnum() const { return at<5>().as_uint32(); }
+  bool has_rt() const { return at<6>().valid(); }
+  uint32_t rt() const { return at<6>().as_uint32(); }
+};
+
+class SdeSdePerfSetQosLutsFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeSdePerfSetQosLutsFtraceEvent_Decoder;
+  enum : int32_t {
+    kFlFieldNumber = 1,
+    kFmtFieldNumber = 2,
+    kLutFieldNumber = 3,
+    kLutUsageFieldNumber = 4,
+    kPnumFieldNumber = 5,
+    kRtFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeSdePerfSetQosLutsFtraceEvent"; }
+
+
+  using FieldMetadata_Fl =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Fl kFl{};
+  void set_fl(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fl::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fmt =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Fmt kFmt{};
+  void set_fmt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fmt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lut =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Lut kLut{};
+  void set_lut(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lut::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LutUsage =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_LutUsage kLutUsage{};
+  void set_lut_usage(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LutUsage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pnum =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Pnum kPnum{};
+  void set_pnum(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pnum::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Rt =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfSetQosLutsFtraceEvent>;
+
+  static constexpr FieldMetadata_Rt kRt{};
+  void set_rt(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Rt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SdeSdePerfCrtcUpdateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeSdePerfCrtcUpdateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeSdePerfCrtcUpdateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeSdePerfCrtcUpdateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bw_ctl_ebi() const { return at<1>().valid(); }
+  uint64_t bw_ctl_ebi() const { return at<1>().as_uint64(); }
+  bool has_bw_ctl_llcc() const { return at<2>().valid(); }
+  uint64_t bw_ctl_llcc() const { return at<2>().as_uint64(); }
+  bool has_bw_ctl_mnoc() const { return at<3>().valid(); }
+  uint64_t bw_ctl_mnoc() const { return at<3>().as_uint64(); }
+  bool has_core_clk_rate() const { return at<4>().valid(); }
+  uint32_t core_clk_rate() const { return at<4>().as_uint32(); }
+  bool has_crtc() const { return at<5>().valid(); }
+  uint32_t crtc() const { return at<5>().as_uint32(); }
+  bool has_params() const { return at<6>().valid(); }
+  int32_t params() const { return at<6>().as_int32(); }
+  bool has_per_pipe_ib_ebi() const { return at<7>().valid(); }
+  uint64_t per_pipe_ib_ebi() const { return at<7>().as_uint64(); }
+  bool has_per_pipe_ib_llcc() const { return at<8>().valid(); }
+  uint64_t per_pipe_ib_llcc() const { return at<8>().as_uint64(); }
+  bool has_per_pipe_ib_mnoc() const { return at<9>().valid(); }
+  uint64_t per_pipe_ib_mnoc() const { return at<9>().as_uint64(); }
+  bool has_stop_req() const { return at<10>().valid(); }
+  uint32_t stop_req() const { return at<10>().as_uint32(); }
+  bool has_update_bus() const { return at<11>().valid(); }
+  uint32_t update_bus() const { return at<11>().as_uint32(); }
+  bool has_update_clk() const { return at<12>().valid(); }
+  uint32_t update_clk() const { return at<12>().as_uint32(); }
+};
+
+class SdeSdePerfCrtcUpdateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeSdePerfCrtcUpdateFtraceEvent_Decoder;
+  enum : int32_t {
+    kBwCtlEbiFieldNumber = 1,
+    kBwCtlLlccFieldNumber = 2,
+    kBwCtlMnocFieldNumber = 3,
+    kCoreClkRateFieldNumber = 4,
+    kCrtcFieldNumber = 5,
+    kParamsFieldNumber = 6,
+    kPerPipeIbEbiFieldNumber = 7,
+    kPerPipeIbLlccFieldNumber = 8,
+    kPerPipeIbMnocFieldNumber = 9,
+    kStopReqFieldNumber = 10,
+    kUpdateBusFieldNumber = 11,
+    kUpdateClkFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeSdePerfCrtcUpdateFtraceEvent"; }
+
+
+  using FieldMetadata_BwCtlEbi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlEbi kBwCtlEbi{};
+  void set_bw_ctl_ebi(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlEbi::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BwCtlLlcc =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlLlcc kBwCtlLlcc{};
+  void set_bw_ctl_llcc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlLlcc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BwCtlMnoc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlMnoc kBwCtlMnoc{};
+  void set_bw_ctl_mnoc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlMnoc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CoreClkRate =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_CoreClkRate kCoreClkRate{};
+  void set_core_clk_rate(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CoreClkRate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Crtc =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Crtc kCrtc{};
+  void set_crtc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Crtc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Params =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Params kParams{};
+  void set_params(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Params::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PerPipeIbEbi =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_PerPipeIbEbi kPerPipeIbEbi{};
+  void set_per_pipe_ib_ebi(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PerPipeIbEbi::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PerPipeIbLlcc =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_PerPipeIbLlcc kPerPipeIbLlcc{};
+  void set_per_pipe_ib_llcc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PerPipeIbLlcc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PerPipeIbMnoc =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_PerPipeIbMnoc kPerPipeIbMnoc{};
+  void set_per_pipe_ib_mnoc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PerPipeIbMnoc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StopReq =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_StopReq kStopReq{};
+  void set_stop_req(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StopReq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UpdateBus =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_UpdateBus kUpdateBus{};
+  void set_update_bus(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UpdateBus::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UpdateClk =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCrtcUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_UpdateClk kUpdateClk{};
+  void set_update_clk(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UpdateClk::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SdeSdePerfCalcCrtcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeSdePerfCalcCrtcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeSdePerfCalcCrtcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeSdePerfCalcCrtcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bw_ctl_ebi() const { return at<1>().valid(); }
+  uint64_t bw_ctl_ebi() const { return at<1>().as_uint64(); }
+  bool has_bw_ctl_llcc() const { return at<2>().valid(); }
+  uint64_t bw_ctl_llcc() const { return at<2>().as_uint64(); }
+  bool has_bw_ctl_mnoc() const { return at<3>().valid(); }
+  uint64_t bw_ctl_mnoc() const { return at<3>().as_uint64(); }
+  bool has_core_clk_rate() const { return at<4>().valid(); }
+  uint32_t core_clk_rate() const { return at<4>().as_uint32(); }
+  bool has_crtc() const { return at<5>().valid(); }
+  uint32_t crtc() const { return at<5>().as_uint32(); }
+  bool has_ib_ebi() const { return at<6>().valid(); }
+  uint64_t ib_ebi() const { return at<6>().as_uint64(); }
+  bool has_ib_llcc() const { return at<7>().valid(); }
+  uint64_t ib_llcc() const { return at<7>().as_uint64(); }
+  bool has_ib_mnoc() const { return at<8>().valid(); }
+  uint64_t ib_mnoc() const { return at<8>().as_uint64(); }
+};
+
+class SdeSdePerfCalcCrtcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeSdePerfCalcCrtcFtraceEvent_Decoder;
+  enum : int32_t {
+    kBwCtlEbiFieldNumber = 1,
+    kBwCtlLlccFieldNumber = 2,
+    kBwCtlMnocFieldNumber = 3,
+    kCoreClkRateFieldNumber = 4,
+    kCrtcFieldNumber = 5,
+    kIbEbiFieldNumber = 6,
+    kIbLlccFieldNumber = 7,
+    kIbMnocFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeSdePerfCalcCrtcFtraceEvent"; }
+
+
+  using FieldMetadata_BwCtlEbi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlEbi kBwCtlEbi{};
+  void set_bw_ctl_ebi(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlEbi::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BwCtlLlcc =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlLlcc kBwCtlLlcc{};
+  void set_bw_ctl_llcc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlLlcc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BwCtlMnoc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_BwCtlMnoc kBwCtlMnoc{};
+  void set_bw_ctl_mnoc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BwCtlMnoc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CoreClkRate =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_CoreClkRate kCoreClkRate{};
+  void set_core_clk_rate(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CoreClkRate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Crtc =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_Crtc kCrtc{};
+  void set_crtc(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Crtc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IbEbi =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_IbEbi kIbEbi{};
+  void set_ib_ebi(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IbEbi::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IbLlcc =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_IbLlcc kIbLlcc{};
+  void set_ib_llcc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IbLlcc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IbMnoc =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SdeSdePerfCalcCrtcFtraceEvent>;
+
+  static constexpr FieldMetadata_IbMnoc kIbMnoc{};
+  void set_ib_mnoc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IbMnoc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SdeSdeEvtlogFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeSdeEvtlogFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeSdeEvtlogFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeSdeEvtlogFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_evtlog_tag() const { return at<1>().valid(); }
+  ::protozero::ConstChars evtlog_tag() const { return at<1>().as_string(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_tag_id() const { return at<3>().valid(); }
+  uint32_t tag_id() const { return at<3>().as_uint32(); }
+};
+
+class SdeSdeEvtlogFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeSdeEvtlogFtraceEvent_Decoder;
+  enum : int32_t {
+    kEvtlogTagFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTagIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeSdeEvtlogFtraceEvent"; }
+
+
+  using FieldMetadata_EvtlogTag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SdeSdeEvtlogFtraceEvent>;
+
+  static constexpr FieldMetadata_EvtlogTag kEvtlogTag{};
+  void set_evtlog_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EvtlogTag::kFieldId, data, size);
+  }
+  void set_evtlog_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EvtlogTag::kFieldId, chars.data, chars.size);
+  }
+  void set_evtlog_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EvtlogTag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeSdeEvtlogFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TagId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeSdeEvtlogFtraceEvent>;
+
+  static constexpr FieldMetadata_TagId kTagId{};
+  void set_tag_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TagId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SdeTracingMarkWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SdeTracingMarkWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SdeTracingMarkWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SdeTracingMarkWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_trace_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars trace_name() const { return at<2>().as_string(); }
+  bool has_trace_type() const { return at<3>().valid(); }
+  uint32_t trace_type() const { return at<3>().as_uint32(); }
+  bool has_value() const { return at<4>().valid(); }
+  int32_t value() const { return at<4>().as_int32(); }
+  bool has_trace_begin() const { return at<5>().valid(); }
+  uint32_t trace_begin() const { return at<5>().as_uint32(); }
+};
+
+class SdeTracingMarkWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SdeTracingMarkWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTraceNameFieldNumber = 2,
+    kTraceTypeFieldNumber = 3,
+    kValueFieldNumber = 4,
+    kTraceBeginFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SdeTracingMarkWriteFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceName kTraceName{};
+  void set_trace_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, data, size);
+  }
+  void set_trace_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_TraceName::kFieldId, chars.data, chars.size);
+  }
+  void set_trace_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceType kTraceType{};
+  void set_trace_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TraceBegin =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SdeTracingMarkWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_TraceBegin kTraceBegin{};
+  void set_trace_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceBegin::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/signal.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SIGNAL_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SIGNAL_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SignalGenerateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SignalGenerateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SignalGenerateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SignalGenerateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_code() const { return at<1>().valid(); }
+  int32_t code() const { return at<1>().as_int32(); }
+  bool has_comm() const { return at<2>().valid(); }
+  ::protozero::ConstChars comm() const { return at<2>().as_string(); }
+  bool has_group() const { return at<3>().valid(); }
+  int32_t group() const { return at<3>().as_int32(); }
+  bool has_pid() const { return at<4>().valid(); }
+  int32_t pid() const { return at<4>().as_int32(); }
+  bool has_result() const { return at<5>().valid(); }
+  int32_t result() const { return at<5>().as_int32(); }
+  bool has_sig() const { return at<6>().valid(); }
+  int32_t sig() const { return at<6>().as_int32(); }
+};
+
+class SignalGenerateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SignalGenerateFtraceEvent_Decoder;
+  enum : int32_t {
+    kCodeFieldNumber = 1,
+    kCommFieldNumber = 2,
+    kGroupFieldNumber = 3,
+    kPidFieldNumber = 4,
+    kResultFieldNumber = 5,
+    kSigFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SignalGenerateFtraceEvent"; }
+
+
+  using FieldMetadata_Code =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Code kCode{};
+  void set_code(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Code::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Group =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Group kGroup{};
+  void set_group(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Group::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Result =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Result kResult{};
+  void set_result(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Result::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sig =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalGenerateFtraceEvent>;
+
+  static constexpr FieldMetadata_Sig kSig{};
+  void set_sig(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sig::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SignalDeliverFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SignalDeliverFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SignalDeliverFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SignalDeliverFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_code() const { return at<1>().valid(); }
+  int32_t code() const { return at<1>().as_int32(); }
+  bool has_sa_flags() const { return at<2>().valid(); }
+  uint64_t sa_flags() const { return at<2>().as_uint64(); }
+  bool has_sig() const { return at<3>().valid(); }
+  int32_t sig() const { return at<3>().as_int32(); }
+};
+
+class SignalDeliverFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SignalDeliverFtraceEvent_Decoder;
+  enum : int32_t {
+    kCodeFieldNumber = 1,
+    kSaFlagsFieldNumber = 2,
+    kSigFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SignalDeliverFtraceEvent"; }
+
+
+  using FieldMetadata_Code =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalDeliverFtraceEvent>;
+
+  static constexpr FieldMetadata_Code kCode{};
+  void set_code(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Code::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SaFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SignalDeliverFtraceEvent>;
+
+  static constexpr FieldMetadata_SaFlags kSaFlags{};
+  void set_sa_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SaFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sig =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SignalDeliverFtraceEvent>;
+
+  static constexpr FieldMetadata_Sig kSig{};
+  void set_sig(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sig::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/skb.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SKB_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SKB_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class KfreeSkbFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  KfreeSkbFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit KfreeSkbFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit KfreeSkbFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_location() const { return at<1>().valid(); }
+  uint64_t location() const { return at<1>().as_uint64(); }
+  bool has_protocol() const { return at<2>().valid(); }
+  uint32_t protocol() const { return at<2>().as_uint32(); }
+  bool has_skbaddr() const { return at<3>().valid(); }
+  uint64_t skbaddr() const { return at<3>().as_uint64(); }
+};
+
+class KfreeSkbFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = KfreeSkbFtraceEvent_Decoder;
+  enum : int32_t {
+    kLocationFieldNumber = 1,
+    kProtocolFieldNumber = 2,
+    kSkbaddrFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.KfreeSkbFtraceEvent"; }
+
+
+  using FieldMetadata_Location =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KfreeSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Location kLocation{};
+  void set_location(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Location::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      KfreeSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Skbaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      KfreeSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Skbaddr kSkbaddr{};
+  void set_skbaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skbaddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/sock.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SOCK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SOCK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class InetSockSetStateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InetSockSetStateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InetSockSetStateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InetSockSetStateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_daddr() const { return at<1>().valid(); }
+  uint32_t daddr() const { return at<1>().as_uint32(); }
+  bool has_dport() const { return at<2>().valid(); }
+  uint32_t dport() const { return at<2>().as_uint32(); }
+  bool has_family() const { return at<3>().valid(); }
+  uint32_t family() const { return at<3>().as_uint32(); }
+  bool has_newstate() const { return at<4>().valid(); }
+  int32_t newstate() const { return at<4>().as_int32(); }
+  bool has_oldstate() const { return at<5>().valid(); }
+  int32_t oldstate() const { return at<5>().as_int32(); }
+  bool has_protocol() const { return at<6>().valid(); }
+  uint32_t protocol() const { return at<6>().as_uint32(); }
+  bool has_saddr() const { return at<7>().valid(); }
+  uint32_t saddr() const { return at<7>().as_uint32(); }
+  bool has_skaddr() const { return at<8>().valid(); }
+  uint64_t skaddr() const { return at<8>().as_uint64(); }
+  bool has_sport() const { return at<9>().valid(); }
+  uint32_t sport() const { return at<9>().as_uint32(); }
+};
+
+class InetSockSetStateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = InetSockSetStateFtraceEvent_Decoder;
+  enum : int32_t {
+    kDaddrFieldNumber = 1,
+    kDportFieldNumber = 2,
+    kFamilyFieldNumber = 3,
+    kNewstateFieldNumber = 4,
+    kOldstateFieldNumber = 5,
+    kProtocolFieldNumber = 6,
+    kSaddrFieldNumber = 7,
+    kSkaddrFieldNumber = 8,
+    kSportFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InetSockSetStateFtraceEvent"; }
+
+
+  using FieldMetadata_Daddr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Daddr kDaddr{};
+  void set_daddr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Daddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dport =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Dport kDport{};
+  void set_dport(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dport::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Family =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Family kFamily{};
+  void set_family(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Family::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Newstate =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Newstate kNewstate{};
+  void set_newstate(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Newstate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Oldstate =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Oldstate kOldstate{};
+  void set_oldstate(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Oldstate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Protocol =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Protocol kProtocol{};
+  void set_protocol(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Protocol::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Saddr =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Saddr kSaddr{};
+  void set_saddr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Saddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Skaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Skaddr kSkaddr{};
+  void set_skaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skaddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sport =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      InetSockSetStateFtraceEvent>;
+
+  static constexpr FieldMetadata_Sport kSport{};
+  void set_sport(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sport::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/sync.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYNC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYNC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SyncWaitFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SyncWaitFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SyncWaitFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SyncWaitFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_status() const { return at<2>().valid(); }
+  int32_t status() const { return at<2>().as_int32(); }
+  bool has_begin() const { return at<3>().valid(); }
+  uint32_t begin() const { return at<3>().as_uint32(); }
+};
+
+class SyncWaitFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SyncWaitFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kStatusFieldNumber = 2,
+    kBeginFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SyncWaitFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Status =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SyncWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Status kStatus{};
+  void set_status(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Status::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Begin =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SyncWaitFtraceEvent>;
+
+  static constexpr FieldMetadata_Begin kBegin{};
+  void set_begin(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Begin::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SyncTimelineFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SyncTimelineFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SyncTimelineFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SyncTimelineFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class SyncTimelineFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SyncTimelineFtraceEvent_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SyncTimelineFtraceEvent"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncTimelineFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncTimelineFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SyncPtFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SyncPtFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SyncPtFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SyncPtFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timeline() const { return at<1>().valid(); }
+  ::protozero::ConstChars timeline() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class SyncPtFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SyncPtFtraceEvent_Decoder;
+  enum : int32_t {
+    kTimelineFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SyncPtFtraceEvent"; }
+
+
+  using FieldMetadata_Timeline =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncPtFtraceEvent>;
+
+  static constexpr FieldMetadata_Timeline kTimeline{};
+  void set_timeline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, data, size);
+  }
+  void set_timeline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Timeline::kFieldId, chars.data, chars.size);
+  }
+  void set_timeline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timeline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SyncPtFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/synthetic.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYNTHETIC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYNTHETIC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SuspendResumeMinimalFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SuspendResumeMinimalFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SuspendResumeMinimalFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SuspendResumeMinimalFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_start() const { return at<1>().valid(); }
+  uint32_t start() const { return at<1>().as_uint32(); }
+};
+
+class SuspendResumeMinimalFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = SuspendResumeMinimalFtraceEvent_Decoder;
+  enum : int32_t {
+    kStartFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SuspendResumeMinimalFtraceEvent"; }
+
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SuspendResumeMinimalFtraceEvent>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class RssStatThrottledFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  RssStatThrottledFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit RssStatThrottledFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit RssStatThrottledFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_curr() const { return at<1>().valid(); }
+  uint32_t curr() const { return at<1>().as_uint32(); }
+  bool has_member() const { return at<2>().valid(); }
+  int32_t member() const { return at<2>().as_int32(); }
+  bool has_mm_id() const { return at<3>().valid(); }
+  uint32_t mm_id() const { return at<3>().as_uint32(); }
+  bool has_size() const { return at<4>().valid(); }
+  int64_t size() const { return at<4>().as_int64(); }
+};
+
+class RssStatThrottledFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = RssStatThrottledFtraceEvent_Decoder;
+  enum : int32_t {
+    kCurrFieldNumber = 1,
+    kMemberFieldNumber = 2,
+    kMmIdFieldNumber = 3,
+    kSizeFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.RssStatThrottledFtraceEvent"; }
+
+
+  using FieldMetadata_Curr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RssStatThrottledFtraceEvent>;
+
+  static constexpr FieldMetadata_Curr kCurr{};
+  void set_curr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Curr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Member =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      RssStatThrottledFtraceEvent>;
+
+  static constexpr FieldMetadata_Member kMember{};
+  void set_member(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Member::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MmId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      RssStatThrottledFtraceEvent>;
+
+  static constexpr FieldMetadata_MmId kMmId{};
+  void set_mm_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MmId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      RssStatThrottledFtraceEvent>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void set_size(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/systrace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYSTRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_SYSTRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ZeroFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ZeroFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ZeroFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ZeroFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_flag() const { return at<1>().valid(); }
+  int32_t flag() const { return at<1>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_pid() const { return at<3>().valid(); }
+  int32_t pid() const { return at<3>().as_int32(); }
+  bool has_value() const { return at<4>().valid(); }
+  int64_t value() const { return at<4>().as_int64(); }
+};
+
+class ZeroFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ZeroFtraceEvent_Decoder;
+  enum : int32_t {
+    kFlagFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kPidFieldNumber = 3,
+    kValueFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ZeroFtraceEvent"; }
+
+
+  using FieldMetadata_Flag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ZeroFtraceEvent>;
+
+  static constexpr FieldMetadata_Flag kFlag{};
+  void set_flag(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ZeroFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ZeroFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ZeroFtraceEvent>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/task.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TASK_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TASK_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class TaskRenameFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TaskRenameFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TaskRenameFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TaskRenameFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_oldcomm() const { return at<2>().valid(); }
+  ::protozero::ConstChars oldcomm() const { return at<2>().as_string(); }
+  bool has_newcomm() const { return at<3>().valid(); }
+  ::protozero::ConstChars newcomm() const { return at<3>().as_string(); }
+  bool has_oom_score_adj() const { return at<4>().valid(); }
+  int32_t oom_score_adj() const { return at<4>().as_int32(); }
+};
+
+class TaskRenameFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TaskRenameFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kOldcommFieldNumber = 2,
+    kNewcommFieldNumber = 3,
+    kOomScoreAdjFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TaskRenameFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TaskRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Oldcomm =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TaskRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Oldcomm kOldcomm{};
+  void set_oldcomm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Oldcomm::kFieldId, data, size);
+  }
+  void set_oldcomm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Oldcomm::kFieldId, chars.data, chars.size);
+  }
+  void set_oldcomm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Oldcomm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Newcomm =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TaskRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_Newcomm kNewcomm{};
+  void set_newcomm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Newcomm::kFieldId, data, size);
+  }
+  void set_newcomm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Newcomm::kFieldId, chars.data, chars.size);
+  }
+  void set_newcomm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Newcomm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OomScoreAdj =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TaskRenameFtraceEvent>;
+
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj{};
+  void set_oom_score_adj(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OomScoreAdj::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TaskNewtaskFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TaskNewtaskFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TaskNewtaskFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TaskNewtaskFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_comm() const { return at<2>().valid(); }
+  ::protozero::ConstChars comm() const { return at<2>().as_string(); }
+  bool has_clone_flags() const { return at<3>().valid(); }
+  uint64_t clone_flags() const { return at<3>().as_uint64(); }
+  bool has_oom_score_adj() const { return at<4>().valid(); }
+  int32_t oom_score_adj() const { return at<4>().as_int32(); }
+};
+
+class TaskNewtaskFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TaskNewtaskFtraceEvent_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kCommFieldNumber = 2,
+    kCloneFlagsFieldNumber = 3,
+    kOomScoreAdjFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TaskNewtaskFtraceEvent"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TaskNewtaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Comm =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TaskNewtaskFtraceEvent>;
+
+  static constexpr FieldMetadata_Comm kComm{};
+  void set_comm(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, data, size);
+  }
+  void set_comm(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Comm::kFieldId, chars.data, chars.size);
+  }
+  void set_comm(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Comm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CloneFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TaskNewtaskFtraceEvent>;
+
+  static constexpr FieldMetadata_CloneFlags kCloneFlags{};
+  void set_clone_flags(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CloneFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OomScoreAdj =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TaskNewtaskFtraceEvent>;
+
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj{};
+  void set_oom_score_adj(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OomScoreAdj::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/tcp.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TCP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TCP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class TcpRetransmitSkbFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TcpRetransmitSkbFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TcpRetransmitSkbFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TcpRetransmitSkbFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_daddr() const { return at<1>().valid(); }
+  uint32_t daddr() const { return at<1>().as_uint32(); }
+  bool has_dport() const { return at<2>().valid(); }
+  uint32_t dport() const { return at<2>().as_uint32(); }
+  bool has_saddr() const { return at<3>().valid(); }
+  uint32_t saddr() const { return at<3>().as_uint32(); }
+  bool has_skaddr() const { return at<4>().valid(); }
+  uint64_t skaddr() const { return at<4>().as_uint64(); }
+  bool has_skbaddr() const { return at<5>().valid(); }
+  uint64_t skbaddr() const { return at<5>().as_uint64(); }
+  bool has_sport() const { return at<6>().valid(); }
+  uint32_t sport() const { return at<6>().as_uint32(); }
+  bool has_state() const { return at<7>().valid(); }
+  int32_t state() const { return at<7>().as_int32(); }
+};
+
+class TcpRetransmitSkbFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TcpRetransmitSkbFtraceEvent_Decoder;
+  enum : int32_t {
+    kDaddrFieldNumber = 1,
+    kDportFieldNumber = 2,
+    kSaddrFieldNumber = 3,
+    kSkaddrFieldNumber = 4,
+    kSkbaddrFieldNumber = 5,
+    kSportFieldNumber = 6,
+    kStateFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TcpRetransmitSkbFtraceEvent"; }
+
+
+  using FieldMetadata_Daddr =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Daddr kDaddr{};
+  void set_daddr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Daddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dport =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Dport kDport{};
+  void set_dport(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dport::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Saddr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Saddr kSaddr{};
+  void set_saddr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Saddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Skaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Skaddr kSkaddr{};
+  void set_skaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skaddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Skbaddr =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Skbaddr kSkbaddr{};
+  void set_skbaddr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Skbaddr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sport =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_Sport kSport{};
+  void set_sport(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sport::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TcpRetransmitSkbFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/thermal.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_THERMAL_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_THERMAL_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class CdevUpdateFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CdevUpdateFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CdevUpdateFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CdevUpdateFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_target() const { return at<1>().valid(); }
+  uint64_t target() const { return at<1>().as_uint64(); }
+  bool has_type() const { return at<2>().valid(); }
+  ::protozero::ConstChars type() const { return at<2>().as_string(); }
+};
+
+class CdevUpdateFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = CdevUpdateFtraceEvent_Decoder;
+  enum : int32_t {
+    kTargetFieldNumber = 1,
+    kTypeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CdevUpdateFtraceEvent"; }
+
+
+  using FieldMetadata_Target =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      CdevUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Target kTarget{};
+  void set_target(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Target::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CdevUpdateFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Type::kFieldId, data, size);
+  }
+  void set_type(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Type::kFieldId, chars.data, chars.size);
+  }
+  void set_type(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ThermalTemperatureFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ThermalTemperatureFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ThermalTemperatureFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ThermalTemperatureFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  int32_t id() const { return at<1>().as_int32(); }
+  bool has_temp() const { return at<2>().valid(); }
+  int32_t temp() const { return at<2>().as_int32(); }
+  bool has_temp_prev() const { return at<3>().valid(); }
+  int32_t temp_prev() const { return at<3>().as_int32(); }
+  bool has_thermal_zone() const { return at<4>().valid(); }
+  ::protozero::ConstChars thermal_zone() const { return at<4>().as_string(); }
+};
+
+class ThermalTemperatureFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = ThermalTemperatureFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kTempFieldNumber = 2,
+    kTempPrevFieldNumber = 3,
+    kThermalZoneFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ThermalTemperatureFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThermalTemperatureFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Temp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThermalTemperatureFtraceEvent>;
+
+  static constexpr FieldMetadata_Temp kTemp{};
+  void set_temp(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Temp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TempPrev =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThermalTemperatureFtraceEvent>;
+
+  static constexpr FieldMetadata_TempPrev kTempPrev{};
+  void set_temp_prev(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TempPrev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThermalZone =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ThermalTemperatureFtraceEvent>;
+
+  static constexpr FieldMetadata_ThermalZone kThermalZone{};
+  void set_thermal_zone(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ThermalZone::kFieldId, data, size);
+  }
+  void set_thermal_zone(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ThermalZone::kFieldId, chars.data, chars.size);
+  }
+  void set_thermal_zone(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThermalZone::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/trusty.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TRUSTY_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_TRUSTY_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class TrustyEnqueueNopFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyEnqueueNopFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyEnqueueNopFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyEnqueueNopFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_arg1() const { return at<1>().valid(); }
+  uint32_t arg1() const { return at<1>().as_uint32(); }
+  bool has_arg2() const { return at<2>().valid(); }
+  uint32_t arg2() const { return at<2>().as_uint32(); }
+  bool has_arg3() const { return at<3>().valid(); }
+  uint32_t arg3() const { return at<3>().as_uint32(); }
+};
+
+class TrustyEnqueueNopFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyEnqueueNopFtraceEvent_Decoder;
+  enum : int32_t {
+    kArg1FieldNumber = 1,
+    kArg2FieldNumber = 2,
+    kArg3FieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyEnqueueNopFtraceEvent"; }
+
+
+  using FieldMetadata_Arg1 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyEnqueueNopFtraceEvent>;
+
+  static constexpr FieldMetadata_Arg1 kArg1{};
+  void set_arg1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Arg1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Arg2 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyEnqueueNopFtraceEvent>;
+
+  static constexpr FieldMetadata_Arg2 kArg2{};
+  void set_arg2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Arg2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Arg3 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyEnqueueNopFtraceEvent>;
+
+  static constexpr FieldMetadata_Arg3 kArg3{};
+  void set_arg3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Arg3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyIpcRxFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcRxFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcRxFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcRxFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buf_id() const { return at<1>().valid(); }
+  uint64_t buf_id() const { return at<1>().as_uint64(); }
+  bool has_chan() const { return at<2>().valid(); }
+  uint32_t chan() const { return at<2>().as_uint32(); }
+  bool has_srv_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<3>().as_string(); }
+};
+
+class TrustyIpcRxFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcRxFtraceEvent_Decoder;
+  enum : int32_t {
+    kBufIdFieldNumber = 1,
+    kChanFieldNumber = 2,
+    kSrvNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcRxFtraceEvent"; }
+
+
+  using FieldMetadata_BufId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyIpcRxFtraceEvent>;
+
+  static constexpr FieldMetadata_BufId kBufId{};
+  void set_buf_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcRxFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcRxFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyIpcReadEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcReadEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcReadEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcReadEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buf_id() const { return at<1>().valid(); }
+  uint64_t buf_id() const { return at<1>().as_uint64(); }
+  bool has_chan() const { return at<2>().valid(); }
+  uint32_t chan() const { return at<2>().as_uint32(); }
+  bool has_len_or_err() const { return at<3>().valid(); }
+  int32_t len_or_err() const { return at<3>().as_int32(); }
+  bool has_shm_cnt() const { return at<4>().valid(); }
+  uint64_t shm_cnt() const { return at<4>().as_uint64(); }
+  bool has_srv_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<5>().as_string(); }
+};
+
+class TrustyIpcReadEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcReadEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kBufIdFieldNumber = 1,
+    kChanFieldNumber = 2,
+    kLenOrErrFieldNumber = 3,
+    kShmCntFieldNumber = 4,
+    kSrvNameFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcReadEndFtraceEvent"; }
+
+
+  using FieldMetadata_BufId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyIpcReadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_BufId kBufId{};
+  void set_buf_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcReadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LenOrErr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcReadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_LenOrErr kLenOrErr{};
+  void set_len_or_err(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LenOrErr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ShmCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyIpcReadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_ShmCnt kShmCnt{};
+  void set_shm_cnt(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcReadEndFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyIpcReadFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcReadFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcReadFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcReadFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chan() const { return at<1>().valid(); }
+  uint32_t chan() const { return at<1>().as_uint32(); }
+  bool has_srv_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<2>().as_string(); }
+};
+
+class TrustyIpcReadFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcReadFtraceEvent_Decoder;
+  enum : int32_t {
+    kChanFieldNumber = 1,
+    kSrvNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcReadFtraceEvent"; }
+
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcReadFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcReadFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyIpcPollFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcPollFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcPollFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcPollFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chan() const { return at<1>().valid(); }
+  uint32_t chan() const { return at<1>().as_uint32(); }
+  bool has_poll_mask() const { return at<2>().valid(); }
+  uint32_t poll_mask() const { return at<2>().as_uint32(); }
+  bool has_srv_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<3>().as_string(); }
+};
+
+class TrustyIpcPollFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcPollFtraceEvent_Decoder;
+  enum : int32_t {
+    kChanFieldNumber = 1,
+    kPollMaskFieldNumber = 2,
+    kSrvNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcPollFtraceEvent"; }
+
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcPollFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PollMask =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcPollFtraceEvent>;
+
+  static constexpr FieldMetadata_PollMask kPollMask{};
+  void set_poll_mask(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PollMask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcPollFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyIpcWriteFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcWriteFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcWriteFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcWriteFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buf_id() const { return at<1>().valid(); }
+  uint64_t buf_id() const { return at<1>().as_uint64(); }
+  bool has_chan() const { return at<2>().valid(); }
+  uint32_t chan() const { return at<2>().as_uint32(); }
+  bool has_kind_shm() const { return at<3>().valid(); }
+  int32_t kind_shm() const { return at<3>().as_int32(); }
+  bool has_len_or_err() const { return at<4>().valid(); }
+  int32_t len_or_err() const { return at<4>().as_int32(); }
+  bool has_shm_cnt() const { return at<5>().valid(); }
+  uint64_t shm_cnt() const { return at<5>().as_uint64(); }
+  bool has_srv_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<6>().as_string(); }
+};
+
+class TrustyIpcWriteFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcWriteFtraceEvent_Decoder;
+  enum : int32_t {
+    kBufIdFieldNumber = 1,
+    kChanFieldNumber = 2,
+    kKindShmFieldNumber = 3,
+    kLenOrErrFieldNumber = 4,
+    kShmCntFieldNumber = 5,
+    kSrvNameFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcWriteFtraceEvent"; }
+
+
+  using FieldMetadata_BufId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_BufId kBufId{};
+  void set_buf_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KindShm =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_KindShm kKindShm{};
+  void set_kind_shm(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KindShm::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LenOrErr =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_LenOrErr kLenOrErr{};
+  void set_len_or_err(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LenOrErr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ShmCnt =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_ShmCnt kShmCnt{};
+  void set_shm_cnt(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ShmCnt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcWriteFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyIpcConnectEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcConnectEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcConnectEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcConnectEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chan() const { return at<1>().valid(); }
+  uint32_t chan() const { return at<1>().as_uint32(); }
+  bool has_err() const { return at<2>().valid(); }
+  int32_t err() const { return at<2>().as_int32(); }
+  bool has_state() const { return at<3>().valid(); }
+  int32_t state() const { return at<3>().as_int32(); }
+};
+
+class TrustyIpcConnectEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcConnectEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kChanFieldNumber = 1,
+    kErrFieldNumber = 2,
+    kStateFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcConnectEndFtraceEvent"; }
+
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcConnectEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Err =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcConnectEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Err kErr{};
+  void set_err(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Err::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcConnectEndFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyIpcConnectFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcConnectFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcConnectFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcConnectFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chan() const { return at<1>().valid(); }
+  uint32_t chan() const { return at<1>().as_uint32(); }
+  bool has_port() const { return at<2>().valid(); }
+  ::protozero::ConstChars port() const { return at<2>().as_string(); }
+  bool has_state() const { return at<3>().valid(); }
+  int32_t state() const { return at<3>().as_int32(); }
+};
+
+class TrustyIpcConnectFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcConnectFtraceEvent_Decoder;
+  enum : int32_t {
+    kChanFieldNumber = 1,
+    kPortFieldNumber = 2,
+    kStateFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcConnectFtraceEvent"; }
+
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcConnectFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Port =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcConnectFtraceEvent>;
+
+  static constexpr FieldMetadata_Port kPort{};
+  void set_port(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Port::kFieldId, data, size);
+  }
+  void set_port(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Port::kFieldId, chars.data, chars.size);
+  }
+  void set_port(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Port::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIpcConnectFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyIpcHandleEventFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIpcHandleEventFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIpcHandleEventFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIpcHandleEventFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chan() const { return at<1>().valid(); }
+  uint32_t chan() const { return at<1>().as_uint32(); }
+  bool has_event_id() const { return at<2>().valid(); }
+  uint32_t event_id() const { return at<2>().as_uint32(); }
+  bool has_srv_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars srv_name() const { return at<3>().as_string(); }
+};
+
+class TrustyIpcHandleEventFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIpcHandleEventFtraceEvent_Decoder;
+  enum : int32_t {
+    kChanFieldNumber = 1,
+    kEventIdFieldNumber = 2,
+    kSrvNameFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIpcHandleEventFtraceEvent"; }
+
+
+  using FieldMetadata_Chan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcHandleEventFtraceEvent>;
+
+  static constexpr FieldMetadata_Chan kChan{};
+  void set_chan(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Chan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyIpcHandleEventFtraceEvent>;
+
+  static constexpr FieldMetadata_EventId kEventId{};
+  void set_event_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SrvName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TrustyIpcHandleEventFtraceEvent>;
+
+  static constexpr FieldMetadata_SrvName kSrvName{};
+  void set_srv_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, data, size);
+  }
+  void set_srv_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SrvName::kFieldId, chars.data, chars.size);
+  }
+  void set_srv_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SrvName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyIrqFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyIrqFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyIrqFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyIrqFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  int32_t irq() const { return at<1>().as_int32(); }
+};
+
+class TrustyIrqFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyIrqFtraceEvent_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyIrqFtraceEvent"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyIrqFtraceEvent>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyReclaimMemoryDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyReclaimMemoryDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyReclaimMemoryDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyReclaimMemoryDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_ret() const { return at<2>().valid(); }
+  int32_t ret() const { return at<2>().as_int32(); }
+};
+
+class TrustyReclaimMemoryDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyReclaimMemoryDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kRetFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyReclaimMemoryDoneFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyReclaimMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyReclaimMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyReclaimMemoryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyReclaimMemoryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyReclaimMemoryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyReclaimMemoryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+};
+
+class TrustyReclaimMemoryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyReclaimMemoryFtraceEvent_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyReclaimMemoryFtraceEvent"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyReclaimMemoryFtraceEvent>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyShareMemoryDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyShareMemoryDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyShareMemoryDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyShareMemoryDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_handle() const { return at<1>().valid(); }
+  uint64_t handle() const { return at<1>().as_uint64(); }
+  bool has_len() const { return at<2>().valid(); }
+  uint64_t len() const { return at<2>().as_uint64(); }
+  bool has_lend() const { return at<3>().valid(); }
+  uint32_t lend() const { return at<3>().as_uint32(); }
+  bool has_nents() const { return at<4>().valid(); }
+  uint32_t nents() const { return at<4>().as_uint32(); }
+  bool has_ret() const { return at<5>().valid(); }
+  int32_t ret() const { return at<5>().as_int32(); }
+};
+
+class TrustyShareMemoryDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyShareMemoryDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kHandleFieldNumber = 1,
+    kLenFieldNumber = 2,
+    kLendFieldNumber = 3,
+    kNentsFieldNumber = 4,
+    kRetFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyShareMemoryDoneFtraceEvent"; }
+
+
+  using FieldMetadata_Handle =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyShareMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Handle kHandle{};
+  void set_handle(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Handle::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyShareMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lend =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyShareMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Lend kLend{};
+  void set_lend(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lend::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nents =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyShareMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Nents kNents{};
+  void set_nents(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TrustyShareMemoryDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyShareMemoryFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyShareMemoryFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyShareMemoryFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyShareMemoryFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_len() const { return at<1>().valid(); }
+  uint64_t len() const { return at<1>().as_uint64(); }
+  bool has_lend() const { return at<2>().valid(); }
+  uint32_t lend() const { return at<2>().as_uint32(); }
+  bool has_nents() const { return at<3>().valid(); }
+  uint32_t nents() const { return at<3>().as_uint32(); }
+};
+
+class TrustyShareMemoryFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyShareMemoryFtraceEvent_Decoder;
+  enum : int32_t {
+    kLenFieldNumber = 1,
+    kLendFieldNumber = 2,
+    kNentsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyShareMemoryFtraceEvent"; }
+
+
+  using FieldMetadata_Len =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyShareMemoryFtraceEvent>;
+
+  static constexpr FieldMetadata_Len kLen{};
+  void set_len(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Len::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lend =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyShareMemoryFtraceEvent>;
+
+  static constexpr FieldMetadata_Lend kLend{};
+  void set_lend(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lend::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nents =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TrustyShareMemoryFtraceEvent>;
+
+  static constexpr FieldMetadata_Nents kNents{};
+  void set_nents(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nents::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyStdCall32DoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyStdCall32DoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyStdCall32DoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyStdCall32DoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ret() const { return at<1>().valid(); }
+  int64_t ret() const { return at<1>().as_int64(); }
+};
+
+class TrustyStdCall32DoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyStdCall32DoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kRetFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyStdCall32DoneFtraceEvent"; }
+
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrustyStdCall32DoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustyStdCall32FtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustyStdCall32FtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustyStdCall32FtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustyStdCall32FtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_r0() const { return at<1>().valid(); }
+  uint64_t r0() const { return at<1>().as_uint64(); }
+  bool has_r1() const { return at<2>().valid(); }
+  uint64_t r1() const { return at<2>().as_uint64(); }
+  bool has_r2() const { return at<3>().valid(); }
+  uint64_t r2() const { return at<3>().as_uint64(); }
+  bool has_r3() const { return at<4>().valid(); }
+  uint64_t r3() const { return at<4>().as_uint64(); }
+};
+
+class TrustyStdCall32FtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustyStdCall32FtraceEvent_Decoder;
+  enum : int32_t {
+    kR0FieldNumber = 1,
+    kR1FieldNumber = 2,
+    kR2FieldNumber = 3,
+    kR3FieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustyStdCall32FtraceEvent"; }
+
+
+  using FieldMetadata_R0 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyStdCall32FtraceEvent>;
+
+  static constexpr FieldMetadata_R0 kR0{};
+  void set_r0(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_R1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyStdCall32FtraceEvent>;
+
+  static constexpr FieldMetadata_R1 kR1{};
+  void set_r1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_R2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyStdCall32FtraceEvent>;
+
+  static constexpr FieldMetadata_R2 kR2{};
+  void set_r2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_R3 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustyStdCall32FtraceEvent>;
+
+  static constexpr FieldMetadata_R3 kR3{};
+  void set_r3(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustySmcDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustySmcDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustySmcDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustySmcDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ret() const { return at<1>().valid(); }
+  uint64_t ret() const { return at<1>().as_uint64(); }
+};
+
+class TrustySmcDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustySmcDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kRetFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustySmcDoneFtraceEvent"; }
+
+
+  using FieldMetadata_Ret =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustySmcDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Ret kRet{};
+  void set_ret(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ret::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TrustySmcFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrustySmcFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrustySmcFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrustySmcFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_r0() const { return at<1>().valid(); }
+  uint64_t r0() const { return at<1>().as_uint64(); }
+  bool has_r1() const { return at<2>().valid(); }
+  uint64_t r1() const { return at<2>().as_uint64(); }
+  bool has_r2() const { return at<3>().valid(); }
+  uint64_t r2() const { return at<3>().as_uint64(); }
+  bool has_r3() const { return at<4>().valid(); }
+  uint64_t r3() const { return at<4>().as_uint64(); }
+};
+
+class TrustySmcFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TrustySmcFtraceEvent_Decoder;
+  enum : int32_t {
+    kR0FieldNumber = 1,
+    kR1FieldNumber = 2,
+    kR2FieldNumber = 3,
+    kR3FieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrustySmcFtraceEvent"; }
+
+
+  using FieldMetadata_R0 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustySmcFtraceEvent>;
+
+  static constexpr FieldMetadata_R0 kR0{};
+  void set_r0(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_R1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustySmcFtraceEvent>;
+
+  static constexpr FieldMetadata_R1 kR1{};
+  void set_r1(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_R2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustySmcFtraceEvent>;
+
+  static constexpr FieldMetadata_R2 kR2{};
+  void set_r2(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_R3 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TrustySmcFtraceEvent>;
+
+  static constexpr FieldMetadata_R3 kR3{};
+  void set_r3(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_R3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/ufs.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_UFS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_UFS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class UfshcdClkGatingFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UfshcdClkGatingFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UfshcdClkGatingFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UfshcdClkGatingFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars dev_name() const { return at<1>().as_string(); }
+  bool has_state() const { return at<2>().valid(); }
+  int32_t state() const { return at<2>().as_int32(); }
+};
+
+class UfshcdClkGatingFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = UfshcdClkGatingFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevNameFieldNumber = 1,
+    kStateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UfshcdClkGatingFtraceEvent"; }
+
+
+  using FieldMetadata_DevName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UfshcdClkGatingFtraceEvent>;
+
+  static constexpr FieldMetadata_DevName kDevName{};
+  void set_dev_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DevName::kFieldId, data, size);
+  }
+  void set_dev_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DevName::kFieldId, chars.data, chars.size);
+  }
+  void set_dev_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      UfshcdClkGatingFtraceEvent>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class UfshcdCommandFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/10, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UfshcdCommandFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UfshcdCommandFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UfshcdCommandFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dev_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars dev_name() const { return at<1>().as_string(); }
+  bool has_doorbell() const { return at<2>().valid(); }
+  uint32_t doorbell() const { return at<2>().as_uint32(); }
+  bool has_intr() const { return at<3>().valid(); }
+  uint32_t intr() const { return at<3>().as_uint32(); }
+  bool has_lba() const { return at<4>().valid(); }
+  uint64_t lba() const { return at<4>().as_uint64(); }
+  bool has_opcode() const { return at<5>().valid(); }
+  uint32_t opcode() const { return at<5>().as_uint32(); }
+  bool has_str() const { return at<6>().valid(); }
+  ::protozero::ConstChars str() const { return at<6>().as_string(); }
+  bool has_tag() const { return at<7>().valid(); }
+  uint32_t tag() const { return at<7>().as_uint32(); }
+  bool has_transfer_len() const { return at<8>().valid(); }
+  int32_t transfer_len() const { return at<8>().as_int32(); }
+  bool has_group_id() const { return at<9>().valid(); }
+  uint32_t group_id() const { return at<9>().as_uint32(); }
+  bool has_str_t() const { return at<10>().valid(); }
+  uint32_t str_t() const { return at<10>().as_uint32(); }
+};
+
+class UfshcdCommandFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = UfshcdCommandFtraceEvent_Decoder;
+  enum : int32_t {
+    kDevNameFieldNumber = 1,
+    kDoorbellFieldNumber = 2,
+    kIntrFieldNumber = 3,
+    kLbaFieldNumber = 4,
+    kOpcodeFieldNumber = 5,
+    kStrFieldNumber = 6,
+    kTagFieldNumber = 7,
+    kTransferLenFieldNumber = 8,
+    kGroupIdFieldNumber = 9,
+    kStrTFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UfshcdCommandFtraceEvent"; }
+
+
+  using FieldMetadata_DevName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_DevName kDevName{};
+  void set_dev_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DevName::kFieldId, data, size);
+  }
+  void set_dev_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DevName::kFieldId, chars.data, chars.size);
+  }
+  void set_dev_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DevName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Doorbell =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Doorbell kDoorbell{};
+  void set_doorbell(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Doorbell::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Intr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Intr kIntr{};
+  void set_intr(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Intr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lba =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Lba kLba{};
+  void set_lba(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Lba::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Opcode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Opcode kOpcode{};
+  void set_opcode(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Opcode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Str =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Str kStr{};
+  void set_str(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, size);
+  }
+  void set_str(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Str::kFieldId, chars.data, chars.size);
+  }
+  void set_str(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Str::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TransferLen =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_TransferLen kTransferLen{};
+  void set_transfer_len(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TransferLen::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GroupId =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_GroupId kGroupId{};
+  void set_group_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GroupId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StrT =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UfshcdCommandFtraceEvent>;
+
+  static constexpr FieldMetadata_StrT kStrT{};
+  void set_str_t(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StrT::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/v4l2.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_V4L2_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_V4L2_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class Vb2V4l2DqbufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Vb2V4l2DqbufFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Vb2V4l2DqbufFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Vb2V4l2DqbufFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_field() const { return at<1>().valid(); }
+  uint32_t field() const { return at<1>().as_uint32(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_minor() const { return at<3>().valid(); }
+  int32_t minor() const { return at<3>().as_int32(); }
+  bool has_sequence() const { return at<4>().valid(); }
+  uint32_t sequence() const { return at<4>().as_uint32(); }
+  bool has_timecode_flags() const { return at<5>().valid(); }
+  uint32_t timecode_flags() const { return at<5>().as_uint32(); }
+  bool has_timecode_frames() const { return at<6>().valid(); }
+  uint32_t timecode_frames() const { return at<6>().as_uint32(); }
+  bool has_timecode_hours() const { return at<7>().valid(); }
+  uint32_t timecode_hours() const { return at<7>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<8>().valid(); }
+  uint32_t timecode_minutes() const { return at<8>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<9>().valid(); }
+  uint32_t timecode_seconds() const { return at<9>().as_uint32(); }
+  bool has_timecode_type() const { return at<10>().valid(); }
+  uint32_t timecode_type() const { return at<10>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<11>().valid(); }
+  uint32_t timecode_userbits0() const { return at<11>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<12>().valid(); }
+  uint32_t timecode_userbits1() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<13>().valid(); }
+  uint32_t timecode_userbits2() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<14>().valid(); }
+  uint32_t timecode_userbits3() const { return at<14>().as_uint32(); }
+  bool has_timestamp() const { return at<15>().valid(); }
+  int64_t timestamp() const { return at<15>().as_int64(); }
+};
+
+class Vb2V4l2DqbufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Vb2V4l2DqbufFtraceEvent_Decoder;
+  enum : int32_t {
+    kFieldFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kMinorFieldNumber = 3,
+    kSequenceFieldNumber = 4,
+    kTimecodeFlagsFieldNumber = 5,
+    kTimecodeFramesFieldNumber = 6,
+    kTimecodeHoursFieldNumber = 7,
+    kTimecodeMinutesFieldNumber = 8,
+    kTimecodeSecondsFieldNumber = 9,
+    kTimecodeTypeFieldNumber = 10,
+    kTimecodeUserbits0FieldNumber = 11,
+    kTimecodeUserbits1FieldNumber = 12,
+    kTimecodeUserbits2FieldNumber = 13,
+    kTimecodeUserbits3FieldNumber = 14,
+    kTimestampFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Vb2V4l2DqbufFtraceEvent"; }
+
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Vb2V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Vb2V4l2QbufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Vb2V4l2QbufFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Vb2V4l2QbufFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Vb2V4l2QbufFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_field() const { return at<1>().valid(); }
+  uint32_t field() const { return at<1>().as_uint32(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_minor() const { return at<3>().valid(); }
+  int32_t minor() const { return at<3>().as_int32(); }
+  bool has_sequence() const { return at<4>().valid(); }
+  uint32_t sequence() const { return at<4>().as_uint32(); }
+  bool has_timecode_flags() const { return at<5>().valid(); }
+  uint32_t timecode_flags() const { return at<5>().as_uint32(); }
+  bool has_timecode_frames() const { return at<6>().valid(); }
+  uint32_t timecode_frames() const { return at<6>().as_uint32(); }
+  bool has_timecode_hours() const { return at<7>().valid(); }
+  uint32_t timecode_hours() const { return at<7>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<8>().valid(); }
+  uint32_t timecode_minutes() const { return at<8>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<9>().valid(); }
+  uint32_t timecode_seconds() const { return at<9>().as_uint32(); }
+  bool has_timecode_type() const { return at<10>().valid(); }
+  uint32_t timecode_type() const { return at<10>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<11>().valid(); }
+  uint32_t timecode_userbits0() const { return at<11>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<12>().valid(); }
+  uint32_t timecode_userbits1() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<13>().valid(); }
+  uint32_t timecode_userbits2() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<14>().valid(); }
+  uint32_t timecode_userbits3() const { return at<14>().as_uint32(); }
+  bool has_timestamp() const { return at<15>().valid(); }
+  int64_t timestamp() const { return at<15>().as_int64(); }
+};
+
+class Vb2V4l2QbufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Vb2V4l2QbufFtraceEvent_Decoder;
+  enum : int32_t {
+    kFieldFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kMinorFieldNumber = 3,
+    kSequenceFieldNumber = 4,
+    kTimecodeFlagsFieldNumber = 5,
+    kTimecodeFramesFieldNumber = 6,
+    kTimecodeHoursFieldNumber = 7,
+    kTimecodeMinutesFieldNumber = 8,
+    kTimecodeSecondsFieldNumber = 9,
+    kTimecodeTypeFieldNumber = 10,
+    kTimecodeUserbits0FieldNumber = 11,
+    kTimecodeUserbits1FieldNumber = 12,
+    kTimecodeUserbits2FieldNumber = 13,
+    kTimecodeUserbits3FieldNumber = 14,
+    kTimestampFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Vb2V4l2QbufFtraceEvent"; }
+
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Vb2V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Vb2V4l2BufDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Vb2V4l2BufDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Vb2V4l2BufDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Vb2V4l2BufDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_field() const { return at<1>().valid(); }
+  uint32_t field() const { return at<1>().as_uint32(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_minor() const { return at<3>().valid(); }
+  int32_t minor() const { return at<3>().as_int32(); }
+  bool has_sequence() const { return at<4>().valid(); }
+  uint32_t sequence() const { return at<4>().as_uint32(); }
+  bool has_timecode_flags() const { return at<5>().valid(); }
+  uint32_t timecode_flags() const { return at<5>().as_uint32(); }
+  bool has_timecode_frames() const { return at<6>().valid(); }
+  uint32_t timecode_frames() const { return at<6>().as_uint32(); }
+  bool has_timecode_hours() const { return at<7>().valid(); }
+  uint32_t timecode_hours() const { return at<7>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<8>().valid(); }
+  uint32_t timecode_minutes() const { return at<8>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<9>().valid(); }
+  uint32_t timecode_seconds() const { return at<9>().as_uint32(); }
+  bool has_timecode_type() const { return at<10>().valid(); }
+  uint32_t timecode_type() const { return at<10>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<11>().valid(); }
+  uint32_t timecode_userbits0() const { return at<11>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<12>().valid(); }
+  uint32_t timecode_userbits1() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<13>().valid(); }
+  uint32_t timecode_userbits2() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<14>().valid(); }
+  uint32_t timecode_userbits3() const { return at<14>().as_uint32(); }
+  bool has_timestamp() const { return at<15>().valid(); }
+  int64_t timestamp() const { return at<15>().as_int64(); }
+};
+
+class Vb2V4l2BufDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Vb2V4l2BufDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kFieldFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kMinorFieldNumber = 3,
+    kSequenceFieldNumber = 4,
+    kTimecodeFlagsFieldNumber = 5,
+    kTimecodeFramesFieldNumber = 6,
+    kTimecodeHoursFieldNumber = 7,
+    kTimecodeMinutesFieldNumber = 8,
+    kTimecodeSecondsFieldNumber = 9,
+    kTimecodeTypeFieldNumber = 10,
+    kTimecodeUserbits0FieldNumber = 11,
+    kTimecodeUserbits1FieldNumber = 12,
+    kTimecodeUserbits2FieldNumber = 13,
+    kTimecodeUserbits3FieldNumber = 14,
+    kTimestampFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Vb2V4l2BufDoneFtraceEvent"; }
+
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Vb2V4l2BufDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Vb2V4l2BufQueueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Vb2V4l2BufQueueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Vb2V4l2BufQueueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Vb2V4l2BufQueueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_field() const { return at<1>().valid(); }
+  uint32_t field() const { return at<1>().as_uint32(); }
+  bool has_flags() const { return at<2>().valid(); }
+  uint32_t flags() const { return at<2>().as_uint32(); }
+  bool has_minor() const { return at<3>().valid(); }
+  int32_t minor() const { return at<3>().as_int32(); }
+  bool has_sequence() const { return at<4>().valid(); }
+  uint32_t sequence() const { return at<4>().as_uint32(); }
+  bool has_timecode_flags() const { return at<5>().valid(); }
+  uint32_t timecode_flags() const { return at<5>().as_uint32(); }
+  bool has_timecode_frames() const { return at<6>().valid(); }
+  uint32_t timecode_frames() const { return at<6>().as_uint32(); }
+  bool has_timecode_hours() const { return at<7>().valid(); }
+  uint32_t timecode_hours() const { return at<7>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<8>().valid(); }
+  uint32_t timecode_minutes() const { return at<8>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<9>().valid(); }
+  uint32_t timecode_seconds() const { return at<9>().as_uint32(); }
+  bool has_timecode_type() const { return at<10>().valid(); }
+  uint32_t timecode_type() const { return at<10>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<11>().valid(); }
+  uint32_t timecode_userbits0() const { return at<11>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<12>().valid(); }
+  uint32_t timecode_userbits1() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<13>().valid(); }
+  uint32_t timecode_userbits2() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<14>().valid(); }
+  uint32_t timecode_userbits3() const { return at<14>().as_uint32(); }
+  bool has_timestamp() const { return at<15>().valid(); }
+  int64_t timestamp() const { return at<15>().as_int64(); }
+};
+
+class Vb2V4l2BufQueueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = Vb2V4l2BufQueueFtraceEvent_Decoder;
+  enum : int32_t {
+    kFieldFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+    kMinorFieldNumber = 3,
+    kSequenceFieldNumber = 4,
+    kTimecodeFlagsFieldNumber = 5,
+    kTimecodeFramesFieldNumber = 6,
+    kTimecodeHoursFieldNumber = 7,
+    kTimecodeMinutesFieldNumber = 8,
+    kTimecodeSecondsFieldNumber = 9,
+    kTimecodeTypeFieldNumber = 10,
+    kTimecodeUserbits0FieldNumber = 11,
+    kTimecodeUserbits1FieldNumber = 12,
+    kTimecodeUserbits2FieldNumber = 13,
+    kTimecodeUserbits3FieldNumber = 14,
+    kTimestampFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Vb2V4l2BufQueueFtraceEvent"; }
+
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      Vb2V4l2BufQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class V4l2DqbufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/18, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V4l2DqbufFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V4l2DqbufFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V4l2DqbufFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytesused() const { return at<1>().valid(); }
+  uint32_t bytesused() const { return at<1>().as_uint32(); }
+  bool has_field() const { return at<2>().valid(); }
+  uint32_t field() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_index() const { return at<4>().valid(); }
+  uint32_t index() const { return at<4>().as_uint32(); }
+  bool has_minor() const { return at<5>().valid(); }
+  int32_t minor() const { return at<5>().as_int32(); }
+  bool has_sequence() const { return at<6>().valid(); }
+  uint32_t sequence() const { return at<6>().as_uint32(); }
+  bool has_timecode_flags() const { return at<7>().valid(); }
+  uint32_t timecode_flags() const { return at<7>().as_uint32(); }
+  bool has_timecode_frames() const { return at<8>().valid(); }
+  uint32_t timecode_frames() const { return at<8>().as_uint32(); }
+  bool has_timecode_hours() const { return at<9>().valid(); }
+  uint32_t timecode_hours() const { return at<9>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<10>().valid(); }
+  uint32_t timecode_minutes() const { return at<10>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<11>().valid(); }
+  uint32_t timecode_seconds() const { return at<11>().as_uint32(); }
+  bool has_timecode_type() const { return at<12>().valid(); }
+  uint32_t timecode_type() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<13>().valid(); }
+  uint32_t timecode_userbits0() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<14>().valid(); }
+  uint32_t timecode_userbits1() const { return at<14>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<15>().valid(); }
+  uint32_t timecode_userbits2() const { return at<15>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<16>().valid(); }
+  uint32_t timecode_userbits3() const { return at<16>().as_uint32(); }
+  bool has_timestamp() const { return at<17>().valid(); }
+  int64_t timestamp() const { return at<17>().as_int64(); }
+  bool has_type() const { return at<18>().valid(); }
+  uint32_t type() const { return at<18>().as_uint32(); }
+};
+
+class V4l2DqbufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = V4l2DqbufFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesusedFieldNumber = 1,
+    kFieldFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kIndexFieldNumber = 4,
+    kMinorFieldNumber = 5,
+    kSequenceFieldNumber = 6,
+    kTimecodeFlagsFieldNumber = 7,
+    kTimecodeFramesFieldNumber = 8,
+    kTimecodeHoursFieldNumber = 9,
+    kTimecodeMinutesFieldNumber = 10,
+    kTimecodeSecondsFieldNumber = 11,
+    kTimecodeTypeFieldNumber = 12,
+    kTimecodeUserbits0FieldNumber = 13,
+    kTimecodeUserbits1FieldNumber = 14,
+    kTimecodeUserbits2FieldNumber = 15,
+    kTimecodeUserbits3FieldNumber = 16,
+    kTimestampFieldNumber = 17,
+    kTypeFieldNumber = 18,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V4l2DqbufFtraceEvent"; }
+
+
+  using FieldMetadata_Bytesused =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytesused kBytesused{};
+  void set_bytesused(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytesused::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2DqbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class V4l2QbufFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/18, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  V4l2QbufFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit V4l2QbufFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit V4l2QbufFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_bytesused() const { return at<1>().valid(); }
+  uint32_t bytesused() const { return at<1>().as_uint32(); }
+  bool has_field() const { return at<2>().valid(); }
+  uint32_t field() const { return at<2>().as_uint32(); }
+  bool has_flags() const { return at<3>().valid(); }
+  uint32_t flags() const { return at<3>().as_uint32(); }
+  bool has_index() const { return at<4>().valid(); }
+  uint32_t index() const { return at<4>().as_uint32(); }
+  bool has_minor() const { return at<5>().valid(); }
+  int32_t minor() const { return at<5>().as_int32(); }
+  bool has_sequence() const { return at<6>().valid(); }
+  uint32_t sequence() const { return at<6>().as_uint32(); }
+  bool has_timecode_flags() const { return at<7>().valid(); }
+  uint32_t timecode_flags() const { return at<7>().as_uint32(); }
+  bool has_timecode_frames() const { return at<8>().valid(); }
+  uint32_t timecode_frames() const { return at<8>().as_uint32(); }
+  bool has_timecode_hours() const { return at<9>().valid(); }
+  uint32_t timecode_hours() const { return at<9>().as_uint32(); }
+  bool has_timecode_minutes() const { return at<10>().valid(); }
+  uint32_t timecode_minutes() const { return at<10>().as_uint32(); }
+  bool has_timecode_seconds() const { return at<11>().valid(); }
+  uint32_t timecode_seconds() const { return at<11>().as_uint32(); }
+  bool has_timecode_type() const { return at<12>().valid(); }
+  uint32_t timecode_type() const { return at<12>().as_uint32(); }
+  bool has_timecode_userbits0() const { return at<13>().valid(); }
+  uint32_t timecode_userbits0() const { return at<13>().as_uint32(); }
+  bool has_timecode_userbits1() const { return at<14>().valid(); }
+  uint32_t timecode_userbits1() const { return at<14>().as_uint32(); }
+  bool has_timecode_userbits2() const { return at<15>().valid(); }
+  uint32_t timecode_userbits2() const { return at<15>().as_uint32(); }
+  bool has_timecode_userbits3() const { return at<16>().valid(); }
+  uint32_t timecode_userbits3() const { return at<16>().as_uint32(); }
+  bool has_timestamp() const { return at<17>().valid(); }
+  int64_t timestamp() const { return at<17>().as_int64(); }
+  bool has_type() const { return at<18>().valid(); }
+  uint32_t type() const { return at<18>().as_uint32(); }
+};
+
+class V4l2QbufFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = V4l2QbufFtraceEvent_Decoder;
+  enum : int32_t {
+    kBytesusedFieldNumber = 1,
+    kFieldFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+    kIndexFieldNumber = 4,
+    kMinorFieldNumber = 5,
+    kSequenceFieldNumber = 6,
+    kTimecodeFlagsFieldNumber = 7,
+    kTimecodeFramesFieldNumber = 8,
+    kTimecodeHoursFieldNumber = 9,
+    kTimecodeMinutesFieldNumber = 10,
+    kTimecodeSecondsFieldNumber = 11,
+    kTimecodeTypeFieldNumber = 12,
+    kTimecodeUserbits0FieldNumber = 13,
+    kTimecodeUserbits1FieldNumber = 14,
+    kTimecodeUserbits2FieldNumber = 15,
+    kTimecodeUserbits3FieldNumber = 16,
+    kTimestampFieldNumber = 17,
+    kTypeFieldNumber = 18,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.V4l2QbufFtraceEvent"; }
+
+
+  using FieldMetadata_Bytesused =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Bytesused kBytesused{};
+  void set_bytesused(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Bytesused::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Field =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Field kField{};
+  void set_field(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Field::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Minor =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Minor kMinor{};
+  void set_minor(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Minor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sequence =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Sequence kSequence{};
+  void set_sequence(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sequence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFlags kTimecodeFlags{};
+  void set_timecode_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeFrames kTimecodeFrames{};
+  void set_timecode_frames(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeHours =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeHours kTimecodeHours{};
+  void set_timecode_hours(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeHours::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeMinutes =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeMinutes kTimecodeMinutes{};
+  void set_timecode_minutes(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeMinutes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeSeconds =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeSeconds kTimecodeSeconds{};
+  void set_timecode_seconds(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeSeconds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeType =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeType kTimecodeType{};
+  void set_timecode_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits0 =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits0 kTimecodeUserbits0{};
+  void set_timecode_userbits0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits1 =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits1 kTimecodeUserbits1{};
+  void set_timecode_userbits1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits2 =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits2 kTimecodeUserbits2{};
+  void set_timecode_userbits2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimecodeUserbits3 =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_TimecodeUserbits3 kTimecodeUserbits3{};
+  void set_timecode_userbits3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimecodeUserbits3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      V4l2QbufFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/virtio_gpu.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VIRTIO_GPU_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VIRTIO_GPU_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class VirtioGpuCmdResponseFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioGpuCmdResponseFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioGpuCmdResponseFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioGpuCmdResponseFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctx_id() const { return at<1>().valid(); }
+  uint32_t ctx_id() const { return at<1>().as_uint32(); }
+  bool has_dev() const { return at<2>().valid(); }
+  int32_t dev() const { return at<2>().as_int32(); }
+  bool has_fence_id() const { return at<3>().valid(); }
+  uint64_t fence_id() const { return at<3>().as_uint64(); }
+  bool has_flags() const { return at<4>().valid(); }
+  uint32_t flags() const { return at<4>().as_uint32(); }
+  bool has_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars name() const { return at<5>().as_string(); }
+  bool has_num_free() const { return at<6>().valid(); }
+  uint32_t num_free() const { return at<6>().as_uint32(); }
+  bool has_seqno() const { return at<7>().valid(); }
+  uint32_t seqno() const { return at<7>().as_uint32(); }
+  bool has_type() const { return at<8>().valid(); }
+  uint32_t type() const { return at<8>().as_uint32(); }
+  bool has_vq() const { return at<9>().valid(); }
+  uint32_t vq() const { return at<9>().as_uint32(); }
+};
+
+class VirtioGpuCmdResponseFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioGpuCmdResponseFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtxIdFieldNumber = 1,
+    kDevFieldNumber = 2,
+    kFenceIdFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+    kNameFieldNumber = 5,
+    kNumFreeFieldNumber = 6,
+    kSeqnoFieldNumber = 7,
+    kTypeFieldNumber = 8,
+    kVqFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioGpuCmdResponseFtraceEvent"; }
+
+
+  using FieldMetadata_CtxId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_CtxId kCtxId{};
+  void set_ctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtxId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FenceId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_FenceId kFenceId{};
+  void set_fence_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FenceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumFree =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_NumFree kNumFree{};
+  void set_num_free(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumFree::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Vq =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdResponseFtraceEvent>;
+
+  static constexpr FieldMetadata_Vq kVq{};
+  void set_vq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class VirtioGpuCmdQueueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioGpuCmdQueueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioGpuCmdQueueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioGpuCmdQueueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_ctx_id() const { return at<1>().valid(); }
+  uint32_t ctx_id() const { return at<1>().as_uint32(); }
+  bool has_dev() const { return at<2>().valid(); }
+  int32_t dev() const { return at<2>().as_int32(); }
+  bool has_fence_id() const { return at<3>().valid(); }
+  uint64_t fence_id() const { return at<3>().as_uint64(); }
+  bool has_flags() const { return at<4>().valid(); }
+  uint32_t flags() const { return at<4>().as_uint32(); }
+  bool has_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars name() const { return at<5>().as_string(); }
+  bool has_num_free() const { return at<6>().valid(); }
+  uint32_t num_free() const { return at<6>().as_uint32(); }
+  bool has_seqno() const { return at<7>().valid(); }
+  uint32_t seqno() const { return at<7>().as_uint32(); }
+  bool has_type() const { return at<8>().valid(); }
+  uint32_t type() const { return at<8>().as_uint32(); }
+  bool has_vq() const { return at<9>().valid(); }
+  uint32_t vq() const { return at<9>().as_uint32(); }
+};
+
+class VirtioGpuCmdQueueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioGpuCmdQueueFtraceEvent_Decoder;
+  enum : int32_t {
+    kCtxIdFieldNumber = 1,
+    kDevFieldNumber = 2,
+    kFenceIdFieldNumber = 3,
+    kFlagsFieldNumber = 4,
+    kNameFieldNumber = 5,
+    kNumFreeFieldNumber = 6,
+    kSeqnoFieldNumber = 7,
+    kTypeFieldNumber = 8,
+    kVqFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioGpuCmdQueueFtraceEvent"; }
+
+
+  using FieldMetadata_CtxId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_CtxId kCtxId{};
+  void set_ctx_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CtxId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Dev =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Dev kDev{};
+  void set_dev(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dev::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FenceId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_FenceId kFenceId{};
+  void set_fence_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FenceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Flags =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Flags kFlags{};
+  void set_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Flags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumFree =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_NumFree kNumFree{};
+  void set_num_free(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumFree::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Seqno =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Seqno kSeqno{};
+  void set_seqno(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Seqno::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Vq =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioGpuCmdQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Vq kVq{};
+  void set_vq(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Vq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/virtio_video.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VIRTIO_VIDEO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VIRTIO_VIDEO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class VirtioVideoResourceQueueDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioVideoResourceQueueDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioVideoResourceQueueDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioVideoResourceQueueDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_data_size0() const { return at<1>().valid(); }
+  uint32_t data_size0() const { return at<1>().as_uint32(); }
+  bool has_data_size1() const { return at<2>().valid(); }
+  uint32_t data_size1() const { return at<2>().as_uint32(); }
+  bool has_data_size2() const { return at<3>().valid(); }
+  uint32_t data_size2() const { return at<3>().as_uint32(); }
+  bool has_data_size3() const { return at<4>().valid(); }
+  uint32_t data_size3() const { return at<4>().as_uint32(); }
+  bool has_queue_type() const { return at<5>().valid(); }
+  uint32_t queue_type() const { return at<5>().as_uint32(); }
+  bool has_resource_id() const { return at<6>().valid(); }
+  int32_t resource_id() const { return at<6>().as_int32(); }
+  bool has_stream_id() const { return at<7>().valid(); }
+  int32_t stream_id() const { return at<7>().as_int32(); }
+  bool has_timestamp() const { return at<8>().valid(); }
+  uint64_t timestamp() const { return at<8>().as_uint64(); }
+};
+
+class VirtioVideoResourceQueueDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioVideoResourceQueueDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kDataSize0FieldNumber = 1,
+    kDataSize1FieldNumber = 2,
+    kDataSize2FieldNumber = 3,
+    kDataSize3FieldNumber = 4,
+    kQueueTypeFieldNumber = 5,
+    kResourceIdFieldNumber = 6,
+    kStreamIdFieldNumber = 7,
+    kTimestampFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioVideoResourceQueueDoneFtraceEvent"; }
+
+
+  using FieldMetadata_DataSize0 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize0 kDataSize0{};
+  void set_data_size0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataSize1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize1 kDataSize1{};
+  void set_data_size1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataSize2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize2 kDataSize2{};
+  void set_data_size2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataSize3 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize3 kDataSize3{};
+  void set_data_size3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_QueueType =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_QueueType kQueueType{};
+  void set_queue_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_QueueType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_ResourceId kResourceId{};
+  void set_resource_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResourceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StreamId =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_StreamId kStreamId{};
+  void set_stream_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StreamId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VirtioVideoResourceQueueDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class VirtioVideoResourceQueueFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioVideoResourceQueueFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioVideoResourceQueueFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioVideoResourceQueueFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_data_size0() const { return at<1>().valid(); }
+  uint32_t data_size0() const { return at<1>().as_uint32(); }
+  bool has_data_size1() const { return at<2>().valid(); }
+  uint32_t data_size1() const { return at<2>().as_uint32(); }
+  bool has_data_size2() const { return at<3>().valid(); }
+  uint32_t data_size2() const { return at<3>().as_uint32(); }
+  bool has_data_size3() const { return at<4>().valid(); }
+  uint32_t data_size3() const { return at<4>().as_uint32(); }
+  bool has_queue_type() const { return at<5>().valid(); }
+  uint32_t queue_type() const { return at<5>().as_uint32(); }
+  bool has_resource_id() const { return at<6>().valid(); }
+  int32_t resource_id() const { return at<6>().as_int32(); }
+  bool has_stream_id() const { return at<7>().valid(); }
+  int32_t stream_id() const { return at<7>().as_int32(); }
+  bool has_timestamp() const { return at<8>().valid(); }
+  uint64_t timestamp() const { return at<8>().as_uint64(); }
+};
+
+class VirtioVideoResourceQueueFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioVideoResourceQueueFtraceEvent_Decoder;
+  enum : int32_t {
+    kDataSize0FieldNumber = 1,
+    kDataSize1FieldNumber = 2,
+    kDataSize2FieldNumber = 3,
+    kDataSize3FieldNumber = 4,
+    kQueueTypeFieldNumber = 5,
+    kResourceIdFieldNumber = 6,
+    kStreamIdFieldNumber = 7,
+    kTimestampFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioVideoResourceQueueFtraceEvent"; }
+
+
+  using FieldMetadata_DataSize0 =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize0 kDataSize0{};
+  void set_data_size0(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize0::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataSize1 =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize1 kDataSize1{};
+  void set_data_size1(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize1::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataSize2 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize2 kDataSize2{};
+  void set_data_size2(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataSize3 =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_DataSize3 kDataSize3{};
+  void set_data_size3(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataSize3::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_QueueType =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_QueueType kQueueType{};
+  void set_queue_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_QueueType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_ResourceId kResourceId{};
+  void set_resource_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResourceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StreamId =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_StreamId kStreamId{};
+  void set_stream_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StreamId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VirtioVideoResourceQueueFtraceEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class VirtioVideoCmdDoneFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioVideoCmdDoneFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioVideoCmdDoneFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioVideoCmdDoneFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_stream_id() const { return at<1>().valid(); }
+  uint32_t stream_id() const { return at<1>().as_uint32(); }
+  bool has_type() const { return at<2>().valid(); }
+  uint32_t type() const { return at<2>().as_uint32(); }
+};
+
+class VirtioVideoCmdDoneFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioVideoCmdDoneFtraceEvent_Decoder;
+  enum : int32_t {
+    kStreamIdFieldNumber = 1,
+    kTypeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioVideoCmdDoneFtraceEvent"; }
+
+
+  using FieldMetadata_StreamId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoCmdDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_StreamId kStreamId{};
+  void set_stream_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StreamId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoCmdDoneFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class VirtioVideoCmdFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VirtioVideoCmdFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VirtioVideoCmdFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VirtioVideoCmdFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_stream_id() const { return at<1>().valid(); }
+  uint32_t stream_id() const { return at<1>().as_uint32(); }
+  bool has_type() const { return at<2>().valid(); }
+  uint32_t type() const { return at<2>().as_uint32(); }
+};
+
+class VirtioVideoCmdFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = VirtioVideoCmdFtraceEvent_Decoder;
+  enum : int32_t {
+    kStreamIdFieldNumber = 1,
+    kTypeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VirtioVideoCmdFtraceEvent"; }
+
+
+  using FieldMetadata_StreamId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoCmdFtraceEvent>;
+
+  static constexpr FieldMetadata_StreamId kStreamId{};
+  void set_stream_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StreamId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VirtioVideoCmdFtraceEvent>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/vmscan.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VMSCAN_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_VMSCAN_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class MmShrinkSlabEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmShrinkSlabEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmShrinkSlabEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmShrinkSlabEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_new_scan() const { return at<1>().valid(); }
+  int64_t new_scan() const { return at<1>().as_int64(); }
+  bool has_retval() const { return at<2>().valid(); }
+  int32_t retval() const { return at<2>().as_int32(); }
+  bool has_shr() const { return at<3>().valid(); }
+  uint64_t shr() const { return at<3>().as_uint64(); }
+  bool has_shrink() const { return at<4>().valid(); }
+  uint64_t shrink() const { return at<4>().as_uint64(); }
+  bool has_total_scan() const { return at<5>().valid(); }
+  int64_t total_scan() const { return at<5>().as_int64(); }
+  bool has_unused_scan() const { return at<6>().valid(); }
+  int64_t unused_scan() const { return at<6>().as_int64(); }
+  bool has_nid() const { return at<7>().valid(); }
+  int32_t nid() const { return at<7>().as_int32(); }
+};
+
+class MmShrinkSlabEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmShrinkSlabEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kNewScanFieldNumber = 1,
+    kRetvalFieldNumber = 2,
+    kShrFieldNumber = 3,
+    kShrinkFieldNumber = 4,
+    kTotalScanFieldNumber = 5,
+    kUnusedScanFieldNumber = 6,
+    kNidFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmShrinkSlabEndFtraceEvent"; }
+
+
+  using FieldMetadata_NewScan =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_NewScan kNewScan{};
+  void set_new_scan(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NewScan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Retval =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Retval kRetval{};
+  void set_retval(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Retval::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Shr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Shr kShr{};
+  void set_shr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Shr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Shrink =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Shrink kShrink{};
+  void set_shrink(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Shrink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalScan =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalScan kTotalScan{};
+  void set_total_scan(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalScan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UnusedScan =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_UnusedScan kUnusedScan{};
+  void set_unused_scan(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnusedScan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmShrinkSlabEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmShrinkSlabStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmShrinkSlabStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmShrinkSlabStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmShrinkSlabStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cache_items() const { return at<1>().valid(); }
+  uint64_t cache_items() const { return at<1>().as_uint64(); }
+  bool has_delta() const { return at<2>().valid(); }
+  uint64_t delta() const { return at<2>().as_uint64(); }
+  bool has_gfp_flags() const { return at<3>().valid(); }
+  uint32_t gfp_flags() const { return at<3>().as_uint32(); }
+  bool has_lru_pgs() const { return at<4>().valid(); }
+  uint64_t lru_pgs() const { return at<4>().as_uint64(); }
+  bool has_nr_objects_to_shrink() const { return at<5>().valid(); }
+  int64_t nr_objects_to_shrink() const { return at<5>().as_int64(); }
+  bool has_pgs_scanned() const { return at<6>().valid(); }
+  uint64_t pgs_scanned() const { return at<6>().as_uint64(); }
+  bool has_shr() const { return at<7>().valid(); }
+  uint64_t shr() const { return at<7>().as_uint64(); }
+  bool has_shrink() const { return at<8>().valid(); }
+  uint64_t shrink() const { return at<8>().as_uint64(); }
+  bool has_total_scan() const { return at<9>().valid(); }
+  uint64_t total_scan() const { return at<9>().as_uint64(); }
+  bool has_nid() const { return at<10>().valid(); }
+  int32_t nid() const { return at<10>().as_int32(); }
+  bool has_priority() const { return at<11>().valid(); }
+  int32_t priority() const { return at<11>().as_int32(); }
+};
+
+class MmShrinkSlabStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmShrinkSlabStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kCacheItemsFieldNumber = 1,
+    kDeltaFieldNumber = 2,
+    kGfpFlagsFieldNumber = 3,
+    kLruPgsFieldNumber = 4,
+    kNrObjectsToShrinkFieldNumber = 5,
+    kPgsScannedFieldNumber = 6,
+    kShrFieldNumber = 7,
+    kShrinkFieldNumber = 8,
+    kTotalScanFieldNumber = 9,
+    kNidFieldNumber = 10,
+    kPriorityFieldNumber = 11,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmShrinkSlabStartFtraceEvent"; }
+
+
+  using FieldMetadata_CacheItems =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_CacheItems kCacheItems{};
+  void set_cache_items(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CacheItems::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Delta =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Delta kDelta{};
+  void set_delta(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Delta::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LruPgs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_LruPgs kLruPgs{};
+  void set_lru_pgs(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LruPgs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NrObjectsToShrink =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_NrObjectsToShrink kNrObjectsToShrink{};
+  void set_nr_objects_to_shrink(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrObjectsToShrink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PgsScanned =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_PgsScanned kPgsScanned{};
+  void set_pgs_scanned(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PgsScanned::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Shr =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Shr kShr{};
+  void set_shr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Shr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Shrink =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Shrink kShrink{};
+  void set_shrink(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Shrink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalScan =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_TotalScan kTotalScan{};
+  void set_total_scan(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalScan::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Priority =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmShrinkSlabStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Priority kPriority{};
+  void set_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Priority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmVmscanKswapdSleepFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmVmscanKswapdSleepFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmVmscanKswapdSleepFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmVmscanKswapdSleepFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+};
+
+class MmVmscanKswapdSleepFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmVmscanKswapdSleepFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmVmscanKswapdSleepFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanKswapdSleepFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmVmscanKswapdWakeFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmVmscanKswapdWakeFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmVmscanKswapdWakeFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmVmscanKswapdWakeFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nid() const { return at<1>().valid(); }
+  int32_t nid() const { return at<1>().as_int32(); }
+  bool has_order() const { return at<2>().valid(); }
+  int32_t order() const { return at<2>().as_int32(); }
+  bool has_zid() const { return at<3>().valid(); }
+  int32_t zid() const { return at<3>().as_int32(); }
+};
+
+class MmVmscanKswapdWakeFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmVmscanKswapdWakeFtraceEvent_Decoder;
+  enum : int32_t {
+    kNidFieldNumber = 1,
+    kOrderFieldNumber = 2,
+    kZidFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmVmscanKswapdWakeFtraceEvent"; }
+
+
+  using FieldMetadata_Nid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanKswapdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_Nid kNid{};
+  void set_nid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanKswapdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Zid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanKswapdWakeFtraceEvent>;
+
+  static constexpr FieldMetadata_Zid kZid{};
+  void set_zid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Zid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmVmscanDirectReclaimEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmVmscanDirectReclaimEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmVmscanDirectReclaimEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmVmscanDirectReclaimEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_nr_reclaimed() const { return at<1>().valid(); }
+  uint64_t nr_reclaimed() const { return at<1>().as_uint64(); }
+};
+
+class MmVmscanDirectReclaimEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmVmscanDirectReclaimEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kNrReclaimedFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmVmscanDirectReclaimEndFtraceEvent"; }
+
+
+  using FieldMetadata_NrReclaimed =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MmVmscanDirectReclaimEndFtraceEvent>;
+
+  static constexpr FieldMetadata_NrReclaimed kNrReclaimed{};
+  void set_nr_reclaimed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NrReclaimed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MmVmscanDirectReclaimBeginFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MmVmscanDirectReclaimBeginFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MmVmscanDirectReclaimBeginFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MmVmscanDirectReclaimBeginFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_order() const { return at<1>().valid(); }
+  int32_t order() const { return at<1>().as_int32(); }
+  bool has_may_writepage() const { return at<2>().valid(); }
+  int32_t may_writepage() const { return at<2>().as_int32(); }
+  bool has_gfp_flags() const { return at<3>().valid(); }
+  uint32_t gfp_flags() const { return at<3>().as_uint32(); }
+};
+
+class MmVmscanDirectReclaimBeginFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = MmVmscanDirectReclaimBeginFtraceEvent_Decoder;
+  enum : int32_t {
+    kOrderFieldNumber = 1,
+    kMayWritepageFieldNumber = 2,
+    kGfpFlagsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MmVmscanDirectReclaimBeginFtraceEvent"; }
+
+
+  using FieldMetadata_Order =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanDirectReclaimBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_Order kOrder{};
+  void set_order(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Order::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MayWritepage =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MmVmscanDirectReclaimBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_MayWritepage kMayWritepage{};
+  void set_may_writepage(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MayWritepage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GfpFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MmVmscanDirectReclaimBeginFtraceEvent>;
+
+  static constexpr FieldMetadata_GfpFlags kGfpFlags{};
+  void set_gfp_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GfpFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ftrace/workqueue.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_WORKQUEUE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_FTRACE_WORKQUEUE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class WorkqueueQueueWorkFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WorkqueueQueueWorkFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WorkqueueQueueWorkFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WorkqueueQueueWorkFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_work() const { return at<1>().valid(); }
+  uint64_t work() const { return at<1>().as_uint64(); }
+  bool has_function() const { return at<2>().valid(); }
+  uint64_t function() const { return at<2>().as_uint64(); }
+  bool has_workqueue() const { return at<3>().valid(); }
+  uint64_t workqueue() const { return at<3>().as_uint64(); }
+  bool has_req_cpu() const { return at<4>().valid(); }
+  uint32_t req_cpu() const { return at<4>().as_uint32(); }
+  bool has_cpu() const { return at<5>().valid(); }
+  uint32_t cpu() const { return at<5>().as_uint32(); }
+};
+
+class WorkqueueQueueWorkFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WorkqueueQueueWorkFtraceEvent_Decoder;
+  enum : int32_t {
+    kWorkFieldNumber = 1,
+    kFunctionFieldNumber = 2,
+    kWorkqueueFieldNumber = 3,
+    kReqCpuFieldNumber = 4,
+    kCpuFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WorkqueueQueueWorkFtraceEvent"; }
+
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_Work kWork{};
+  void set_work(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Work::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Function =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_Function kFunction{};
+  void set_function(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Function::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Workqueue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_Workqueue kWorkqueue{};
+  void set_workqueue(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Workqueue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReqCpu =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_ReqCpu kReqCpu{};
+  void set_req_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReqCpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      WorkqueueQueueWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class WorkqueueExecuteStartFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WorkqueueExecuteStartFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WorkqueueExecuteStartFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WorkqueueExecuteStartFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_work() const { return at<1>().valid(); }
+  uint64_t work() const { return at<1>().as_uint64(); }
+  bool has_function() const { return at<2>().valid(); }
+  uint64_t function() const { return at<2>().as_uint64(); }
+};
+
+class WorkqueueExecuteStartFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WorkqueueExecuteStartFtraceEvent_Decoder;
+  enum : int32_t {
+    kWorkFieldNumber = 1,
+    kFunctionFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WorkqueueExecuteStartFtraceEvent"; }
+
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueExecuteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Work kWork{};
+  void set_work(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Work::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Function =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueExecuteStartFtraceEvent>;
+
+  static constexpr FieldMetadata_Function kFunction{};
+  void set_function(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Function::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class WorkqueueExecuteEndFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WorkqueueExecuteEndFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WorkqueueExecuteEndFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WorkqueueExecuteEndFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_work() const { return at<1>().valid(); }
+  uint64_t work() const { return at<1>().as_uint64(); }
+  bool has_function() const { return at<2>().valid(); }
+  uint64_t function() const { return at<2>().as_uint64(); }
+};
+
+class WorkqueueExecuteEndFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WorkqueueExecuteEndFtraceEvent_Decoder;
+  enum : int32_t {
+    kWorkFieldNumber = 1,
+    kFunctionFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WorkqueueExecuteEndFtraceEvent"; }
+
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueExecuteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Work kWork{};
+  void set_work(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Work::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Function =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueExecuteEndFtraceEvent>;
+
+  static constexpr FieldMetadata_Function kFunction{};
+  void set_function(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Function::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class WorkqueueActivateWorkFtraceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  WorkqueueActivateWorkFtraceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit WorkqueueActivateWorkFtraceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit WorkqueueActivateWorkFtraceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_work() const { return at<1>().valid(); }
+  uint64_t work() const { return at<1>().as_uint64(); }
+};
+
+class WorkqueueActivateWorkFtraceEvent : public ::protozero::Message {
+ public:
+  using Decoder = WorkqueueActivateWorkFtraceEvent_Decoder;
+  enum : int32_t {
+    kWorkFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.WorkqueueActivateWorkFtraceEvent"; }
+
+
+  using FieldMetadata_Work =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      WorkqueueActivateWorkFtraceEvent>;
+
+  static constexpr FieldMetadata_Work kWork{};
+  void set_work(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Work::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_COUNTER_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_COUNTER_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GpuCounterDescriptor;
+class GpuCounterEvent_GpuCounter;
+
+class GpuCounterEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuCounterEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_counter_descriptor() const { return at<1>().valid(); }
+  ::protozero::ConstBytes counter_descriptor() const { return at<1>().as_bytes(); }
+  bool has_counters() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> counters() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_gpu_id() const { return at<3>().valid(); }
+  int32_t gpu_id() const { return at<3>().as_int32(); }
+};
+
+class GpuCounterEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterEvent_Decoder;
+  enum : int32_t {
+    kCounterDescriptorFieldNumber = 1,
+    kCountersFieldNumber = 2,
+    kGpuIdFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterEvent"; }
+
+  using GpuCounter = ::perfetto::protos::pbzero::GpuCounterEvent_GpuCounter;
+
+  using FieldMetadata_CounterDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterDescriptor,
+      GpuCounterEvent>;
+
+  static constexpr FieldMetadata_CounterDescriptor kCounterDescriptor{};
+  template <typename T = GpuCounterDescriptor> T* set_counter_descriptor() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Counters =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuCounterEvent_GpuCounter,
+      GpuCounterEvent>;
+
+  static constexpr FieldMetadata_Counters kCounters{};
+  template <typename T = GpuCounterEvent_GpuCounter> T* add_counters() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      GpuCounterEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class GpuCounterEvent_GpuCounter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuCounterEvent_GpuCounter_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuCounterEvent_GpuCounter_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuCounterEvent_GpuCounter_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_counter_id() const { return at<1>().valid(); }
+  uint32_t counter_id() const { return at<1>().as_uint32(); }
+  bool has_int_value() const { return at<2>().valid(); }
+  int64_t int_value() const { return at<2>().as_int64(); }
+  bool has_double_value() const { return at<3>().valid(); }
+  double double_value() const { return at<3>().as_double(); }
+};
+
+class GpuCounterEvent_GpuCounter : public ::protozero::Message {
+ public:
+  using Decoder = GpuCounterEvent_GpuCounter_Decoder;
+  enum : int32_t {
+    kCounterIdFieldNumber = 1,
+    kIntValueFieldNumber = 2,
+    kDoubleValueFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuCounterEvent.GpuCounter"; }
+
+
+  using FieldMetadata_CounterId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuCounterEvent_GpuCounter>;
+
+  static constexpr FieldMetadata_CounterId kCounterId{};
+  void set_counter_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      GpuCounterEvent_GpuCounter>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      GpuCounterEvent_GpuCounter>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/gpu/gpu_log.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_LOG_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_LOG_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_GpuLog {
+enum Severity : int32_t;
+}  // namespace perfetto_pbzero_enum_GpuLog
+using GpuLog_Severity = perfetto_pbzero_enum_GpuLog::Severity;
+
+namespace perfetto_pbzero_enum_GpuLog {
+enum Severity : int32_t {
+  LOG_SEVERITY_UNSPECIFIED = 0,
+  LOG_SEVERITY_VERBOSE = 1,
+  LOG_SEVERITY_DEBUG = 2,
+  LOG_SEVERITY_INFO = 3,
+  LOG_SEVERITY_WARNING = 4,
+  LOG_SEVERITY_ERROR = 5,
+};
+} // namespace perfetto_pbzero_enum_GpuLog
+using GpuLog_Severity = perfetto_pbzero_enum_GpuLog::Severity;
+
+
+constexpr GpuLog_Severity GpuLog_Severity_MIN = GpuLog_Severity::LOG_SEVERITY_UNSPECIFIED;
+constexpr GpuLog_Severity GpuLog_Severity_MAX = GpuLog_Severity::LOG_SEVERITY_ERROR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* GpuLog_Severity_Name(::perfetto::protos::pbzero::GpuLog_Severity value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_UNSPECIFIED:
+    return "LOG_SEVERITY_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_VERBOSE:
+    return "LOG_SEVERITY_VERBOSE";
+
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_DEBUG:
+    return "LOG_SEVERITY_DEBUG";
+
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_INFO:
+    return "LOG_SEVERITY_INFO";
+
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_WARNING:
+    return "LOG_SEVERITY_WARNING";
+
+  case ::perfetto::protos::pbzero::GpuLog_Severity::LOG_SEVERITY_ERROR:
+    return "LOG_SEVERITY_ERROR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class GpuLog_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuLog_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuLog_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuLog_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_severity() const { return at<1>().valid(); }
+  int32_t severity() const { return at<1>().as_int32(); }
+  bool has_tag() const { return at<2>().valid(); }
+  ::protozero::ConstChars tag() const { return at<2>().as_string(); }
+  bool has_log_message() const { return at<3>().valid(); }
+  ::protozero::ConstChars log_message() const { return at<3>().as_string(); }
+};
+
+class GpuLog : public ::protozero::Message {
+ public:
+  using Decoder = GpuLog_Decoder;
+  enum : int32_t {
+    kSeverityFieldNumber = 1,
+    kTagFieldNumber = 2,
+    kLogMessageFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuLog"; }
+
+
+  using Severity = ::perfetto::protos::pbzero::GpuLog_Severity;
+  static inline const char* Severity_Name(Severity value) {
+    return ::perfetto::protos::pbzero::GpuLog_Severity_Name(value);
+  }
+  static inline const Severity LOG_SEVERITY_UNSPECIFIED = Severity::LOG_SEVERITY_UNSPECIFIED;
+  static inline const Severity LOG_SEVERITY_VERBOSE = Severity::LOG_SEVERITY_VERBOSE;
+  static inline const Severity LOG_SEVERITY_DEBUG = Severity::LOG_SEVERITY_DEBUG;
+  static inline const Severity LOG_SEVERITY_INFO = Severity::LOG_SEVERITY_INFO;
+  static inline const Severity LOG_SEVERITY_WARNING = Severity::LOG_SEVERITY_WARNING;
+  static inline const Severity LOG_SEVERITY_ERROR = Severity::LOG_SEVERITY_ERROR;
+
+  using FieldMetadata_Severity =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::GpuLog_Severity,
+      GpuLog>;
+
+  static constexpr FieldMetadata_Severity kSeverity{};
+  void set_severity(::perfetto::protos::pbzero::GpuLog_Severity value) {
+    static constexpr uint32_t field_id = FieldMetadata_Severity::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tag =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuLog>;
+
+  static constexpr FieldMetadata_Tag kTag{};
+  void set_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, data, size);
+  }
+  void set_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Tag::kFieldId, chars.data, chars.size);
+  }
+  void set_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LogMessage =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuLog>;
+
+  static constexpr FieldMetadata_LogMessage kLogMessage{};
+  void set_log_message(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_LogMessage::kFieldId, data, size);
+  }
+  void set_log_message(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_LogMessage::kFieldId, chars.data, chars.size);
+  }
+  void set_log_message(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_LogMessage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_RENDER_STAGE_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_GPU_RENDER_STAGE_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class GpuRenderStageEvent_ExtraData;
+class GpuRenderStageEvent_Specifications;
+class GpuRenderStageEvent_Specifications_ContextSpec;
+class GpuRenderStageEvent_Specifications_Description;
+namespace perfetto_pbzero_enum_InternedGpuRenderStageSpecification {
+enum RenderStageCategory : int32_t;
+}  // namespace perfetto_pbzero_enum_InternedGpuRenderStageSpecification
+using InternedGpuRenderStageSpecification_RenderStageCategory = perfetto_pbzero_enum_InternedGpuRenderStageSpecification::RenderStageCategory;
+namespace perfetto_pbzero_enum_InternedGraphicsContext {
+enum Api : int32_t;
+}  // namespace perfetto_pbzero_enum_InternedGraphicsContext
+using InternedGraphicsContext_Api = perfetto_pbzero_enum_InternedGraphicsContext::Api;
+
+namespace perfetto_pbzero_enum_InternedGpuRenderStageSpecification {
+enum RenderStageCategory : int32_t {
+  OTHER = 0,
+  GRAPHICS = 1,
+  COMPUTE = 2,
+};
+} // namespace perfetto_pbzero_enum_InternedGpuRenderStageSpecification
+using InternedGpuRenderStageSpecification_RenderStageCategory = perfetto_pbzero_enum_InternedGpuRenderStageSpecification::RenderStageCategory;
+
+
+constexpr InternedGpuRenderStageSpecification_RenderStageCategory InternedGpuRenderStageSpecification_RenderStageCategory_MIN = InternedGpuRenderStageSpecification_RenderStageCategory::OTHER;
+constexpr InternedGpuRenderStageSpecification_RenderStageCategory InternedGpuRenderStageSpecification_RenderStageCategory_MAX = InternedGpuRenderStageSpecification_RenderStageCategory::COMPUTE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* InternedGpuRenderStageSpecification_RenderStageCategory_Name(::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory::OTHER:
+    return "OTHER";
+
+  case ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory::GRAPHICS:
+    return "GRAPHICS";
+
+  case ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory::COMPUTE:
+    return "COMPUTE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_InternedGraphicsContext {
+enum Api : int32_t {
+  UNDEFINED = 0,
+  OPEN_GL = 1,
+  VULKAN = 2,
+  OPEN_CL = 3,
+};
+} // namespace perfetto_pbzero_enum_InternedGraphicsContext
+using InternedGraphicsContext_Api = perfetto_pbzero_enum_InternedGraphicsContext::Api;
+
+
+constexpr InternedGraphicsContext_Api InternedGraphicsContext_Api_MIN = InternedGraphicsContext_Api::UNDEFINED;
+constexpr InternedGraphicsContext_Api InternedGraphicsContext_Api_MAX = InternedGraphicsContext_Api::OPEN_CL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* InternedGraphicsContext_Api_Name(::perfetto::protos::pbzero::InternedGraphicsContext_Api value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::InternedGraphicsContext_Api::UNDEFINED:
+    return "UNDEFINED";
+
+  case ::perfetto::protos::pbzero::InternedGraphicsContext_Api::OPEN_GL:
+    return "OPEN_GL";
+
+  case ::perfetto::protos::pbzero::InternedGraphicsContext_Api::VULKAN:
+    return "VULKAN";
+
+  case ::perfetto::protos::pbzero::InternedGraphicsContext_Api::OPEN_CL:
+    return "OPEN_CL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class InternedGpuRenderStageSpecification_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedGpuRenderStageSpecification_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedGpuRenderStageSpecification_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedGpuRenderStageSpecification_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_description() const { return at<3>().valid(); }
+  ::protozero::ConstChars description() const { return at<3>().as_string(); }
+  bool has_category() const { return at<4>().valid(); }
+  int32_t category() const { return at<4>().as_int32(); }
+};
+
+class InternedGpuRenderStageSpecification : public ::protozero::Message {
+ public:
+  using Decoder = InternedGpuRenderStageSpecification_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kDescriptionFieldNumber = 3,
+    kCategoryFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedGpuRenderStageSpecification"; }
+
+
+  using RenderStageCategory = ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory;
+  static inline const char* RenderStageCategory_Name(RenderStageCategory value) {
+    return ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory_Name(value);
+  }
+  static inline const RenderStageCategory OTHER = RenderStageCategory::OTHER;
+  static inline const RenderStageCategory GRAPHICS = RenderStageCategory::GRAPHICS;
+  static inline const RenderStageCategory COMPUTE = RenderStageCategory::COMPUTE;
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedGpuRenderStageSpecification>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InternedGpuRenderStageSpecification>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      InternedGpuRenderStageSpecification>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Category =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory,
+      InternedGpuRenderStageSpecification>;
+
+  static constexpr FieldMetadata_Category kCategory{};
+  void set_category(::perfetto::protos::pbzero::InternedGpuRenderStageSpecification_RenderStageCategory value) {
+    static constexpr uint32_t field_id = FieldMetadata_Category::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class InternedGraphicsContext_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedGraphicsContext_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedGraphicsContext_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedGraphicsContext_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+  bool has_api() const { return at<3>().valid(); }
+  int32_t api() const { return at<3>().as_int32(); }
+};
+
+class InternedGraphicsContext : public ::protozero::Message {
+ public:
+  using Decoder = InternedGraphicsContext_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kApiFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedGraphicsContext"; }
+
+
+  using Api = ::perfetto::protos::pbzero::InternedGraphicsContext_Api;
+  static inline const char* Api_Name(Api value) {
+    return ::perfetto::protos::pbzero::InternedGraphicsContext_Api_Name(value);
+  }
+  static inline const Api UNDEFINED = Api::UNDEFINED;
+  static inline const Api OPEN_GL = Api::OPEN_GL;
+  static inline const Api VULKAN = Api::VULKAN;
+  static inline const Api OPEN_CL = Api::OPEN_CL;
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedGraphicsContext>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      InternedGraphicsContext>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Api =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::InternedGraphicsContext_Api,
+      InternedGraphicsContext>;
+
+  static constexpr FieldMetadata_Api kApi{};
+  void set_api(::perfetto::protos::pbzero::InternedGraphicsContext_Api value) {
+    static constexpr uint32_t field_id = FieldMetadata_Api::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class GpuRenderStageEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuRenderStageEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuRenderStageEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuRenderStageEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_id() const { return at<1>().valid(); }
+  uint64_t event_id() const { return at<1>().as_uint64(); }
+  bool has_duration() const { return at<2>().valid(); }
+  uint64_t duration() const { return at<2>().as_uint64(); }
+  bool has_hw_queue_iid() const { return at<13>().valid(); }
+  uint64_t hw_queue_iid() const { return at<13>().as_uint64(); }
+  bool has_stage_iid() const { return at<14>().valid(); }
+  uint64_t stage_iid() const { return at<14>().as_uint64(); }
+  bool has_gpu_id() const { return at<11>().valid(); }
+  int32_t gpu_id() const { return at<11>().as_int32(); }
+  bool has_context() const { return at<5>().valid(); }
+  uint64_t context() const { return at<5>().as_uint64(); }
+  bool has_render_target_handle() const { return at<8>().valid(); }
+  uint64_t render_target_handle() const { return at<8>().as_uint64(); }
+  bool has_submission_id() const { return at<10>().valid(); }
+  uint32_t submission_id() const { return at<10>().as_uint32(); }
+  bool has_extra_data() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> extra_data() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_render_pass_handle() const { return at<9>().valid(); }
+  uint64_t render_pass_handle() const { return at<9>().as_uint64(); }
+  bool has_render_subpass_index_mask() const { return at<15>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> render_subpass_index_mask() const { return GetRepeated<uint64_t>(15); }
+  bool has_command_buffer_handle() const { return at<12>().valid(); }
+  uint64_t command_buffer_handle() const { return at<12>().as_uint64(); }
+  bool has_specifications() const { return at<7>().valid(); }
+  ::protozero::ConstBytes specifications() const { return at<7>().as_bytes(); }
+  bool has_hw_queue_id() const { return at<3>().valid(); }
+  int32_t hw_queue_id() const { return at<3>().as_int32(); }
+  bool has_stage_id() const { return at<4>().valid(); }
+  int32_t stage_id() const { return at<4>().as_int32(); }
+};
+
+class GpuRenderStageEvent : public ::protozero::Message {
+ public:
+  using Decoder = GpuRenderStageEvent_Decoder;
+  enum : int32_t {
+    kEventIdFieldNumber = 1,
+    kDurationFieldNumber = 2,
+    kHwQueueIidFieldNumber = 13,
+    kStageIidFieldNumber = 14,
+    kGpuIdFieldNumber = 11,
+    kContextFieldNumber = 5,
+    kRenderTargetHandleFieldNumber = 8,
+    kSubmissionIdFieldNumber = 10,
+    kExtraDataFieldNumber = 6,
+    kRenderPassHandleFieldNumber = 9,
+    kRenderSubpassIndexMaskFieldNumber = 15,
+    kCommandBufferHandleFieldNumber = 12,
+    kSpecificationsFieldNumber = 7,
+    kHwQueueIdFieldNumber = 3,
+    kStageIdFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuRenderStageEvent"; }
+
+  using ExtraData = ::perfetto::protos::pbzero::GpuRenderStageEvent_ExtraData;
+  using Specifications = ::perfetto::protos::pbzero::GpuRenderStageEvent_Specifications;
+
+  using FieldMetadata_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_EventId kEventId{};
+  void set_event_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Duration =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_Duration kDuration{};
+  void set_duration(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Duration::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HwQueueIid =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_HwQueueIid kHwQueueIid{};
+  void set_hw_queue_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwQueueIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StageIid =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_StageIid kStageIid{};
+  void set_stage_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StageIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_GpuId kGpuId{};
+  void set_gpu_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RenderTargetHandle =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_RenderTargetHandle kRenderTargetHandle{};
+  void set_render_target_handle(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RenderTargetHandle::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SubmissionId =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_SubmissionId kSubmissionId{};
+  void set_submission_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SubmissionId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExtraData =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent_ExtraData,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_ExtraData kExtraData{};
+  template <typename T = GpuRenderStageEvent_ExtraData> T* add_extra_data() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_RenderPassHandle =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_RenderPassHandle kRenderPassHandle{};
+  void set_render_pass_handle(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RenderPassHandle::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RenderSubpassIndexMask =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_RenderSubpassIndexMask kRenderSubpassIndexMask{};
+  void add_render_subpass_index_mask(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RenderSubpassIndexMask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CommandBufferHandle =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_CommandBufferHandle kCommandBufferHandle{};
+  void set_command_buffer_handle(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CommandBufferHandle::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Specifications =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent_Specifications,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_Specifications kSpecifications{};
+  template <typename T = GpuRenderStageEvent_Specifications> T* set_specifications() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_HwQueueId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_HwQueueId kHwQueueId{};
+  void set_hw_queue_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwQueueId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StageId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      GpuRenderStageEvent>;
+
+  static constexpr FieldMetadata_StageId kStageId{};
+  void set_stage_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StageId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class GpuRenderStageEvent_Specifications_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  GpuRenderStageEvent_Specifications_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuRenderStageEvent_Specifications_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuRenderStageEvent_Specifications_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context_spec() const { return at<1>().valid(); }
+  ::protozero::ConstBytes context_spec() const { return at<1>().as_bytes(); }
+  bool has_hw_queue() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> hw_queue() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_stage() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> stage() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class GpuRenderStageEvent_Specifications : public ::protozero::Message {
+ public:
+  using Decoder = GpuRenderStageEvent_Specifications_Decoder;
+  enum : int32_t {
+    kContextSpecFieldNumber = 1,
+    kHwQueueFieldNumber = 2,
+    kStageFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuRenderStageEvent.Specifications"; }
+
+  using ContextSpec = ::perfetto::protos::pbzero::GpuRenderStageEvent_Specifications_ContextSpec;
+  using Description = ::perfetto::protos::pbzero::GpuRenderStageEvent_Specifications_Description;
+
+  using FieldMetadata_ContextSpec =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent_Specifications_ContextSpec,
+      GpuRenderStageEvent_Specifications>;
+
+  static constexpr FieldMetadata_ContextSpec kContextSpec{};
+  template <typename T = GpuRenderStageEvent_Specifications_ContextSpec> T* set_context_spec() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_HwQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent_Specifications_Description,
+      GpuRenderStageEvent_Specifications>;
+
+  static constexpr FieldMetadata_HwQueue kHwQueue{};
+  template <typename T = GpuRenderStageEvent_Specifications_Description> T* add_hw_queue() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_Stage =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      GpuRenderStageEvent_Specifications_Description,
+      GpuRenderStageEvent_Specifications>;
+
+  static constexpr FieldMetadata_Stage kStage{};
+  template <typename T = GpuRenderStageEvent_Specifications_Description> T* add_stage() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class GpuRenderStageEvent_Specifications_Description_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuRenderStageEvent_Specifications_Description_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuRenderStageEvent_Specifications_Description_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuRenderStageEvent_Specifications_Description_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_description() const { return at<2>().valid(); }
+  ::protozero::ConstChars description() const { return at<2>().as_string(); }
+};
+
+class GpuRenderStageEvent_Specifications_Description : public ::protozero::Message {
+ public:
+  using Decoder = GpuRenderStageEvent_Specifications_Description_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kDescriptionFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuRenderStageEvent.Specifications.Description"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuRenderStageEvent_Specifications_Description>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Description =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuRenderStageEvent_Specifications_Description>;
+
+  static constexpr FieldMetadata_Description kDescription{};
+  void set_description(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Description::kFieldId, data, size);
+  }
+  void set_description(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Description::kFieldId, chars.data, chars.size);
+  }
+  void set_description(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Description::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class GpuRenderStageEvent_Specifications_ContextSpec_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuRenderStageEvent_Specifications_ContextSpec_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuRenderStageEvent_Specifications_ContextSpec_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuRenderStageEvent_Specifications_ContextSpec_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_context() const { return at<1>().valid(); }
+  uint64_t context() const { return at<1>().as_uint64(); }
+  bool has_pid() const { return at<2>().valid(); }
+  int32_t pid() const { return at<2>().as_int32(); }
+};
+
+class GpuRenderStageEvent_Specifications_ContextSpec : public ::protozero::Message {
+ public:
+  using Decoder = GpuRenderStageEvent_Specifications_ContextSpec_Decoder;
+  enum : int32_t {
+    kContextFieldNumber = 1,
+    kPidFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuRenderStageEvent.Specifications.ContextSpec"; }
+
+
+  using FieldMetadata_Context =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      GpuRenderStageEvent_Specifications_ContextSpec>;
+
+  static constexpr FieldMetadata_Context kContext{};
+  void set_context(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Context::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      GpuRenderStageEvent_Specifications_ContextSpec>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class GpuRenderStageEvent_ExtraData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  GpuRenderStageEvent_ExtraData_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit GpuRenderStageEvent_ExtraData_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit GpuRenderStageEvent_ExtraData_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class GpuRenderStageEvent_ExtraData : public ::protozero::Message {
+ public:
+  using Decoder = GpuRenderStageEvent_ExtraData_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.GpuRenderStageEvent.ExtraData"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuRenderStageEvent_ExtraData>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      GpuRenderStageEvent_ExtraData>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_VULKAN_API_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_VULKAN_API_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class VulkanApiEvent_VkDebugUtilsObjectName;
+class VulkanApiEvent_VkQueueSubmit;
+
+class VulkanApiEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VulkanApiEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanApiEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanApiEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_vk_debug_utils_object_name() const { return at<1>().valid(); }
+  ::protozero::ConstBytes vk_debug_utils_object_name() const { return at<1>().as_bytes(); }
+  bool has_vk_queue_submit() const { return at<2>().valid(); }
+  ::protozero::ConstBytes vk_queue_submit() const { return at<2>().as_bytes(); }
+};
+
+class VulkanApiEvent : public ::protozero::Message {
+ public:
+  using Decoder = VulkanApiEvent_Decoder;
+  enum : int32_t {
+    kVkDebugUtilsObjectNameFieldNumber = 1,
+    kVkQueueSubmitFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanApiEvent"; }
+
+  using VkDebugUtilsObjectName = ::perfetto::protos::pbzero::VulkanApiEvent_VkDebugUtilsObjectName;
+  using VkQueueSubmit = ::perfetto::protos::pbzero::VulkanApiEvent_VkQueueSubmit;
+
+  using FieldMetadata_VkDebugUtilsObjectName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanApiEvent_VkDebugUtilsObjectName,
+      VulkanApiEvent>;
+
+  static constexpr FieldMetadata_VkDebugUtilsObjectName kVkDebugUtilsObjectName{};
+  template <typename T = VulkanApiEvent_VkDebugUtilsObjectName> T* set_vk_debug_utils_object_name() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_VkQueueSubmit =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanApiEvent_VkQueueSubmit,
+      VulkanApiEvent>;
+
+  static constexpr FieldMetadata_VkQueueSubmit kVkQueueSubmit{};
+  template <typename T = VulkanApiEvent_VkQueueSubmit> T* set_vk_queue_submit() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class VulkanApiEvent_VkQueueSubmit_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  VulkanApiEvent_VkQueueSubmit_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanApiEvent_VkQueueSubmit_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanApiEvent_VkQueueSubmit_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_duration_ns() const { return at<1>().valid(); }
+  uint64_t duration_ns() const { return at<1>().as_uint64(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_tid() const { return at<3>().valid(); }
+  uint32_t tid() const { return at<3>().as_uint32(); }
+  bool has_vk_queue() const { return at<4>().valid(); }
+  uint64_t vk_queue() const { return at<4>().as_uint64(); }
+  bool has_vk_command_buffers() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> vk_command_buffers() const { return GetRepeated<uint64_t>(5); }
+  bool has_submission_id() const { return at<6>().valid(); }
+  uint32_t submission_id() const { return at<6>().as_uint32(); }
+};
+
+class VulkanApiEvent_VkQueueSubmit : public ::protozero::Message {
+ public:
+  using Decoder = VulkanApiEvent_VkQueueSubmit_Decoder;
+  enum : int32_t {
+    kDurationNsFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTidFieldNumber = 3,
+    kVkQueueFieldNumber = 4,
+    kVkCommandBuffersFieldNumber = 5,
+    kSubmissionIdFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanApiEvent.VkQueueSubmit"; }
+
+
+  using FieldMetadata_DurationNs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_DurationNs kDurationNs{};
+  void set_duration_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DurationNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VkQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_VkQueue kVkQueue{};
+  void set_vk_queue(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VkQueue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VkCommandBuffers =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_VkCommandBuffers kVkCommandBuffers{};
+  void add_vk_command_buffers(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VkCommandBuffers::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SubmissionId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanApiEvent_VkQueueSubmit>;
+
+  static constexpr FieldMetadata_SubmissionId kSubmissionId{};
+  void set_submission_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SubmissionId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class VulkanApiEvent_VkDebugUtilsObjectName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VulkanApiEvent_VkDebugUtilsObjectName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanApiEvent_VkDebugUtilsObjectName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanApiEvent_VkDebugUtilsObjectName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  uint32_t pid() const { return at<1>().as_uint32(); }
+  bool has_vk_device() const { return at<2>().valid(); }
+  uint64_t vk_device() const { return at<2>().as_uint64(); }
+  bool has_object_type() const { return at<3>().valid(); }
+  int32_t object_type() const { return at<3>().as_int32(); }
+  bool has_object() const { return at<4>().valid(); }
+  uint64_t object() const { return at<4>().as_uint64(); }
+  bool has_object_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars object_name() const { return at<5>().as_string(); }
+};
+
+class VulkanApiEvent_VkDebugUtilsObjectName : public ::protozero::Message {
+ public:
+  using Decoder = VulkanApiEvent_VkDebugUtilsObjectName_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kVkDeviceFieldNumber = 2,
+    kObjectTypeFieldNumber = 3,
+    kObjectFieldNumber = 4,
+    kObjectNameFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanApiEvent.VkDebugUtilsObjectName"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VkDevice =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  static constexpr FieldMetadata_VkDevice kVkDevice{};
+  void set_vk_device(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VkDevice::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ObjectType =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  static constexpr FieldMetadata_ObjectType kObjectType{};
+  void set_object_type(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObjectType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Object =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  static constexpr FieldMetadata_Object kObject{};
+  void set_object(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Object::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ObjectName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      VulkanApiEvent_VkDebugUtilsObjectName>;
+
+  static constexpr FieldMetadata_ObjectName kObjectName{};
+  void set_object_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObjectName::kFieldId, data, size);
+  }
+  void set_object_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ObjectName::kFieldId, chars.data, chars.size);
+  }
+  void set_object_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObjectName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_VULKAN_MEMORY_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_GPU_VULKAN_MEMORY_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class VulkanMemoryEventAnnotation;
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum AllocationScope : int32_t;
+}  // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_AllocationScope = perfetto_pbzero_enum_VulkanMemoryEvent::AllocationScope;
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum Operation : int32_t;
+}  // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_Operation = perfetto_pbzero_enum_VulkanMemoryEvent::Operation;
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum Source : int32_t;
+}  // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_Source = perfetto_pbzero_enum_VulkanMemoryEvent::Source;
+
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum Source : int32_t {
+  SOURCE_UNSPECIFIED = 0,
+  SOURCE_DRIVER = 1,
+  SOURCE_DEVICE = 2,
+  SOURCE_DEVICE_MEMORY = 3,
+  SOURCE_BUFFER = 4,
+  SOURCE_IMAGE = 5,
+};
+} // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_Source = perfetto_pbzero_enum_VulkanMemoryEvent::Source;
+
+
+constexpr VulkanMemoryEvent_Source VulkanMemoryEvent_Source_MIN = VulkanMemoryEvent_Source::SOURCE_UNSPECIFIED;
+constexpr VulkanMemoryEvent_Source VulkanMemoryEvent_Source_MAX = VulkanMemoryEvent_Source::SOURCE_IMAGE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* VulkanMemoryEvent_Source_Name(::perfetto::protos::pbzero::VulkanMemoryEvent_Source value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_UNSPECIFIED:
+    return "SOURCE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_DRIVER:
+    return "SOURCE_DRIVER";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_DEVICE:
+    return "SOURCE_DEVICE";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_DEVICE_MEMORY:
+    return "SOURCE_DEVICE_MEMORY";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_BUFFER:
+    return "SOURCE_BUFFER";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Source::SOURCE_IMAGE:
+    return "SOURCE_IMAGE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum Operation : int32_t {
+  OP_UNSPECIFIED = 0,
+  OP_CREATE = 1,
+  OP_DESTROY = 2,
+  OP_BIND = 3,
+  OP_DESTROY_BOUND = 4,
+  OP_ANNOTATIONS = 5,
+};
+} // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_Operation = perfetto_pbzero_enum_VulkanMemoryEvent::Operation;
+
+
+constexpr VulkanMemoryEvent_Operation VulkanMemoryEvent_Operation_MIN = VulkanMemoryEvent_Operation::OP_UNSPECIFIED;
+constexpr VulkanMemoryEvent_Operation VulkanMemoryEvent_Operation_MAX = VulkanMemoryEvent_Operation::OP_ANNOTATIONS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* VulkanMemoryEvent_Operation_Name(::perfetto::protos::pbzero::VulkanMemoryEvent_Operation value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_UNSPECIFIED:
+    return "OP_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_CREATE:
+    return "OP_CREATE";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_DESTROY:
+    return "OP_DESTROY";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_BIND:
+    return "OP_BIND";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_DESTROY_BOUND:
+    return "OP_DESTROY_BOUND";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation::OP_ANNOTATIONS:
+    return "OP_ANNOTATIONS";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_VulkanMemoryEvent {
+enum AllocationScope : int32_t {
+  SCOPE_UNSPECIFIED = 0,
+  SCOPE_COMMAND = 1,
+  SCOPE_OBJECT = 2,
+  SCOPE_CACHE = 3,
+  SCOPE_DEVICE = 4,
+  SCOPE_INSTANCE = 5,
+};
+} // namespace perfetto_pbzero_enum_VulkanMemoryEvent
+using VulkanMemoryEvent_AllocationScope = perfetto_pbzero_enum_VulkanMemoryEvent::AllocationScope;
+
+
+constexpr VulkanMemoryEvent_AllocationScope VulkanMemoryEvent_AllocationScope_MIN = VulkanMemoryEvent_AllocationScope::SCOPE_UNSPECIFIED;
+constexpr VulkanMemoryEvent_AllocationScope VulkanMemoryEvent_AllocationScope_MAX = VulkanMemoryEvent_AllocationScope::SCOPE_INSTANCE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* VulkanMemoryEvent_AllocationScope_Name(::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_UNSPECIFIED:
+    return "SCOPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_COMMAND:
+    return "SCOPE_COMMAND";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_OBJECT:
+    return "SCOPE_OBJECT";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_CACHE:
+    return "SCOPE_CACHE";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_DEVICE:
+    return "SCOPE_DEVICE";
+
+  case ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope::SCOPE_INSTANCE:
+    return "SCOPE_INSTANCE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class VulkanMemoryEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/20, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  VulkanMemoryEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanMemoryEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanMemoryEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_source() const { return at<1>().valid(); }
+  int32_t source() const { return at<1>().as_int32(); }
+  bool has_operation() const { return at<2>().valid(); }
+  int32_t operation() const { return at<2>().as_int32(); }
+  bool has_timestamp() const { return at<3>().valid(); }
+  int64_t timestamp() const { return at<3>().as_int64(); }
+  bool has_pid() const { return at<4>().valid(); }
+  uint32_t pid() const { return at<4>().as_uint32(); }
+  bool has_memory_address() const { return at<5>().valid(); }
+  uint64_t memory_address() const { return at<5>().as_uint64(); }
+  bool has_memory_size() const { return at<6>().valid(); }
+  uint64_t memory_size() const { return at<6>().as_uint64(); }
+  bool has_caller_iid() const { return at<7>().valid(); }
+  uint64_t caller_iid() const { return at<7>().as_uint64(); }
+  bool has_allocation_scope() const { return at<8>().valid(); }
+  int32_t allocation_scope() const { return at<8>().as_int32(); }
+  bool has_annotations() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> annotations() const { return GetRepeated<::protozero::ConstBytes>(9); }
+  bool has_device() const { return at<16>().valid(); }
+  uint64_t device() const { return at<16>().as_uint64(); }
+  bool has_device_memory() const { return at<17>().valid(); }
+  uint64_t device_memory() const { return at<17>().as_uint64(); }
+  bool has_memory_type() const { return at<18>().valid(); }
+  uint32_t memory_type() const { return at<18>().as_uint32(); }
+  bool has_heap() const { return at<19>().valid(); }
+  uint32_t heap() const { return at<19>().as_uint32(); }
+  bool has_object_handle() const { return at<20>().valid(); }
+  uint64_t object_handle() const { return at<20>().as_uint64(); }
+};
+
+class VulkanMemoryEvent : public ::protozero::Message {
+ public:
+  using Decoder = VulkanMemoryEvent_Decoder;
+  enum : int32_t {
+    kSourceFieldNumber = 1,
+    kOperationFieldNumber = 2,
+    kTimestampFieldNumber = 3,
+    kPidFieldNumber = 4,
+    kMemoryAddressFieldNumber = 5,
+    kMemorySizeFieldNumber = 6,
+    kCallerIidFieldNumber = 7,
+    kAllocationScopeFieldNumber = 8,
+    kAnnotationsFieldNumber = 9,
+    kDeviceFieldNumber = 16,
+    kDeviceMemoryFieldNumber = 17,
+    kMemoryTypeFieldNumber = 18,
+    kHeapFieldNumber = 19,
+    kObjectHandleFieldNumber = 20,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanMemoryEvent"; }
+
+
+  using Source = ::perfetto::protos::pbzero::VulkanMemoryEvent_Source;
+  static inline const char* Source_Name(Source value) {
+    return ::perfetto::protos::pbzero::VulkanMemoryEvent_Source_Name(value);
+  }
+
+  using Operation = ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation;
+  static inline const char* Operation_Name(Operation value) {
+    return ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation_Name(value);
+  }
+
+  using AllocationScope = ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope;
+  static inline const char* AllocationScope_Name(AllocationScope value) {
+    return ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope_Name(value);
+  }
+  static inline const Source SOURCE_UNSPECIFIED = Source::SOURCE_UNSPECIFIED;
+  static inline const Source SOURCE_DRIVER = Source::SOURCE_DRIVER;
+  static inline const Source SOURCE_DEVICE = Source::SOURCE_DEVICE;
+  static inline const Source SOURCE_DEVICE_MEMORY = Source::SOURCE_DEVICE_MEMORY;
+  static inline const Source SOURCE_BUFFER = Source::SOURCE_BUFFER;
+  static inline const Source SOURCE_IMAGE = Source::SOURCE_IMAGE;
+  static inline const Operation OP_UNSPECIFIED = Operation::OP_UNSPECIFIED;
+  static inline const Operation OP_CREATE = Operation::OP_CREATE;
+  static inline const Operation OP_DESTROY = Operation::OP_DESTROY;
+  static inline const Operation OP_BIND = Operation::OP_BIND;
+  static inline const Operation OP_DESTROY_BOUND = Operation::OP_DESTROY_BOUND;
+  static inline const Operation OP_ANNOTATIONS = Operation::OP_ANNOTATIONS;
+  static inline const AllocationScope SCOPE_UNSPECIFIED = AllocationScope::SCOPE_UNSPECIFIED;
+  static inline const AllocationScope SCOPE_COMMAND = AllocationScope::SCOPE_COMMAND;
+  static inline const AllocationScope SCOPE_OBJECT = AllocationScope::SCOPE_OBJECT;
+  static inline const AllocationScope SCOPE_CACHE = AllocationScope::SCOPE_CACHE;
+  static inline const AllocationScope SCOPE_DEVICE = AllocationScope::SCOPE_DEVICE;
+  static inline const AllocationScope SCOPE_INSTANCE = AllocationScope::SCOPE_INSTANCE;
+
+  using FieldMetadata_Source =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::VulkanMemoryEvent_Source,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Source kSource{};
+  void set_source(::perfetto::protos::pbzero::VulkanMemoryEvent_Source value) {
+    static constexpr uint32_t field_id = FieldMetadata_Source::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Operation =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::VulkanMemoryEvent_Operation,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Operation kOperation{};
+  void set_operation(::perfetto::protos::pbzero::VulkanMemoryEvent_Operation value) {
+    static constexpr uint32_t field_id = FieldMetadata_Operation::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MemoryAddress =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_MemoryAddress kMemoryAddress{};
+  void set_memory_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MemoryAddress::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MemorySize =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_MemorySize kMemorySize{};
+  void set_memory_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MemorySize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CallerIid =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_CallerIid kCallerIid{};
+  void set_caller_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallerIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllocationScope =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_AllocationScope kAllocationScope{};
+  void set_allocation_scope(::perfetto::protos::pbzero::VulkanMemoryEvent_AllocationScope value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocationScope::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Annotations =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      VulkanMemoryEventAnnotation,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Annotations kAnnotations{};
+  template <typename T = VulkanMemoryEventAnnotation> T* add_annotations() {
+    return BeginNestedMessage<T>(9);
+  }
+
+
+  using FieldMetadata_Device =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Device kDevice{};
+  void set_device(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Device::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeviceMemory =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_DeviceMemory kDeviceMemory{};
+  void set_device_memory(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeviceMemory::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MemoryType =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_MemoryType kMemoryType{};
+  void set_memory_type(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MemoryType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Heap =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_Heap kHeap{};
+  void set_heap(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Heap::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ObjectHandle =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      VulkanMemoryEvent>;
+
+  static constexpr FieldMetadata_ObjectHandle kObjectHandle{};
+  void set_object_handle(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObjectHandle::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class VulkanMemoryEventAnnotation_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  VulkanMemoryEventAnnotation_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit VulkanMemoryEventAnnotation_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit VulkanMemoryEventAnnotation_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key_iid() const { return at<1>().valid(); }
+  uint64_t key_iid() const { return at<1>().as_uint64(); }
+  bool has_int_value() const { return at<2>().valid(); }
+  int64_t int_value() const { return at<2>().as_int64(); }
+  bool has_double_value() const { return at<3>().valid(); }
+  double double_value() const { return at<3>().as_double(); }
+  bool has_string_iid() const { return at<4>().valid(); }
+  uint64_t string_iid() const { return at<4>().as_uint64(); }
+};
+
+class VulkanMemoryEventAnnotation : public ::protozero::Message {
+ public:
+  using Decoder = VulkanMemoryEventAnnotation_Decoder;
+  enum : int32_t {
+    kKeyIidFieldNumber = 1,
+    kIntValueFieldNumber = 2,
+    kDoubleValueFieldNumber = 3,
+    kStringIidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.VulkanMemoryEventAnnotation"; }
+
+
+  using FieldMetadata_KeyIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanMemoryEventAnnotation>;
+
+  static constexpr FieldMetadata_KeyIid kKeyIid{};
+  void set_key_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KeyIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      VulkanMemoryEventAnnotation>;
+
+  static constexpr FieldMetadata_IntValue kIntValue{};
+  void set_int_value(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DoubleValue =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kDouble,
+      double,
+      VulkanMemoryEventAnnotation>;
+
+  static constexpr FieldMetadata_DoubleValue kDoubleValue{};
+  void set_double_value(double value) {
+    static constexpr uint32_t field_id = FieldMetadata_DoubleValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kDouble>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringIid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      VulkanMemoryEventAnnotation>;
+
+  static constexpr FieldMetadata_StringIid kStringIid{};
+  void set_string_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/profiling/deobfuscation.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_DEOBFUSCATION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_DEOBFUSCATION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ObfuscatedClass;
+class ObfuscatedMember;
+
+class DeobfuscationMapping_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  DeobfuscationMapping_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit DeobfuscationMapping_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit DeobfuscationMapping_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_package_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars package_name() const { return at<1>().as_string(); }
+  bool has_version_code() const { return at<2>().valid(); }
+  int64_t version_code() const { return at<2>().as_int64(); }
+  bool has_obfuscated_classes() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> obfuscated_classes() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class DeobfuscationMapping : public ::protozero::Message {
+ public:
+  using Decoder = DeobfuscationMapping_Decoder;
+  enum : int32_t {
+    kPackageNameFieldNumber = 1,
+    kVersionCodeFieldNumber = 2,
+    kObfuscatedClassesFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.DeobfuscationMapping"; }
+
+
+  using FieldMetadata_PackageName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      DeobfuscationMapping>;
+
+  static constexpr FieldMetadata_PackageName kPackageName{};
+  void set_package_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_PackageName::kFieldId, data, size);
+  }
+  void set_package_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_PackageName::kFieldId, chars.data, chars.size);
+  }
+  void set_package_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_PackageName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VersionCode =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      DeobfuscationMapping>;
+
+  static constexpr FieldMetadata_VersionCode kVersionCode{};
+  void set_version_code(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VersionCode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ObfuscatedClasses =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ObfuscatedClass,
+      DeobfuscationMapping>;
+
+  static constexpr FieldMetadata_ObfuscatedClasses kObfuscatedClasses{};
+  template <typename T = ObfuscatedClass> T* add_obfuscated_classes() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class ObfuscatedClass_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ObfuscatedClass_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ObfuscatedClass_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ObfuscatedClass_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_obfuscated_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars obfuscated_name() const { return at<1>().as_string(); }
+  bool has_deobfuscated_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars deobfuscated_name() const { return at<2>().as_string(); }
+  bool has_obfuscated_members() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> obfuscated_members() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_obfuscated_methods() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> obfuscated_methods() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class ObfuscatedClass : public ::protozero::Message {
+ public:
+  using Decoder = ObfuscatedClass_Decoder;
+  enum : int32_t {
+    kObfuscatedNameFieldNumber = 1,
+    kDeobfuscatedNameFieldNumber = 2,
+    kObfuscatedMembersFieldNumber = 3,
+    kObfuscatedMethodsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ObfuscatedClass"; }
+
+
+  using FieldMetadata_ObfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedClass>;
+
+  static constexpr FieldMetadata_ObfuscatedName kObfuscatedName{};
+  void set_obfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, data, size);
+  }
+  void set_obfuscated_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, chars.data, chars.size);
+  }
+  void set_obfuscated_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObfuscatedName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeobfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedClass>;
+
+  static constexpr FieldMetadata_DeobfuscatedName kDeobfuscatedName{};
+  void set_deobfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, data, size);
+  }
+  void set_deobfuscated_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, chars.data, chars.size);
+  }
+  void set_deobfuscated_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeobfuscatedName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ObfuscatedMembers =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ObfuscatedMember,
+      ObfuscatedClass>;
+
+  static constexpr FieldMetadata_ObfuscatedMembers kObfuscatedMembers{};
+  template <typename T = ObfuscatedMember> T* add_obfuscated_members() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ObfuscatedMethods =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ObfuscatedMember,
+      ObfuscatedClass>;
+
+  static constexpr FieldMetadata_ObfuscatedMethods kObfuscatedMethods{};
+  template <typename T = ObfuscatedMember> T* add_obfuscated_methods() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class ObfuscatedMember_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ObfuscatedMember_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ObfuscatedMember_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ObfuscatedMember_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_obfuscated_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars obfuscated_name() const { return at<1>().as_string(); }
+  bool has_deobfuscated_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars deobfuscated_name() const { return at<2>().as_string(); }
+};
+
+class ObfuscatedMember : public ::protozero::Message {
+ public:
+  using Decoder = ObfuscatedMember_Decoder;
+  enum : int32_t {
+    kObfuscatedNameFieldNumber = 1,
+    kDeobfuscatedNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ObfuscatedMember"; }
+
+
+  using FieldMetadata_ObfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedMember>;
+
+  static constexpr FieldMetadata_ObfuscatedName kObfuscatedName{};
+  void set_obfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, data, size);
+  }
+  void set_obfuscated_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ObfuscatedName::kFieldId, chars.data, chars.size);
+  }
+  void set_obfuscated_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObfuscatedName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeobfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ObfuscatedMember>;
+
+  static constexpr FieldMetadata_DeobfuscatedName kDeobfuscatedName{};
+  void set_deobfuscated_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, data, size);
+  }
+  void set_deobfuscated_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DeobfuscatedName::kFieldId, chars.data, chars.size);
+  }
+  void set_deobfuscated_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeobfuscatedName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/profiling/heap_graph.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_HEAP_GRAPH_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_HEAP_GRAPH_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/profiling/deobfuscation.pbzero.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class HeapGraphObject;
+class HeapGraphRoot;
+class HeapGraphType;
+class InternedString;
+namespace perfetto_pbzero_enum_HeapGraphRoot {
+enum Type : int32_t;
+}  // namespace perfetto_pbzero_enum_HeapGraphRoot
+using HeapGraphRoot_Type = perfetto_pbzero_enum_HeapGraphRoot::Type;
+namespace perfetto_pbzero_enum_HeapGraphType {
+enum Kind : int32_t;
+}  // namespace perfetto_pbzero_enum_HeapGraphType
+using HeapGraphType_Kind = perfetto_pbzero_enum_HeapGraphType::Kind;
+
+namespace perfetto_pbzero_enum_HeapGraphType {
+enum Kind : int32_t {
+  KIND_UNKNOWN = 0,
+  KIND_NORMAL = 1,
+  KIND_NOREFERENCES = 2,
+  KIND_STRING = 3,
+  KIND_ARRAY = 4,
+  KIND_CLASS = 5,
+  KIND_CLASSLOADER = 6,
+  KIND_DEXCACHE = 7,
+  KIND_SOFT_REFERENCE = 8,
+  KIND_WEAK_REFERENCE = 9,
+  KIND_FINALIZER_REFERENCE = 10,
+  KIND_PHANTOM_REFERENCE = 11,
+};
+} // namespace perfetto_pbzero_enum_HeapGraphType
+using HeapGraphType_Kind = perfetto_pbzero_enum_HeapGraphType::Kind;
+
+
+constexpr HeapGraphType_Kind HeapGraphType_Kind_MIN = HeapGraphType_Kind::KIND_UNKNOWN;
+constexpr HeapGraphType_Kind HeapGraphType_Kind_MAX = HeapGraphType_Kind::KIND_PHANTOM_REFERENCE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* HeapGraphType_Kind_Name(::perfetto::protos::pbzero::HeapGraphType_Kind value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_UNKNOWN:
+    return "KIND_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_NORMAL:
+    return "KIND_NORMAL";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_NOREFERENCES:
+    return "KIND_NOREFERENCES";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_STRING:
+    return "KIND_STRING";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_ARRAY:
+    return "KIND_ARRAY";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_CLASS:
+    return "KIND_CLASS";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_CLASSLOADER:
+    return "KIND_CLASSLOADER";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_DEXCACHE:
+    return "KIND_DEXCACHE";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_SOFT_REFERENCE:
+    return "KIND_SOFT_REFERENCE";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_WEAK_REFERENCE:
+    return "KIND_WEAK_REFERENCE";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_FINALIZER_REFERENCE:
+    return "KIND_FINALIZER_REFERENCE";
+
+  case ::perfetto::protos::pbzero::HeapGraphType_Kind::KIND_PHANTOM_REFERENCE:
+    return "KIND_PHANTOM_REFERENCE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_HeapGraphRoot {
+enum Type : int32_t {
+  ROOT_UNKNOWN = 0,
+  ROOT_JNI_GLOBAL = 1,
+  ROOT_JNI_LOCAL = 2,
+  ROOT_JAVA_FRAME = 3,
+  ROOT_NATIVE_STACK = 4,
+  ROOT_STICKY_CLASS = 5,
+  ROOT_THREAD_BLOCK = 6,
+  ROOT_MONITOR_USED = 7,
+  ROOT_THREAD_OBJECT = 8,
+  ROOT_INTERNED_STRING = 9,
+  ROOT_FINALIZING = 10,
+  ROOT_DEBUGGER = 11,
+  ROOT_REFERENCE_CLEANUP = 12,
+  ROOT_VM_INTERNAL = 13,
+  ROOT_JNI_MONITOR = 14,
+};
+} // namespace perfetto_pbzero_enum_HeapGraphRoot
+using HeapGraphRoot_Type = perfetto_pbzero_enum_HeapGraphRoot::Type;
+
+
+constexpr HeapGraphRoot_Type HeapGraphRoot_Type_MIN = HeapGraphRoot_Type::ROOT_UNKNOWN;
+constexpr HeapGraphRoot_Type HeapGraphRoot_Type_MAX = HeapGraphRoot_Type::ROOT_JNI_MONITOR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* HeapGraphRoot_Type_Name(::perfetto::protos::pbzero::HeapGraphRoot_Type value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_UNKNOWN:
+    return "ROOT_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_JNI_GLOBAL:
+    return "ROOT_JNI_GLOBAL";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_JNI_LOCAL:
+    return "ROOT_JNI_LOCAL";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_JAVA_FRAME:
+    return "ROOT_JAVA_FRAME";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_NATIVE_STACK:
+    return "ROOT_NATIVE_STACK";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_STICKY_CLASS:
+    return "ROOT_STICKY_CLASS";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_THREAD_BLOCK:
+    return "ROOT_THREAD_BLOCK";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_MONITOR_USED:
+    return "ROOT_MONITOR_USED";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_THREAD_OBJECT:
+    return "ROOT_THREAD_OBJECT";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_INTERNED_STRING:
+    return "ROOT_INTERNED_STRING";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_FINALIZING:
+    return "ROOT_FINALIZING";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_DEBUGGER:
+    return "ROOT_DEBUGGER";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_REFERENCE_CLEANUP:
+    return "ROOT_REFERENCE_CLEANUP";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_VM_INTERNAL:
+    return "ROOT_VM_INTERNAL";
+
+  case ::perfetto::protos::pbzero::HeapGraphRoot_Type::ROOT_JNI_MONITOR:
+    return "ROOT_JNI_MONITOR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class HeapGraph_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  HeapGraph_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapGraph_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapGraph_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_objects() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> objects() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_roots() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> roots() const { return GetRepeated<::protozero::ConstBytes>(7); }
+  bool has_types() const { return at<9>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> types() const { return GetRepeated<::protozero::ConstBytes>(9); }
+  bool has_field_names() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> field_names() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_location_names() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> location_names() const { return GetRepeated<::protozero::ConstBytes>(8); }
+  bool has_continued() const { return at<5>().valid(); }
+  bool continued() const { return at<5>().as_bool(); }
+  bool has_index() const { return at<6>().valid(); }
+  uint64_t index() const { return at<6>().as_uint64(); }
+};
+
+class HeapGraph : public ::protozero::Message {
+ public:
+  using Decoder = HeapGraph_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kObjectsFieldNumber = 2,
+    kRootsFieldNumber = 7,
+    kTypesFieldNumber = 9,
+    kFieldNamesFieldNumber = 4,
+    kLocationNamesFieldNumber = 8,
+    kContinuedFieldNumber = 5,
+    kIndexFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapGraph"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Objects =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapGraphObject,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Objects kObjects{};
+  template <typename T = HeapGraphObject> T* add_objects() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_Roots =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapGraphRoot,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Roots kRoots{};
+  template <typename T = HeapGraphRoot> T* add_roots() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_Types =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      HeapGraphType,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Types kTypes{};
+  template <typename T = HeapGraphType> T* add_types() {
+    return BeginNestedMessage<T>(9);
+  }
+
+
+  using FieldMetadata_FieldNames =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_FieldNames kFieldNames{};
+  template <typename T = InternedString> T* add_field_names() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_LocationNames =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_LocationNames kLocationNames{};
+  template <typename T = InternedString> T* add_location_names() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_Continued =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Continued kContinued{};
+  void set_continued(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Continued::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraph>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class HeapGraphObject_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HeapGraphObject_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapGraphObject_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapGraphObject_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_id_delta() const { return at<7>().valid(); }
+  uint64_t id_delta() const { return at<7>().as_uint64(); }
+  bool has_type_id() const { return at<2>().valid(); }
+  uint64_t type_id() const { return at<2>().as_uint64(); }
+  bool has_self_size() const { return at<3>().valid(); }
+  uint64_t self_size() const { return at<3>().as_uint64(); }
+  bool has_reference_field_id_base() const { return at<6>().valid(); }
+  uint64_t reference_field_id_base() const { return at<6>().as_uint64(); }
+  bool has_reference_field_id() const { return at<4>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> reference_field_id(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(4, parse_error_ptr); }
+  bool has_reference_object_id() const { return at<5>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> reference_object_id(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(5, parse_error_ptr); }
+  bool has_native_allocation_registry_size_field() const { return at<8>().valid(); }
+  int64_t native_allocation_registry_size_field() const { return at<8>().as_int64(); }
+};
+
+class HeapGraphObject : public ::protozero::Message {
+ public:
+  using Decoder = HeapGraphObject_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kIdDeltaFieldNumber = 7,
+    kTypeIdFieldNumber = 2,
+    kSelfSizeFieldNumber = 3,
+    kReferenceFieldIdBaseFieldNumber = 6,
+    kReferenceFieldIdFieldNumber = 4,
+    kReferenceObjectIdFieldNumber = 5,
+    kNativeAllocationRegistrySizeFieldFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapGraphObject"; }
+
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IdDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_IdDelta kIdDelta{};
+  void set_id_delta(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IdDelta::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TypeId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_TypeId kTypeId{};
+  void set_type_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TypeId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SelfSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_SelfSize kSelfSize{};
+  void set_self_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelfSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReferenceFieldIdBase =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_ReferenceFieldIdBase kReferenceFieldIdBase{};
+  void set_reference_field_id_base(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReferenceFieldIdBase::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReferenceFieldId =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_ReferenceFieldId kReferenceFieldId{};
+  void set_reference_field_id(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ReferenceFieldId::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_ReferenceObjectId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_ReferenceObjectId kReferenceObjectId{};
+  void set_reference_object_id(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ReferenceObjectId::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_NativeAllocationRegistrySizeField =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      HeapGraphObject>;
+
+  static constexpr FieldMetadata_NativeAllocationRegistrySizeField kNativeAllocationRegistrySizeField{};
+  void set_native_allocation_registry_size_field(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NativeAllocationRegistrySizeField::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class HeapGraphType_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HeapGraphType_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapGraphType_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapGraphType_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_location_id() const { return at<2>().valid(); }
+  uint64_t location_id() const { return at<2>().as_uint64(); }
+  bool has_class_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars class_name() const { return at<3>().as_string(); }
+  bool has_object_size() const { return at<4>().valid(); }
+  uint64_t object_size() const { return at<4>().as_uint64(); }
+  bool has_superclass_id() const { return at<5>().valid(); }
+  uint64_t superclass_id() const { return at<5>().as_uint64(); }
+  bool has_reference_field_id() const { return at<6>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> reference_field_id(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(6, parse_error_ptr); }
+  bool has_kind() const { return at<7>().valid(); }
+  int32_t kind() const { return at<7>().as_int32(); }
+  bool has_classloader_id() const { return at<8>().valid(); }
+  uint64_t classloader_id() const { return at<8>().as_uint64(); }
+};
+
+class HeapGraphType : public ::protozero::Message {
+ public:
+  using Decoder = HeapGraphType_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kLocationIdFieldNumber = 2,
+    kClassNameFieldNumber = 3,
+    kObjectSizeFieldNumber = 4,
+    kSuperclassIdFieldNumber = 5,
+    kReferenceFieldIdFieldNumber = 6,
+    kKindFieldNumber = 7,
+    kClassloaderIdFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapGraphType"; }
+
+
+  using Kind = ::perfetto::protos::pbzero::HeapGraphType_Kind;
+  static inline const char* Kind_Name(Kind value) {
+    return ::perfetto::protos::pbzero::HeapGraphType_Kind_Name(value);
+  }
+  static inline const Kind KIND_UNKNOWN = Kind::KIND_UNKNOWN;
+  static inline const Kind KIND_NORMAL = Kind::KIND_NORMAL;
+  static inline const Kind KIND_NOREFERENCES = Kind::KIND_NOREFERENCES;
+  static inline const Kind KIND_STRING = Kind::KIND_STRING;
+  static inline const Kind KIND_ARRAY = Kind::KIND_ARRAY;
+  static inline const Kind KIND_CLASS = Kind::KIND_CLASS;
+  static inline const Kind KIND_CLASSLOADER = Kind::KIND_CLASSLOADER;
+  static inline const Kind KIND_DEXCACHE = Kind::KIND_DEXCACHE;
+  static inline const Kind KIND_SOFT_REFERENCE = Kind::KIND_SOFT_REFERENCE;
+  static inline const Kind KIND_WEAK_REFERENCE = Kind::KIND_WEAK_REFERENCE;
+  static inline const Kind KIND_FINALIZER_REFERENCE = Kind::KIND_FINALIZER_REFERENCE;
+  static inline const Kind KIND_PHANTOM_REFERENCE = Kind::KIND_PHANTOM_REFERENCE;
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LocationId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_LocationId kLocationId{};
+  void set_location_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LocationId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ClassName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_ClassName kClassName{};
+  void set_class_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ClassName::kFieldId, data, size);
+  }
+  void set_class_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ClassName::kFieldId, chars.data, chars.size);
+  }
+  void set_class_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClassName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ObjectSize =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_ObjectSize kObjectSize{};
+  void set_object_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObjectSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SuperclassId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_SuperclassId kSuperclassId{};
+  void set_superclass_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SuperclassId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReferenceFieldId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_ReferenceFieldId kReferenceFieldId{};
+  void set_reference_field_id(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ReferenceFieldId::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_Kind =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::HeapGraphType_Kind,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_Kind kKind{};
+  void set_kind(::perfetto::protos::pbzero::HeapGraphType_Kind value) {
+    static constexpr uint32_t field_id = FieldMetadata_Kind::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ClassloaderId =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphType>;
+
+  static constexpr FieldMetadata_ClassloaderId kClassloaderId{};
+  void set_classloader_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClassloaderId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class HeapGraphRoot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HeapGraphRoot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HeapGraphRoot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HeapGraphRoot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_object_ids() const { return at<1>().valid(); }
+  ::protozero::PackedRepeatedFieldIterator<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t> object_ids(bool* parse_error_ptr) const { return GetPackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(1, parse_error_ptr); }
+  bool has_root_type() const { return at<2>().valid(); }
+  int32_t root_type() const { return at<2>().as_int32(); }
+};
+
+class HeapGraphRoot : public ::protozero::Message {
+ public:
+  using Decoder = HeapGraphRoot_Decoder;
+  enum : int32_t {
+    kObjectIdsFieldNumber = 1,
+    kRootTypeFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HeapGraphRoot"; }
+
+
+  using Type = ::perfetto::protos::pbzero::HeapGraphRoot_Type;
+  static inline const char* Type_Name(Type value) {
+    return ::perfetto::protos::pbzero::HeapGraphRoot_Type_Name(value);
+  }
+  static inline const Type ROOT_UNKNOWN = Type::ROOT_UNKNOWN;
+  static inline const Type ROOT_JNI_GLOBAL = Type::ROOT_JNI_GLOBAL;
+  static inline const Type ROOT_JNI_LOCAL = Type::ROOT_JNI_LOCAL;
+  static inline const Type ROOT_JAVA_FRAME = Type::ROOT_JAVA_FRAME;
+  static inline const Type ROOT_NATIVE_STACK = Type::ROOT_NATIVE_STACK;
+  static inline const Type ROOT_STICKY_CLASS = Type::ROOT_STICKY_CLASS;
+  static inline const Type ROOT_THREAD_BLOCK = Type::ROOT_THREAD_BLOCK;
+  static inline const Type ROOT_MONITOR_USED = Type::ROOT_MONITOR_USED;
+  static inline const Type ROOT_THREAD_OBJECT = Type::ROOT_THREAD_OBJECT;
+  static inline const Type ROOT_INTERNED_STRING = Type::ROOT_INTERNED_STRING;
+  static inline const Type ROOT_FINALIZING = Type::ROOT_FINALIZING;
+  static inline const Type ROOT_DEBUGGER = Type::ROOT_DEBUGGER;
+  static inline const Type ROOT_REFERENCE_CLEANUP = Type::ROOT_REFERENCE_CLEANUP;
+  static inline const Type ROOT_VM_INTERNAL = Type::ROOT_VM_INTERNAL;
+  static inline const Type ROOT_JNI_MONITOR = Type::ROOT_JNI_MONITOR;
+
+  using FieldMetadata_ObjectIds =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HeapGraphRoot>;
+
+  static constexpr FieldMetadata_ObjectIds kObjectIds{};
+  void set_object_ids(const ::protozero::PackedVarInt& packed_buffer) {
+    AppendBytes(FieldMetadata_ObjectIds::kFieldId, packed_buffer.data(),
+                packed_buffer.size());
+  }
+
+  using FieldMetadata_RootType =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::HeapGraphRoot_Type,
+      HeapGraphRoot>;
+
+  static constexpr FieldMetadata_RootType kRootType{};
+  void set_root_type(::perfetto::protos::pbzero::HeapGraphRoot_Type value) {
+    static constexpr uint32_t field_id = FieldMetadata_RootType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/profiling/profile_common.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_PROFILE_COMMON_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_PROFILE_COMMON_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AddressSymbols;
+class Line;
+
+class Callstack_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  Callstack_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Callstack_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Callstack_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_frame_ids() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> frame_ids() const { return GetRepeated<uint64_t>(2); }
+};
+
+class Callstack : public ::protozero::Message {
+ public:
+  using Decoder = Callstack_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kFrameIdsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Callstack"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Callstack>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameIds =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Callstack>;
+
+  static constexpr FieldMetadata_FrameIds kFrameIds{};
+  void add_frame_ids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Frame_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Frame_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Frame_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Frame_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_function_name_id() const { return at<2>().valid(); }
+  uint64_t function_name_id() const { return at<2>().as_uint64(); }
+  bool has_mapping_id() const { return at<3>().valid(); }
+  uint64_t mapping_id() const { return at<3>().as_uint64(); }
+  bool has_rel_pc() const { return at<4>().valid(); }
+  uint64_t rel_pc() const { return at<4>().as_uint64(); }
+};
+
+class Frame : public ::protozero::Message {
+ public:
+  using Decoder = Frame_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kFunctionNameIdFieldNumber = 2,
+    kMappingIdFieldNumber = 3,
+    kRelPcFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Frame"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Frame>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FunctionNameId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Frame>;
+
+  static constexpr FieldMetadata_FunctionNameId kFunctionNameId{};
+  void set_function_name_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionNameId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MappingId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Frame>;
+
+  static constexpr FieldMetadata_MappingId kMappingId{};
+  void set_mapping_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MappingId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RelPc =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Frame>;
+
+  static constexpr FieldMetadata_RelPc kRelPc{};
+  void set_rel_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RelPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Mapping_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  Mapping_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Mapping_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Mapping_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_build_id() const { return at<2>().valid(); }
+  uint64_t build_id() const { return at<2>().as_uint64(); }
+  bool has_exact_offset() const { return at<8>().valid(); }
+  uint64_t exact_offset() const { return at<8>().as_uint64(); }
+  bool has_start_offset() const { return at<3>().valid(); }
+  uint64_t start_offset() const { return at<3>().as_uint64(); }
+  bool has_start() const { return at<4>().valid(); }
+  uint64_t start() const { return at<4>().as_uint64(); }
+  bool has_end() const { return at<5>().valid(); }
+  uint64_t end() const { return at<5>().as_uint64(); }
+  bool has_load_bias() const { return at<6>().valid(); }
+  uint64_t load_bias() const { return at<6>().as_uint64(); }
+  bool has_path_string_ids() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> path_string_ids() const { return GetRepeated<uint64_t>(7); }
+};
+
+class Mapping : public ::protozero::Message {
+ public:
+  using Decoder = Mapping_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kBuildIdFieldNumber = 2,
+    kExactOffsetFieldNumber = 8,
+    kStartOffsetFieldNumber = 3,
+    kStartFieldNumber = 4,
+    kEndFieldNumber = 5,
+    kLoadBiasFieldNumber = 6,
+    kPathStringIdsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Mapping"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BuildId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_BuildId kBuildId{};
+  void set_build_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BuildId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ExactOffset =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_ExactOffset kExactOffset{};
+  void set_exact_offset(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ExactOffset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartOffset =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_StartOffset kStartOffset{};
+  void set_start_offset(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartOffset::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Start =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_Start kStart{};
+  void set_start(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Start::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_End =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_End kEnd{};
+  void set_end(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_End::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LoadBias =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_LoadBias kLoadBias{};
+  void set_load_bias(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LoadBias::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PathStringIds =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      Mapping>;
+
+  static constexpr FieldMetadata_PathStringIds kPathStringIds{};
+  void add_path_string_ids(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PathStringIds::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ModuleSymbols_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ModuleSymbols_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ModuleSymbols_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ModuleSymbols_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_path() const { return at<1>().valid(); }
+  ::protozero::ConstChars path() const { return at<1>().as_string(); }
+  bool has_build_id() const { return at<2>().valid(); }
+  ::protozero::ConstChars build_id() const { return at<2>().as_string(); }
+  bool has_address_symbols() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> address_symbols() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class ModuleSymbols : public ::protozero::Message {
+ public:
+  using Decoder = ModuleSymbols_Decoder;
+  enum : int32_t {
+    kPathFieldNumber = 1,
+    kBuildIdFieldNumber = 2,
+    kAddressSymbolsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ModuleSymbols"; }
+
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ModuleSymbols>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BuildId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ModuleSymbols>;
+
+  static constexpr FieldMetadata_BuildId kBuildId{};
+  void set_build_id(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_BuildId::kFieldId, data, size);
+  }
+  void set_build_id(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_BuildId::kFieldId, chars.data, chars.size);
+  }
+  void set_build_id(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_BuildId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AddressSymbols =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AddressSymbols,
+      ModuleSymbols>;
+
+  static constexpr FieldMetadata_AddressSymbols kAddressSymbols{};
+  template <typename T = AddressSymbols> T* add_address_symbols() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class AddressSymbols_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AddressSymbols_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AddressSymbols_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AddressSymbols_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_address() const { return at<1>().valid(); }
+  uint64_t address() const { return at<1>().as_uint64(); }
+  bool has_lines() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> lines() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class AddressSymbols : public ::protozero::Message {
+ public:
+  using Decoder = AddressSymbols_Decoder;
+  enum : int32_t {
+    kAddressFieldNumber = 1,
+    kLinesFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AddressSymbols"; }
+
+
+  using FieldMetadata_Address =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      AddressSymbols>;
+
+  static constexpr FieldMetadata_Address kAddress{};
+  void set_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Address::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Lines =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Line,
+      AddressSymbols>;
+
+  static constexpr FieldMetadata_Lines kLines{};
+  template <typename T = Line> T* add_lines() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class Line_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Line_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Line_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Line_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_function_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars function_name() const { return at<1>().as_string(); }
+  bool has_source_file_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars source_file_name() const { return at<2>().as_string(); }
+  bool has_line_number() const { return at<3>().valid(); }
+  uint32_t line_number() const { return at<3>().as_uint32(); }
+};
+
+class Line : public ::protozero::Message {
+ public:
+  using Decoder = Line_Decoder;
+  enum : int32_t {
+    kFunctionNameFieldNumber = 1,
+    kSourceFileNameFieldNumber = 2,
+    kLineNumberFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Line"; }
+
+
+  using FieldMetadata_FunctionName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Line>;
+
+  static constexpr FieldMetadata_FunctionName kFunctionName{};
+  void set_function_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, data, size);
+  }
+  void set_function_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, chars.data, chars.size);
+  }
+  void set_function_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SourceFileName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      Line>;
+
+  static constexpr FieldMetadata_SourceFileName kSourceFileName{};
+  void set_source_file_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SourceFileName::kFieldId, data, size);
+  }
+  void set_source_file_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SourceFileName::kFieldId, chars.data, chars.size);
+  }
+  void set_source_file_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceFileName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LineNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      Line>;
+
+  static constexpr FieldMetadata_LineNumber kLineNumber{};
+  void set_line_number(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LineNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ProfiledFrameSymbols_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProfiledFrameSymbols_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfiledFrameSymbols_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfiledFrameSymbols_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_frame_iid() const { return at<1>().valid(); }
+  uint64_t frame_iid() const { return at<1>().as_uint64(); }
+  bool has_function_name_id() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> function_name_id() const { return GetRepeated<uint64_t>(2); }
+  bool has_file_name_id() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> file_name_id() const { return GetRepeated<uint64_t>(3); }
+  bool has_line_number() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> line_number() const { return GetRepeated<uint32_t>(4); }
+};
+
+class ProfiledFrameSymbols : public ::protozero::Message {
+ public:
+  using Decoder = ProfiledFrameSymbols_Decoder;
+  enum : int32_t {
+    kFrameIidFieldNumber = 1,
+    kFunctionNameIdFieldNumber = 2,
+    kFileNameIdFieldNumber = 3,
+    kLineNumberFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfiledFrameSymbols"; }
+
+
+  using FieldMetadata_FrameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfiledFrameSymbols>;
+
+  static constexpr FieldMetadata_FrameIid kFrameIid{};
+  void set_frame_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FunctionNameId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfiledFrameSymbols>;
+
+  static constexpr FieldMetadata_FunctionNameId kFunctionNameId{};
+  void add_function_name_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionNameId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FileNameId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfiledFrameSymbols>;
+
+  static constexpr FieldMetadata_FileNameId kFileNameId{};
+  void add_file_name_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FileNameId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LineNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProfiledFrameSymbols>;
+
+  static constexpr FieldMetadata_LineNumber kLineNumber{};
+  void add_line_number(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LineNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class InternedString_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  InternedString_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit InternedString_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit InternedString_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_str() const { return at<2>().valid(); }
+  ::protozero::ConstBytes str() const { return at<2>().as_bytes(); }
+};
+
+class InternedString : public ::protozero::Message {
+ public:
+  using Decoder = InternedString_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kStrFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.InternedString"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      InternedString>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Str =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      InternedString>;
+
+  static constexpr FieldMetadata_Str kStr{};
+  void set_str(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, size);
+  }
+  void set_str(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_Str::kFieldId, bytes.data, bytes.size);
+  }
+  void set_str(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Str::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/profiling/profile_packet.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_PROFILE_PACKET_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_PROFILE_PACKET_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class Callstack;
+class Frame;
+class InternedString;
+class Mapping;
+class PerfEvents_Timebase;
+class PerfSample_ProducerEvent;
+class ProfilePacket_HeapSample;
+class ProfilePacket_Histogram;
+class ProfilePacket_Histogram_Bucket;
+class ProfilePacket_ProcessHeapSamples;
+class ProfilePacket_ProcessStats;
+namespace perfetto_pbzero_enum_PerfSample_ProducerEvent {
+enum DataSourceStopReason : int32_t;
+}  // namespace perfetto_pbzero_enum_PerfSample_ProducerEvent
+using PerfSample_ProducerEvent_DataSourceStopReason = perfetto_pbzero_enum_PerfSample_ProducerEvent::DataSourceStopReason;
+namespace perfetto_pbzero_enum_PerfSample {
+enum SampleSkipReason : int32_t;
+}  // namespace perfetto_pbzero_enum_PerfSample
+using PerfSample_SampleSkipReason = perfetto_pbzero_enum_PerfSample::SampleSkipReason;
+namespace perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples {
+enum ClientError : int32_t;
+}  // namespace perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples
+using ProfilePacket_ProcessHeapSamples_ClientError = perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples::ClientError;
+namespace perfetto_pbzero_enum_Profiling {
+enum CpuMode : int32_t;
+}  // namespace perfetto_pbzero_enum_Profiling
+using Profiling_CpuMode = perfetto_pbzero_enum_Profiling::CpuMode;
+namespace perfetto_pbzero_enum_Profiling {
+enum StackUnwindError : int32_t;
+}  // namespace perfetto_pbzero_enum_Profiling
+using Profiling_StackUnwindError = perfetto_pbzero_enum_Profiling::StackUnwindError;
+
+namespace perfetto_pbzero_enum_PerfSample {
+enum SampleSkipReason : int32_t {
+  PROFILER_SKIP_UNKNOWN = 0,
+  PROFILER_SKIP_READ_STAGE = 1,
+  PROFILER_SKIP_UNWIND_STAGE = 2,
+  PROFILER_SKIP_UNWIND_ENQUEUE = 3,
+};
+} // namespace perfetto_pbzero_enum_PerfSample
+using PerfSample_SampleSkipReason = perfetto_pbzero_enum_PerfSample::SampleSkipReason;
+
+
+constexpr PerfSample_SampleSkipReason PerfSample_SampleSkipReason_MIN = PerfSample_SampleSkipReason::PROFILER_SKIP_UNKNOWN;
+constexpr PerfSample_SampleSkipReason PerfSample_SampleSkipReason_MAX = PerfSample_SampleSkipReason::PROFILER_SKIP_UNWIND_ENQUEUE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PerfSample_SampleSkipReason_Name(::perfetto::protos::pbzero::PerfSample_SampleSkipReason value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PerfSample_SampleSkipReason::PROFILER_SKIP_UNKNOWN:
+    return "PROFILER_SKIP_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::PerfSample_SampleSkipReason::PROFILER_SKIP_READ_STAGE:
+    return "PROFILER_SKIP_READ_STAGE";
+
+  case ::perfetto::protos::pbzero::PerfSample_SampleSkipReason::PROFILER_SKIP_UNWIND_STAGE:
+    return "PROFILER_SKIP_UNWIND_STAGE";
+
+  case ::perfetto::protos::pbzero::PerfSample_SampleSkipReason::PROFILER_SKIP_UNWIND_ENQUEUE:
+    return "PROFILER_SKIP_UNWIND_ENQUEUE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_PerfSample_ProducerEvent {
+enum DataSourceStopReason : int32_t {
+  PROFILER_STOP_UNKNOWN = 0,
+  PROFILER_STOP_GUARDRAIL = 1,
+};
+} // namespace perfetto_pbzero_enum_PerfSample_ProducerEvent
+using PerfSample_ProducerEvent_DataSourceStopReason = perfetto_pbzero_enum_PerfSample_ProducerEvent::DataSourceStopReason;
+
+
+constexpr PerfSample_ProducerEvent_DataSourceStopReason PerfSample_ProducerEvent_DataSourceStopReason_MIN = PerfSample_ProducerEvent_DataSourceStopReason::PROFILER_STOP_UNKNOWN;
+constexpr PerfSample_ProducerEvent_DataSourceStopReason PerfSample_ProducerEvent_DataSourceStopReason_MAX = PerfSample_ProducerEvent_DataSourceStopReason::PROFILER_STOP_GUARDRAIL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* PerfSample_ProducerEvent_DataSourceStopReason_Name(::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason::PROFILER_STOP_UNKNOWN:
+    return "PROFILER_STOP_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason::PROFILER_STOP_GUARDRAIL:
+    return "PROFILER_STOP_GUARDRAIL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_Profiling {
+enum CpuMode : int32_t {
+  MODE_UNKNOWN = 0,
+  MODE_KERNEL = 1,
+  MODE_USER = 2,
+  MODE_HYPERVISOR = 3,
+  MODE_GUEST_KERNEL = 4,
+  MODE_GUEST_USER = 5,
+};
+} // namespace perfetto_pbzero_enum_Profiling
+using Profiling_CpuMode = perfetto_pbzero_enum_Profiling::CpuMode;
+
+
+constexpr Profiling_CpuMode Profiling_CpuMode_MIN = Profiling_CpuMode::MODE_UNKNOWN;
+constexpr Profiling_CpuMode Profiling_CpuMode_MAX = Profiling_CpuMode::MODE_GUEST_USER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* Profiling_CpuMode_Name(::perfetto::protos::pbzero::Profiling_CpuMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_UNKNOWN:
+    return "MODE_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_KERNEL:
+    return "MODE_KERNEL";
+
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_USER:
+    return "MODE_USER";
+
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_HYPERVISOR:
+    return "MODE_HYPERVISOR";
+
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_GUEST_KERNEL:
+    return "MODE_GUEST_KERNEL";
+
+  case ::perfetto::protos::pbzero::Profiling_CpuMode::MODE_GUEST_USER:
+    return "MODE_GUEST_USER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_Profiling {
+enum StackUnwindError : int32_t {
+  UNWIND_ERROR_UNKNOWN = 0,
+  UNWIND_ERROR_NONE = 1,
+  UNWIND_ERROR_MEMORY_INVALID = 2,
+  UNWIND_ERROR_UNWIND_INFO = 3,
+  UNWIND_ERROR_UNSUPPORTED = 4,
+  UNWIND_ERROR_INVALID_MAP = 5,
+  UNWIND_ERROR_MAX_FRAMES_EXCEEDED = 6,
+  UNWIND_ERROR_REPEATED_FRAME = 7,
+  UNWIND_ERROR_INVALID_ELF = 8,
+  UNWIND_ERROR_SYSTEM_CALL = 9,
+  UNWIND_ERROR_THREAD_TIMEOUT = 10,
+  UNWIND_ERROR_THREAD_DOES_NOT_EXIST = 11,
+  UNWIND_ERROR_BAD_ARCH = 12,
+  UNWIND_ERROR_MAPS_PARSE = 13,
+  UNWIND_ERROR_INVALID_PARAMETER = 14,
+  UNWIND_ERROR_PTRACE_CALL = 15,
+};
+} // namespace perfetto_pbzero_enum_Profiling
+using Profiling_StackUnwindError = perfetto_pbzero_enum_Profiling::StackUnwindError;
+
+
+constexpr Profiling_StackUnwindError Profiling_StackUnwindError_MIN = Profiling_StackUnwindError::UNWIND_ERROR_UNKNOWN;
+constexpr Profiling_StackUnwindError Profiling_StackUnwindError_MAX = Profiling_StackUnwindError::UNWIND_ERROR_PTRACE_CALL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* Profiling_StackUnwindError_Name(::perfetto::protos::pbzero::Profiling_StackUnwindError value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_UNKNOWN:
+    return "UNWIND_ERROR_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_NONE:
+    return "UNWIND_ERROR_NONE";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_MEMORY_INVALID:
+    return "UNWIND_ERROR_MEMORY_INVALID";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_UNWIND_INFO:
+    return "UNWIND_ERROR_UNWIND_INFO";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_UNSUPPORTED:
+    return "UNWIND_ERROR_UNSUPPORTED";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_INVALID_MAP:
+    return "UNWIND_ERROR_INVALID_MAP";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_MAX_FRAMES_EXCEEDED:
+    return "UNWIND_ERROR_MAX_FRAMES_EXCEEDED";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_REPEATED_FRAME:
+    return "UNWIND_ERROR_REPEATED_FRAME";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_INVALID_ELF:
+    return "UNWIND_ERROR_INVALID_ELF";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_SYSTEM_CALL:
+    return "UNWIND_ERROR_SYSTEM_CALL";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_THREAD_TIMEOUT:
+    return "UNWIND_ERROR_THREAD_TIMEOUT";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_THREAD_DOES_NOT_EXIST:
+    return "UNWIND_ERROR_THREAD_DOES_NOT_EXIST";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_BAD_ARCH:
+    return "UNWIND_ERROR_BAD_ARCH";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_MAPS_PARSE:
+    return "UNWIND_ERROR_MAPS_PARSE";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_INVALID_PARAMETER:
+    return "UNWIND_ERROR_INVALID_PARAMETER";
+
+  case ::perfetto::protos::pbzero::Profiling_StackUnwindError::UNWIND_ERROR_PTRACE_CALL:
+    return "UNWIND_ERROR_PTRACE_CALL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples {
+enum ClientError : int32_t {
+  CLIENT_ERROR_NONE = 0,
+  CLIENT_ERROR_HIT_TIMEOUT = 1,
+  CLIENT_ERROR_INVALID_STACK_BOUNDS = 2,
+};
+} // namespace perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples
+using ProfilePacket_ProcessHeapSamples_ClientError = perfetto_pbzero_enum_ProfilePacket_ProcessHeapSamples::ClientError;
+
+
+constexpr ProfilePacket_ProcessHeapSamples_ClientError ProfilePacket_ProcessHeapSamples_ClientError_MIN = ProfilePacket_ProcessHeapSamples_ClientError::CLIENT_ERROR_NONE;
+constexpr ProfilePacket_ProcessHeapSamples_ClientError ProfilePacket_ProcessHeapSamples_ClientError_MAX = ProfilePacket_ProcessHeapSamples_ClientError::CLIENT_ERROR_INVALID_STACK_BOUNDS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ProfilePacket_ProcessHeapSamples_ClientError_Name(::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError::CLIENT_ERROR_NONE:
+    return "CLIENT_ERROR_NONE";
+
+  case ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError::CLIENT_ERROR_HIT_TIMEOUT:
+    return "CLIENT_ERROR_HIT_TIMEOUT";
+
+  case ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError::CLIENT_ERROR_INVALID_STACK_BOUNDS:
+    return "CLIENT_ERROR_INVALID_STACK_BOUNDS";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class PerfSampleDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfSampleDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfSampleDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfSampleDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timebase() const { return at<1>().valid(); }
+  ::protozero::ConstBytes timebase() const { return at<1>().as_bytes(); }
+  bool has_process_shard_count() const { return at<2>().valid(); }
+  uint32_t process_shard_count() const { return at<2>().as_uint32(); }
+  bool has_chosen_process_shard() const { return at<3>().valid(); }
+  uint32_t chosen_process_shard() const { return at<3>().as_uint32(); }
+};
+
+class PerfSampleDefaults : public ::protozero::Message {
+ public:
+  using Decoder = PerfSampleDefaults_Decoder;
+  enum : int32_t {
+    kTimebaseFieldNumber = 1,
+    kProcessShardCountFieldNumber = 2,
+    kChosenProcessShardFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfSampleDefaults"; }
+
+
+  using FieldMetadata_Timebase =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfEvents_Timebase,
+      PerfSampleDefaults>;
+
+  static constexpr FieldMetadata_Timebase kTimebase{};
+  template <typename T = PerfEvents_Timebase> T* set_timebase() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ProcessShardCount =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfSampleDefaults>;
+
+  static constexpr FieldMetadata_ProcessShardCount kProcessShardCount{};
+  void set_process_shard_count(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessShardCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChosenProcessShard =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfSampleDefaults>;
+
+  static constexpr FieldMetadata_ChosenProcessShard kChosenProcessShard{};
+  void set_chosen_process_shard(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChosenProcessShard::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PerfSample_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfSample_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfSample_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfSample_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu() const { return at<1>().valid(); }
+  uint32_t cpu() const { return at<1>().as_uint32(); }
+  bool has_pid() const { return at<2>().valid(); }
+  uint32_t pid() const { return at<2>().as_uint32(); }
+  bool has_tid() const { return at<3>().valid(); }
+  uint32_t tid() const { return at<3>().as_uint32(); }
+  bool has_cpu_mode() const { return at<5>().valid(); }
+  int32_t cpu_mode() const { return at<5>().as_int32(); }
+  bool has_timebase_count() const { return at<6>().valid(); }
+  uint64_t timebase_count() const { return at<6>().as_uint64(); }
+  bool has_callstack_iid() const { return at<4>().valid(); }
+  uint64_t callstack_iid() const { return at<4>().as_uint64(); }
+  bool has_unwind_error() const { return at<16>().valid(); }
+  int32_t unwind_error() const { return at<16>().as_int32(); }
+  bool has_kernel_records_lost() const { return at<17>().valid(); }
+  uint64_t kernel_records_lost() const { return at<17>().as_uint64(); }
+  bool has_sample_skipped_reason() const { return at<18>().valid(); }
+  int32_t sample_skipped_reason() const { return at<18>().as_int32(); }
+  bool has_producer_event() const { return at<19>().valid(); }
+  ::protozero::ConstBytes producer_event() const { return at<19>().as_bytes(); }
+};
+
+class PerfSample : public ::protozero::Message {
+ public:
+  using Decoder = PerfSample_Decoder;
+  enum : int32_t {
+    kCpuFieldNumber = 1,
+    kPidFieldNumber = 2,
+    kTidFieldNumber = 3,
+    kCpuModeFieldNumber = 5,
+    kTimebaseCountFieldNumber = 6,
+    kCallstackIidFieldNumber = 4,
+    kUnwindErrorFieldNumber = 16,
+    kKernelRecordsLostFieldNumber = 17,
+    kSampleSkippedReasonFieldNumber = 18,
+    kProducerEventFieldNumber = 19,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfSample"; }
+
+  using ProducerEvent = ::perfetto::protos::pbzero::PerfSample_ProducerEvent;
+
+  using SampleSkipReason = ::perfetto::protos::pbzero::PerfSample_SampleSkipReason;
+  static inline const char* SampleSkipReason_Name(SampleSkipReason value) {
+    return ::perfetto::protos::pbzero::PerfSample_SampleSkipReason_Name(value);
+  }
+  static inline const SampleSkipReason PROFILER_SKIP_UNKNOWN = SampleSkipReason::PROFILER_SKIP_UNKNOWN;
+  static inline const SampleSkipReason PROFILER_SKIP_READ_STAGE = SampleSkipReason::PROFILER_SKIP_READ_STAGE;
+  static inline const SampleSkipReason PROFILER_SKIP_UNWIND_STAGE = SampleSkipReason::PROFILER_SKIP_UNWIND_STAGE;
+  static inline const SampleSkipReason PROFILER_SKIP_UNWIND_ENQUEUE = SampleSkipReason::PROFILER_SKIP_UNWIND_ENQUEUE;
+
+  using FieldMetadata_Cpu =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_Cpu kCpu{};
+  void set_cpu(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cpu::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CpuMode =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::Profiling_CpuMode,
+      PerfSample>;
+
+  static constexpr FieldMetadata_CpuMode kCpuMode{};
+  void set_cpu_mode(::perfetto::protos::pbzero::Profiling_CpuMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimebaseCount =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_TimebaseCount kTimebaseCount{};
+  void set_timebase_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimebaseCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CallstackIid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_CallstackIid kCallstackIid{};
+  void set_callstack_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallstackIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UnwindError =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::Profiling_StackUnwindError,
+      PerfSample>;
+
+  static constexpr FieldMetadata_UnwindError kUnwindError{};
+  void set_unwind_error(::perfetto::protos::pbzero::Profiling_StackUnwindError value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnwindError::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KernelRecordsLost =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfSample>;
+
+  static constexpr FieldMetadata_KernelRecordsLost kKernelRecordsLost{};
+  void set_kernel_records_lost(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KernelRecordsLost::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SampleSkippedReason =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::PerfSample_SampleSkipReason,
+      PerfSample>;
+
+  static constexpr FieldMetadata_SampleSkippedReason kSampleSkippedReason{};
+  void set_sample_skipped_reason(::perfetto::protos::pbzero::PerfSample_SampleSkipReason value) {
+    static constexpr uint32_t field_id = FieldMetadata_SampleSkippedReason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProducerEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfSample_ProducerEvent,
+      PerfSample>;
+
+  static constexpr FieldMetadata_ProducerEvent kProducerEvent{};
+  template <typename T = PerfSample_ProducerEvent> T* set_producer_event() {
+    return BeginNestedMessage<T>(19);
+  }
+
+};
+
+class PerfSample_ProducerEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfSample_ProducerEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfSample_ProducerEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfSample_ProducerEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_source_stop_reason() const { return at<1>().valid(); }
+  int32_t source_stop_reason() const { return at<1>().as_int32(); }
+};
+
+class PerfSample_ProducerEvent : public ::protozero::Message {
+ public:
+  using Decoder = PerfSample_ProducerEvent_Decoder;
+  enum : int32_t {
+    kSourceStopReasonFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfSample.ProducerEvent"; }
+
+
+  using DataSourceStopReason = ::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason;
+  static inline const char* DataSourceStopReason_Name(DataSourceStopReason value) {
+    return ::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason_Name(value);
+  }
+  static inline const DataSourceStopReason PROFILER_STOP_UNKNOWN = DataSourceStopReason::PROFILER_STOP_UNKNOWN;
+  static inline const DataSourceStopReason PROFILER_STOP_GUARDRAIL = DataSourceStopReason::PROFILER_STOP_GUARDRAIL;
+
+  using FieldMetadata_SourceStopReason =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason,
+      PerfSample_ProducerEvent>;
+
+  static constexpr FieldMetadata_SourceStopReason kSourceStopReason{};
+  void set_source_stop_reason(::perfetto::protos::pbzero::PerfSample_ProducerEvent_DataSourceStopReason value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceStopReason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Profiling_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Profiling_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Profiling_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Profiling_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class Profiling : public ::protozero::Message {
+ public:
+  using Decoder = Profiling_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.Profiling"; }
+
+
+  using CpuMode = ::perfetto::protos::pbzero::Profiling_CpuMode;
+  static inline const char* CpuMode_Name(CpuMode value) {
+    return ::perfetto::protos::pbzero::Profiling_CpuMode_Name(value);
+  }
+
+  using StackUnwindError = ::perfetto::protos::pbzero::Profiling_StackUnwindError;
+  static inline const char* StackUnwindError_Name(StackUnwindError value) {
+    return ::perfetto::protos::pbzero::Profiling_StackUnwindError_Name(value);
+  }
+  static inline const CpuMode MODE_UNKNOWN = CpuMode::MODE_UNKNOWN;
+  static inline const CpuMode MODE_KERNEL = CpuMode::MODE_KERNEL;
+  static inline const CpuMode MODE_USER = CpuMode::MODE_USER;
+  static inline const CpuMode MODE_HYPERVISOR = CpuMode::MODE_HYPERVISOR;
+  static inline const CpuMode MODE_GUEST_KERNEL = CpuMode::MODE_GUEST_KERNEL;
+  static inline const CpuMode MODE_GUEST_USER = CpuMode::MODE_GUEST_USER;
+  static inline const StackUnwindError UNWIND_ERROR_UNKNOWN = StackUnwindError::UNWIND_ERROR_UNKNOWN;
+  static inline const StackUnwindError UNWIND_ERROR_NONE = StackUnwindError::UNWIND_ERROR_NONE;
+  static inline const StackUnwindError UNWIND_ERROR_MEMORY_INVALID = StackUnwindError::UNWIND_ERROR_MEMORY_INVALID;
+  static inline const StackUnwindError UNWIND_ERROR_UNWIND_INFO = StackUnwindError::UNWIND_ERROR_UNWIND_INFO;
+  static inline const StackUnwindError UNWIND_ERROR_UNSUPPORTED = StackUnwindError::UNWIND_ERROR_UNSUPPORTED;
+  static inline const StackUnwindError UNWIND_ERROR_INVALID_MAP = StackUnwindError::UNWIND_ERROR_INVALID_MAP;
+  static inline const StackUnwindError UNWIND_ERROR_MAX_FRAMES_EXCEEDED = StackUnwindError::UNWIND_ERROR_MAX_FRAMES_EXCEEDED;
+  static inline const StackUnwindError UNWIND_ERROR_REPEATED_FRAME = StackUnwindError::UNWIND_ERROR_REPEATED_FRAME;
+  static inline const StackUnwindError UNWIND_ERROR_INVALID_ELF = StackUnwindError::UNWIND_ERROR_INVALID_ELF;
+  static inline const StackUnwindError UNWIND_ERROR_SYSTEM_CALL = StackUnwindError::UNWIND_ERROR_SYSTEM_CALL;
+  static inline const StackUnwindError UNWIND_ERROR_THREAD_TIMEOUT = StackUnwindError::UNWIND_ERROR_THREAD_TIMEOUT;
+  static inline const StackUnwindError UNWIND_ERROR_THREAD_DOES_NOT_EXIST = StackUnwindError::UNWIND_ERROR_THREAD_DOES_NOT_EXIST;
+  static inline const StackUnwindError UNWIND_ERROR_BAD_ARCH = StackUnwindError::UNWIND_ERROR_BAD_ARCH;
+  static inline const StackUnwindError UNWIND_ERROR_MAPS_PARSE = StackUnwindError::UNWIND_ERROR_MAPS_PARSE;
+  static inline const StackUnwindError UNWIND_ERROR_INVALID_PARAMETER = StackUnwindError::UNWIND_ERROR_INVALID_PARAMETER;
+  static inline const StackUnwindError UNWIND_ERROR_PTRACE_CALL = StackUnwindError::UNWIND_ERROR_PTRACE_CALL;
+};
+
+class StreamingProfilePacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StreamingProfilePacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StreamingProfilePacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StreamingProfilePacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_callstack_iid() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> callstack_iid() const { return GetRepeated<uint64_t>(1); }
+  bool has_timestamp_delta_us() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> timestamp_delta_us() const { return GetRepeated<int64_t>(2); }
+  bool has_process_priority() const { return at<3>().valid(); }
+  int32_t process_priority() const { return at<3>().as_int32(); }
+};
+
+class StreamingProfilePacket : public ::protozero::Message {
+ public:
+  using Decoder = StreamingProfilePacket_Decoder;
+  enum : int32_t {
+    kCallstackIidFieldNumber = 1,
+    kTimestampDeltaUsFieldNumber = 2,
+    kProcessPriorityFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StreamingProfilePacket"; }
+
+
+  using FieldMetadata_CallstackIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingProfilePacket>;
+
+  static constexpr FieldMetadata_CallstackIid kCallstackIid{};
+  void add_callstack_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallstackIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimestampDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      StreamingProfilePacket>;
+
+  static constexpr FieldMetadata_TimestampDeltaUs kTimestampDeltaUs{};
+  void add_timestamp_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      StreamingProfilePacket>;
+
+  static constexpr FieldMetadata_ProcessPriority kProcessPriority{};
+  void set_process_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessPriority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class StreamingFree_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StreamingFree_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StreamingFree_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StreamingFree_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_address() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> address() const { return GetRepeated<uint64_t>(1); }
+  bool has_heap_id() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> heap_id() const { return GetRepeated<uint32_t>(2); }
+  bool has_sequence_number() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> sequence_number() const { return GetRepeated<uint64_t>(3); }
+};
+
+class StreamingFree : public ::protozero::Message {
+ public:
+  using Decoder = StreamingFree_Decoder;
+  enum : int32_t {
+    kAddressFieldNumber = 1,
+    kHeapIdFieldNumber = 2,
+    kSequenceNumberFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StreamingFree"; }
+
+
+  using FieldMetadata_Address =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingFree>;
+
+  static constexpr FieldMetadata_Address kAddress{};
+  void add_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Address::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StreamingFree>;
+
+  static constexpr FieldMetadata_HeapId kHeapId{};
+  void add_heap_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SequenceNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingFree>;
+
+  static constexpr FieldMetadata_SequenceNumber kSequenceNumber{};
+  void add_sequence_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SequenceNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class StreamingAllocation_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StreamingAllocation_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StreamingAllocation_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StreamingAllocation_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_address() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> address() const { return GetRepeated<uint64_t>(1); }
+  bool has_size() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> size() const { return GetRepeated<uint64_t>(2); }
+  bool has_sample_size() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> sample_size() const { return GetRepeated<uint64_t>(3); }
+  bool has_clock_monotonic_coarse_timestamp() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> clock_monotonic_coarse_timestamp() const { return GetRepeated<uint64_t>(4); }
+  bool has_heap_id() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> heap_id() const { return GetRepeated<uint32_t>(5); }
+  bool has_sequence_number() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint64_t> sequence_number() const { return GetRepeated<uint64_t>(6); }
+};
+
+class StreamingAllocation : public ::protozero::Message {
+ public:
+  using Decoder = StreamingAllocation_Decoder;
+  enum : int32_t {
+    kAddressFieldNumber = 1,
+    kSizeFieldNumber = 2,
+    kSampleSizeFieldNumber = 3,
+    kClockMonotonicCoarseTimestampFieldNumber = 4,
+    kHeapIdFieldNumber = 5,
+    kSequenceNumberFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StreamingAllocation"; }
+
+
+  using FieldMetadata_Address =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_Address kAddress{};
+  void add_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Address::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Size =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_Size kSize{};
+  void add_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Size::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SampleSize =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_SampleSize kSampleSize{};
+  void add_sample_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SampleSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ClockMonotonicCoarseTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_ClockMonotonicCoarseTimestamp kClockMonotonicCoarseTimestamp{};
+  void add_clock_monotonic_coarse_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClockMonotonicCoarseTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_HeapId kHeapId{};
+  void add_heap_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SequenceNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      StreamingAllocation>;
+
+  static constexpr FieldMetadata_SequenceNumber kSequenceNumber{};
+  void add_sequence_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SequenceNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ProfilePacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProfilePacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_strings() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> strings() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_mappings() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mappings() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_frames() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> frames() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_callstacks() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> callstacks() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_process_dumps() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> process_dumps() const { return GetRepeated<::protozero::ConstBytes>(5); }
+  bool has_continued() const { return at<6>().valid(); }
+  bool continued() const { return at<6>().as_bool(); }
+  bool has_index() const { return at<7>().valid(); }
+  uint64_t index() const { return at<7>().as_uint64(); }
+};
+
+class ProfilePacket : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_Decoder;
+  enum : int32_t {
+    kStringsFieldNumber = 1,
+    kMappingsFieldNumber = 4,
+    kFramesFieldNumber = 2,
+    kCallstacksFieldNumber = 3,
+    kProcessDumpsFieldNumber = 5,
+    kContinuedFieldNumber = 6,
+    kIndexFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket"; }
+
+  using HeapSample = ::perfetto::protos::pbzero::ProfilePacket_HeapSample;
+  using Histogram = ::perfetto::protos::pbzero::ProfilePacket_Histogram;
+  using ProcessStats = ::perfetto::protos::pbzero::ProfilePacket_ProcessStats;
+  using ProcessHeapSamples = ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples;
+
+  using FieldMetadata_Strings =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      InternedString,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Strings kStrings{};
+  template <typename T = InternedString> T* add_strings() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Mappings =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Mapping,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Mappings kMappings{};
+  template <typename T = Mapping> T* add_mappings() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_Frames =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Frame,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Frames kFrames{};
+  template <typename T = Frame> T* add_frames() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_Callstacks =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Callstack,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Callstacks kCallstacks{};
+  template <typename T = Callstack> T* add_callstacks() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_ProcessDumps =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket_ProcessHeapSamples,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_ProcessDumps kProcessDumps{};
+  template <typename T = ProfilePacket_ProcessHeapSamples> T* add_process_dumps() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Continued =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Continued kContinued{};
+  void set_continued(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Continued::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ProfilePacket_ProcessHeapSamples_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/14, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProfilePacket_ProcessHeapSamples_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_ProcessHeapSamples_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_ProcessHeapSamples_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  uint64_t pid() const { return at<1>().as_uint64(); }
+  bool has_from_startup() const { return at<3>().valid(); }
+  bool from_startup() const { return at<3>().as_bool(); }
+  bool has_rejected_concurrent() const { return at<4>().valid(); }
+  bool rejected_concurrent() const { return at<4>().as_bool(); }
+  bool has_disconnected() const { return at<6>().valid(); }
+  bool disconnected() const { return at<6>().as_bool(); }
+  bool has_buffer_overran() const { return at<7>().valid(); }
+  bool buffer_overran() const { return at<7>().as_bool(); }
+  bool has_client_error() const { return at<14>().valid(); }
+  int32_t client_error() const { return at<14>().as_int32(); }
+  bool has_buffer_corrupted() const { return at<8>().valid(); }
+  bool buffer_corrupted() const { return at<8>().as_bool(); }
+  bool has_hit_guardrail() const { return at<10>().valid(); }
+  bool hit_guardrail() const { return at<10>().as_bool(); }
+  bool has_heap_name() const { return at<11>().valid(); }
+  ::protozero::ConstChars heap_name() const { return at<11>().as_string(); }
+  bool has_sampling_interval_bytes() const { return at<12>().valid(); }
+  uint64_t sampling_interval_bytes() const { return at<12>().as_uint64(); }
+  bool has_orig_sampling_interval_bytes() const { return at<13>().valid(); }
+  uint64_t orig_sampling_interval_bytes() const { return at<13>().as_uint64(); }
+  bool has_timestamp() const { return at<9>().valid(); }
+  uint64_t timestamp() const { return at<9>().as_uint64(); }
+  bool has_stats() const { return at<5>().valid(); }
+  ::protozero::ConstBytes stats() const { return at<5>().as_bytes(); }
+  bool has_samples() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> samples() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class ProfilePacket_ProcessHeapSamples : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_ProcessHeapSamples_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kFromStartupFieldNumber = 3,
+    kRejectedConcurrentFieldNumber = 4,
+    kDisconnectedFieldNumber = 6,
+    kBufferOverranFieldNumber = 7,
+    kClientErrorFieldNumber = 14,
+    kBufferCorruptedFieldNumber = 8,
+    kHitGuardrailFieldNumber = 10,
+    kHeapNameFieldNumber = 11,
+    kSamplingIntervalBytesFieldNumber = 12,
+    kOrigSamplingIntervalBytesFieldNumber = 13,
+    kTimestampFieldNumber = 9,
+    kStatsFieldNumber = 5,
+    kSamplesFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket.ProcessHeapSamples"; }
+
+
+  using ClientError = ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError;
+  static inline const char* ClientError_Name(ClientError value) {
+    return ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError_Name(value);
+  }
+  static inline const ClientError CLIENT_ERROR_NONE = ClientError::CLIENT_ERROR_NONE;
+  static inline const ClientError CLIENT_ERROR_HIT_TIMEOUT = ClientError::CLIENT_ERROR_HIT_TIMEOUT;
+  static inline const ClientError CLIENT_ERROR_INVALID_STACK_BOUNDS = ClientError::CLIENT_ERROR_INVALID_STACK_BOUNDS;
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FromStartup =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_FromStartup kFromStartup{};
+  void set_from_startup(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_FromStartup::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RejectedConcurrent =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_RejectedConcurrent kRejectedConcurrent{};
+  void set_rejected_concurrent(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_RejectedConcurrent::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Disconnected =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_Disconnected kDisconnected{};
+  void set_disconnected(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Disconnected::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BufferOverran =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_BufferOverran kBufferOverran{};
+  void set_buffer_overran(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferOverran::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ClientError =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_ClientError kClientError{};
+  void set_client_error(::perfetto::protos::pbzero::ProfilePacket_ProcessHeapSamples_ClientError value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientError::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BufferCorrupted =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_BufferCorrupted kBufferCorrupted{};
+  void set_buffer_corrupted(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BufferCorrupted::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HitGuardrail =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_HitGuardrail kHitGuardrail{};
+  void set_hit_guardrail(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HitGuardrail::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapName =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_HeapName kHeapName{};
+  void set_heap_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, data, size);
+  }
+  void set_heap_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HeapName::kFieldId, chars.data, chars.size);
+  }
+  void set_heap_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SamplingIntervalBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_SamplingIntervalBytes kSamplingIntervalBytes{};
+  void set_sampling_interval_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SamplingIntervalBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrigSamplingIntervalBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_OrigSamplingIntervalBytes kOrigSamplingIntervalBytes{};
+  void set_orig_sampling_interval_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrigSamplingIntervalBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Stats =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket_ProcessStats,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_Stats kStats{};
+  template <typename T = ProfilePacket_ProcessStats> T* set_stats() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_Samples =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket_HeapSample,
+      ProfilePacket_ProcessHeapSamples>;
+
+  static constexpr FieldMetadata_Samples kSamples{};
+  template <typename T = ProfilePacket_HeapSample> T* add_samples() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class ProfilePacket_ProcessStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProfilePacket_ProcessStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_ProcessStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_ProcessStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_unwinding_errors() const { return at<1>().valid(); }
+  uint64_t unwinding_errors() const { return at<1>().as_uint64(); }
+  bool has_heap_samples() const { return at<2>().valid(); }
+  uint64_t heap_samples() const { return at<2>().as_uint64(); }
+  bool has_map_reparses() const { return at<3>().valid(); }
+  uint64_t map_reparses() const { return at<3>().as_uint64(); }
+  bool has_unwinding_time_us() const { return at<4>().valid(); }
+  ::protozero::ConstBytes unwinding_time_us() const { return at<4>().as_bytes(); }
+  bool has_total_unwinding_time_us() const { return at<5>().valid(); }
+  uint64_t total_unwinding_time_us() const { return at<5>().as_uint64(); }
+  bool has_client_spinlock_blocked_us() const { return at<6>().valid(); }
+  uint64_t client_spinlock_blocked_us() const { return at<6>().as_uint64(); }
+};
+
+class ProfilePacket_ProcessStats : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_ProcessStats_Decoder;
+  enum : int32_t {
+    kUnwindingErrorsFieldNumber = 1,
+    kHeapSamplesFieldNumber = 2,
+    kMapReparsesFieldNumber = 3,
+    kUnwindingTimeUsFieldNumber = 4,
+    kTotalUnwindingTimeUsFieldNumber = 5,
+    kClientSpinlockBlockedUsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket.ProcessStats"; }
+
+
+  using FieldMetadata_UnwindingErrors =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_UnwindingErrors kUnwindingErrors{};
+  void set_unwinding_errors(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UnwindingErrors::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HeapSamples =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_HeapSamples kHeapSamples{};
+  void set_heap_samples(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HeapSamples::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MapReparses =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_MapReparses kMapReparses{};
+  void set_map_reparses(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MapReparses::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UnwindingTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket_Histogram,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_UnwindingTimeUs kUnwindingTimeUs{};
+  template <typename T = ProfilePacket_Histogram> T* set_unwinding_time_us() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_TotalUnwindingTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_TotalUnwindingTimeUs kTotalUnwindingTimeUs{};
+  void set_total_unwinding_time_us(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalUnwindingTimeUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ClientSpinlockBlockedUs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_ProcessStats>;
+
+  static constexpr FieldMetadata_ClientSpinlockBlockedUs kClientSpinlockBlockedUs{};
+  void set_client_spinlock_blocked_us(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ClientSpinlockBlockedUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ProfilePacket_Histogram_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProfilePacket_Histogram_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_Histogram_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_Histogram_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_buckets() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buckets() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class ProfilePacket_Histogram : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_Histogram_Decoder;
+  enum : int32_t {
+    kBucketsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket.Histogram"; }
+
+  using Bucket = ::perfetto::protos::pbzero::ProfilePacket_Histogram_Bucket;
+
+  using FieldMetadata_Buckets =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProfilePacket_Histogram_Bucket,
+      ProfilePacket_Histogram>;
+
+  static constexpr FieldMetadata_Buckets kBuckets{};
+  template <typename T = ProfilePacket_Histogram_Bucket> T* add_buckets() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ProfilePacket_Histogram_Bucket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProfilePacket_Histogram_Bucket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_Histogram_Bucket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_Histogram_Bucket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_upper_limit() const { return at<1>().valid(); }
+  uint64_t upper_limit() const { return at<1>().as_uint64(); }
+  bool has_max_bucket() const { return at<2>().valid(); }
+  bool max_bucket() const { return at<2>().as_bool(); }
+  bool has_count() const { return at<3>().valid(); }
+  uint64_t count() const { return at<3>().as_uint64(); }
+};
+
+class ProfilePacket_Histogram_Bucket : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_Histogram_Bucket_Decoder;
+  enum : int32_t {
+    kUpperLimitFieldNumber = 1,
+    kMaxBucketFieldNumber = 2,
+    kCountFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket.Histogram.Bucket"; }
+
+
+  using FieldMetadata_UpperLimit =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_Histogram_Bucket>;
+
+  static constexpr FieldMetadata_UpperLimit kUpperLimit{};
+  void set_upper_limit(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UpperLimit::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MaxBucket =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProfilePacket_Histogram_Bucket>;
+
+  static constexpr FieldMetadata_MaxBucket kMaxBucket{};
+  void set_max_bucket(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_MaxBucket::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_Histogram_Bucket>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ProfilePacket_HeapSample_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProfilePacket_HeapSample_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProfilePacket_HeapSample_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProfilePacket_HeapSample_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_callstack_id() const { return at<1>().valid(); }
+  uint64_t callstack_id() const { return at<1>().as_uint64(); }
+  bool has_self_allocated() const { return at<2>().valid(); }
+  uint64_t self_allocated() const { return at<2>().as_uint64(); }
+  bool has_self_freed() const { return at<3>().valid(); }
+  uint64_t self_freed() const { return at<3>().as_uint64(); }
+  bool has_self_max() const { return at<8>().valid(); }
+  uint64_t self_max() const { return at<8>().as_uint64(); }
+  bool has_self_max_count() const { return at<9>().valid(); }
+  uint64_t self_max_count() const { return at<9>().as_uint64(); }
+  bool has_timestamp() const { return at<4>().valid(); }
+  uint64_t timestamp() const { return at<4>().as_uint64(); }
+  bool has_alloc_count() const { return at<5>().valid(); }
+  uint64_t alloc_count() const { return at<5>().as_uint64(); }
+  bool has_free_count() const { return at<6>().valid(); }
+  uint64_t free_count() const { return at<6>().as_uint64(); }
+};
+
+class ProfilePacket_HeapSample : public ::protozero::Message {
+ public:
+  using Decoder = ProfilePacket_HeapSample_Decoder;
+  enum : int32_t {
+    kCallstackIdFieldNumber = 1,
+    kSelfAllocatedFieldNumber = 2,
+    kSelfFreedFieldNumber = 3,
+    kSelfMaxFieldNumber = 8,
+    kSelfMaxCountFieldNumber = 9,
+    kTimestampFieldNumber = 4,
+    kAllocCountFieldNumber = 5,
+    kFreeCountFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProfilePacket.HeapSample"; }
+
+
+  using FieldMetadata_CallstackId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_CallstackId kCallstackId{};
+  void set_callstack_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CallstackId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SelfAllocated =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_SelfAllocated kSelfAllocated{};
+  void set_self_allocated(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelfAllocated::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SelfFreed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_SelfFreed kSelfFreed{};
+  void set_self_freed(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelfFreed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SelfMax =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_SelfMax kSelfMax{};
+  void set_self_max(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelfMax::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SelfMaxCount =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_SelfMaxCount kSelfMaxCount{};
+  void set_self_max_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SelfMaxCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Timestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_Timestamp kTimestamp{};
+  void set_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllocCount =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_AllocCount kAllocCount{};
+  void set_alloc_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllocCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FreeCount =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProfilePacket_HeapSample>;
+
+  static constexpr FieldMetadata_FreeCount kFreeCount{};
+  void set_free_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FreeCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/profiling/smaps.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_SMAPS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PROFILING_SMAPS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SmapsEntry;
+
+class SmapsPacket_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SmapsPacket_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmapsPacket_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmapsPacket_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  uint32_t pid() const { return at<1>().as_uint32(); }
+  bool has_entries() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> entries() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class SmapsPacket : public ::protozero::Message {
+ public:
+  using Decoder = SmapsPacket_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kEntriesFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmapsPacket"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmapsPacket>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Entries =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SmapsEntry,
+      SmapsPacket>;
+
+  static constexpr FieldMetadata_Entries kEntries{};
+  template <typename T = SmapsEntry> T* add_entries() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class SmapsEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/15, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SmapsEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SmapsEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SmapsEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_path() const { return at<1>().valid(); }
+  ::protozero::ConstChars path() const { return at<1>().as_string(); }
+  bool has_size_kb() const { return at<2>().valid(); }
+  uint64_t size_kb() const { return at<2>().as_uint64(); }
+  bool has_private_dirty_kb() const { return at<3>().valid(); }
+  uint64_t private_dirty_kb() const { return at<3>().as_uint64(); }
+  bool has_swap_kb() const { return at<4>().valid(); }
+  uint64_t swap_kb() const { return at<4>().as_uint64(); }
+  bool has_file_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars file_name() const { return at<5>().as_string(); }
+  bool has_start_address() const { return at<6>().valid(); }
+  uint64_t start_address() const { return at<6>().as_uint64(); }
+  bool has_module_timestamp() const { return at<7>().valid(); }
+  uint64_t module_timestamp() const { return at<7>().as_uint64(); }
+  bool has_module_debugid() const { return at<8>().valid(); }
+  ::protozero::ConstChars module_debugid() const { return at<8>().as_string(); }
+  bool has_module_debug_path() const { return at<9>().valid(); }
+  ::protozero::ConstChars module_debug_path() const { return at<9>().as_string(); }
+  bool has_protection_flags() const { return at<10>().valid(); }
+  uint32_t protection_flags() const { return at<10>().as_uint32(); }
+  bool has_private_clean_resident_kb() const { return at<11>().valid(); }
+  uint64_t private_clean_resident_kb() const { return at<11>().as_uint64(); }
+  bool has_shared_dirty_resident_kb() const { return at<12>().valid(); }
+  uint64_t shared_dirty_resident_kb() const { return at<12>().as_uint64(); }
+  bool has_shared_clean_resident_kb() const { return at<13>().valid(); }
+  uint64_t shared_clean_resident_kb() const { return at<13>().as_uint64(); }
+  bool has_locked_kb() const { return at<14>().valid(); }
+  uint64_t locked_kb() const { return at<14>().as_uint64(); }
+  bool has_proportional_resident_kb() const { return at<15>().valid(); }
+  uint64_t proportional_resident_kb() const { return at<15>().as_uint64(); }
+};
+
+class SmapsEntry : public ::protozero::Message {
+ public:
+  using Decoder = SmapsEntry_Decoder;
+  enum : int32_t {
+    kPathFieldNumber = 1,
+    kSizeKbFieldNumber = 2,
+    kPrivateDirtyKbFieldNumber = 3,
+    kSwapKbFieldNumber = 4,
+    kFileNameFieldNumber = 5,
+    kStartAddressFieldNumber = 6,
+    kModuleTimestampFieldNumber = 7,
+    kModuleDebugidFieldNumber = 8,
+    kModuleDebugPathFieldNumber = 9,
+    kProtectionFlagsFieldNumber = 10,
+    kPrivateCleanResidentKbFieldNumber = 11,
+    kSharedDirtyResidentKbFieldNumber = 12,
+    kSharedCleanResidentKbFieldNumber = 13,
+    kLockedKbFieldNumber = 14,
+    kProportionalResidentKbFieldNumber = 15,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SmapsEntry"; }
+
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_SizeKb kSizeKb{};
+  void set_size_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SizeKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrivateDirtyKb =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_PrivateDirtyKb kPrivateDirtyKb{};
+  void set_private_dirty_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrivateDirtyKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SwapKb =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_SwapKb kSwapKb{};
+  void set_swap_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SwapKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FileName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_FileName kFileName{};
+  void set_file_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FileName::kFieldId, data, size);
+  }
+  void set_file_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FileName::kFieldId, chars.data, chars.size);
+  }
+  void set_file_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FileName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartAddress =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_StartAddress kStartAddress{};
+  void set_start_address(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartAddress::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ModuleTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_ModuleTimestamp kModuleTimestamp{};
+  void set_module_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ModuleTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ModuleDebugid =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_ModuleDebugid kModuleDebugid{};
+  void set_module_debugid(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ModuleDebugid::kFieldId, data, size);
+  }
+  void set_module_debugid(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ModuleDebugid::kFieldId, chars.data, chars.size);
+  }
+  void set_module_debugid(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ModuleDebugid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ModuleDebugPath =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_ModuleDebugPath kModuleDebugPath{};
+  void set_module_debug_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ModuleDebugPath::kFieldId, data, size);
+  }
+  void set_module_debug_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ModuleDebugPath::kFieldId, chars.data, chars.size);
+  }
+  void set_module_debug_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ModuleDebugPath::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProtectionFlags =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_ProtectionFlags kProtectionFlags{};
+  void set_protection_flags(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProtectionFlags::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrivateCleanResidentKb =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_PrivateCleanResidentKb kPrivateCleanResidentKb{};
+  void set_private_clean_resident_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrivateCleanResidentKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SharedDirtyResidentKb =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_SharedDirtyResidentKb kSharedDirtyResidentKb{};
+  void set_shared_dirty_resident_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SharedDirtyResidentKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SharedCleanResidentKb =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_SharedCleanResidentKb kSharedCleanResidentKb{};
+  void set_shared_clean_resident_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SharedCleanResidentKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LockedKb =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_LockedKb kLockedKb{};
+  void set_locked_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LockedKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProportionalResidentKb =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SmapsEntry>;
+
+  static constexpr FieldMetadata_ProportionalResidentKb kProportionalResidentKb{};
+  void set_proportional_resident_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProportionalResidentKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_active_processes.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_ACTIVE_PROCESSES_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_ACTIVE_PROCESSES_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ChromeActiveProcesses_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeActiveProcesses_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeActiveProcesses_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeActiveProcesses_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> pid() const { return GetRepeated<int32_t>(1); }
+};
+
+class ChromeActiveProcesses : public ::protozero::Message {
+ public:
+  using Decoder = ChromeActiveProcesses_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeActiveProcesses"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeActiveProcesses>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void add_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeApplicationStateInfo {
+enum ChromeApplicationState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeApplicationStateInfo
+using ChromeApplicationStateInfo_ChromeApplicationState = perfetto_pbzero_enum_ChromeApplicationStateInfo::ChromeApplicationState;
+
+namespace perfetto_pbzero_enum_ChromeApplicationStateInfo {
+enum ChromeApplicationState : int32_t {
+  APPLICATION_STATE_UNKNOWN = 0,
+  APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = 1,
+  APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = 2,
+  APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = 3,
+  APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = 4,
+};
+} // namespace perfetto_pbzero_enum_ChromeApplicationStateInfo
+using ChromeApplicationStateInfo_ChromeApplicationState = perfetto_pbzero_enum_ChromeApplicationStateInfo::ChromeApplicationState;
+
+
+constexpr ChromeApplicationStateInfo_ChromeApplicationState ChromeApplicationStateInfo_ChromeApplicationState_MIN = ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_UNKNOWN;
+constexpr ChromeApplicationStateInfo_ChromeApplicationState ChromeApplicationStateInfo_ChromeApplicationState_MAX = ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeApplicationStateInfo_ChromeApplicationState_Name(::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_UNKNOWN:
+    return "APPLICATION_STATE_UNKNOWN";
+
+  case ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES:
+    return "APPLICATION_STATE_HAS_RUNNING_ACTIVITIES";
+
+  case ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES:
+    return "APPLICATION_STATE_HAS_PAUSED_ACTIVITIES";
+
+  case ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES:
+    return "APPLICATION_STATE_HAS_STOPPED_ACTIVITIES";
+
+  case ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState::APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES:
+    return "APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeApplicationStateInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeApplicationStateInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeApplicationStateInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeApplicationStateInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_application_state() const { return at<1>().valid(); }
+  int32_t application_state() const { return at<1>().as_int32(); }
+};
+
+class ChromeApplicationStateInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeApplicationStateInfo_Decoder;
+  enum : int32_t {
+    kApplicationStateFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeApplicationStateInfo"; }
+
+
+  using ChromeApplicationState = ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState;
+  static inline const char* ChromeApplicationState_Name(ChromeApplicationState value) {
+    return ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState_Name(value);
+  }
+  static inline const ChromeApplicationState APPLICATION_STATE_UNKNOWN = ChromeApplicationState::APPLICATION_STATE_UNKNOWN;
+  static inline const ChromeApplicationState APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = ChromeApplicationState::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+  static inline const ChromeApplicationState APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = ChromeApplicationState::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
+  static inline const ChromeApplicationState APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = ChromeApplicationState::APPLICATION_STATE_HAS_STOPPED_ACTIVITIES;
+  static inline const ChromeApplicationState APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = ChromeApplicationState::APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
+
+  using FieldMetadata_ApplicationState =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState,
+      ChromeApplicationStateInfo>;
+
+  static constexpr FieldMetadata_ApplicationState kApplicationState{};
+  void set_application_state(::perfetto::protos::pbzero::ChromeApplicationStateInfo_ChromeApplicationState value) {
+    static constexpr uint32_t field_id = FieldMetadata_ApplicationState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class BeginFrameArgs;
+class BeginFrameObserverState;
+class BeginFrameSourceState;
+class BeginImplFrameArgs;
+class BeginImplFrameArgs_TimestampsInUs;
+class ChromeCompositorStateMachine;
+class ChromeCompositorStateMachine_MajorState;
+class ChromeCompositorStateMachine_MinorState;
+class CompositorTimingHistory;
+class SourceLocation;
+namespace perfetto_pbzero_enum_BeginFrameArgs {
+enum BeginFrameArgsType : int32_t;
+}  // namespace perfetto_pbzero_enum_BeginFrameArgs
+using BeginFrameArgs_BeginFrameArgsType = perfetto_pbzero_enum_BeginFrameArgs::BeginFrameArgsType;
+namespace perfetto_pbzero_enum_BeginImplFrameArgs {
+enum State : int32_t;
+}  // namespace perfetto_pbzero_enum_BeginImplFrameArgs
+using BeginImplFrameArgs_State = perfetto_pbzero_enum_BeginImplFrameArgs::State;
+enum ChromeCompositorSchedulerAction : int32_t;
+namespace perfetto_pbzero_enum_ChromeCompositorSchedulerState {
+enum BeginImplFrameDeadlineMode : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorSchedulerState
+using ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode = perfetto_pbzero_enum_ChromeCompositorSchedulerState::BeginImplFrameDeadlineMode;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum BeginImplFrameState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_BeginImplFrameState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::BeginImplFrameState;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum BeginMainFrameState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_BeginMainFrameState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::BeginMainFrameState;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum ForcedRedrawOnTimeoutState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::ForcedRedrawOnTimeoutState;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum LayerTreeFrameSinkState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::LayerTreeFrameSinkState;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState {
+enum ScrollHandlerState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState
+using ChromeCompositorStateMachine_MinorState_ScrollHandlerState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState::ScrollHandlerState;
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState {
+enum TreePriority : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState
+using ChromeCompositorStateMachine_MinorState_TreePriority = perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState::TreePriority;
+
+enum ChromeCompositorSchedulerAction : int32_t {
+  CC_SCHEDULER_ACTION_UNSPECIFIED = 0,
+  CC_SCHEDULER_ACTION_NONE = 1,
+  CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME = 2,
+  CC_SCHEDULER_ACTION_COMMIT = 3,
+  CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE = 4,
+  CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE = 5,
+  CC_SCHEDULER_ACTION_DRAW_FORCED = 6,
+  CC_SCHEDULER_ACTION_DRAW_ABORT = 7,
+  CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION = 8,
+  CC_SCHEDULER_ACTION_PREPARE_TILES = 9,
+  CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK = 10,
+  CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION = 11,
+  CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL = 12,
+  CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON = 13,
+};
+
+constexpr ChromeCompositorSchedulerAction ChromeCompositorSchedulerAction_MIN = ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_UNSPECIFIED;
+constexpr ChromeCompositorSchedulerAction ChromeCompositorSchedulerAction_MAX = ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorSchedulerAction_Name(::perfetto::protos::pbzero::ChromeCompositorSchedulerAction value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_UNSPECIFIED:
+    return "CC_SCHEDULER_ACTION_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_NONE:
+    return "CC_SCHEDULER_ACTION_NONE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME:
+    return "CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_COMMIT:
+    return "CC_SCHEDULER_ACTION_COMMIT";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE:
+    return "CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE:
+    return "CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_DRAW_FORCED:
+    return "CC_SCHEDULER_ACTION_DRAW_FORCED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_DRAW_ABORT:
+    return "CC_SCHEDULER_ACTION_DRAW_ABORT";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION:
+    return "CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_PREPARE_TILES:
+    return "CC_SCHEDULER_ACTION_PREPARE_TILES";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK:
+    return "CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION:
+    return "CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL:
+    return "CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction::CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON:
+    return "CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_BeginImplFrameArgs {
+enum State : int32_t {
+  BEGIN_FRAME_FINISHED = 0,
+  BEGIN_FRAME_USING = 1,
+};
+} // namespace perfetto_pbzero_enum_BeginImplFrameArgs
+using BeginImplFrameArgs_State = perfetto_pbzero_enum_BeginImplFrameArgs::State;
+
+
+constexpr BeginImplFrameArgs_State BeginImplFrameArgs_State_MIN = BeginImplFrameArgs_State::BEGIN_FRAME_FINISHED;
+constexpr BeginImplFrameArgs_State BeginImplFrameArgs_State_MAX = BeginImplFrameArgs_State::BEGIN_FRAME_USING;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* BeginImplFrameArgs_State_Name(::perfetto::protos::pbzero::BeginImplFrameArgs_State value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::BeginImplFrameArgs_State::BEGIN_FRAME_FINISHED:
+    return "BEGIN_FRAME_FINISHED";
+
+  case ::perfetto::protos::pbzero::BeginImplFrameArgs_State::BEGIN_FRAME_USING:
+    return "BEGIN_FRAME_USING";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_BeginFrameArgs {
+enum BeginFrameArgsType : int32_t {
+  BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = 0,
+  BEGIN_FRAME_ARGS_TYPE_INVALID = 1,
+  BEGIN_FRAME_ARGS_TYPE_NORMAL = 2,
+  BEGIN_FRAME_ARGS_TYPE_MISSED = 3,
+};
+} // namespace perfetto_pbzero_enum_BeginFrameArgs
+using BeginFrameArgs_BeginFrameArgsType = perfetto_pbzero_enum_BeginFrameArgs::BeginFrameArgsType;
+
+
+constexpr BeginFrameArgs_BeginFrameArgsType BeginFrameArgs_BeginFrameArgsType_MIN = BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
+constexpr BeginFrameArgs_BeginFrameArgsType BeginFrameArgs_BeginFrameArgsType_MAX = BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_MISSED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* BeginFrameArgs_BeginFrameArgsType_Name(::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED:
+    return "BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_INVALID:
+    return "BEGIN_FRAME_ARGS_TYPE_INVALID";
+
+  case ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_NORMAL:
+    return "BEGIN_FRAME_ARGS_TYPE_NORMAL";
+
+  case ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_MISSED:
+    return "BEGIN_FRAME_ARGS_TYPE_MISSED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState {
+enum TreePriority : int32_t {
+  TREE_PRIORITY_UNSPECIFIED = 0,
+  TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = 1,
+  TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = 2,
+  TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState
+using ChromeCompositorStateMachine_MinorState_TreePriority = perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState::TreePriority;
+
+
+constexpr ChromeCompositorStateMachine_MinorState_TreePriority ChromeCompositorStateMachine_MinorState_TreePriority_MIN = ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MinorState_TreePriority ChromeCompositorStateMachine_MinorState_TreePriority_MAX = ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MinorState_TreePriority_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_UNSPECIFIED:
+    return "TREE_PRIORITY_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES:
+    return "TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY:
+    return "TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority::TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY:
+    return "TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState {
+enum ScrollHandlerState : int32_t {
+  SCROLL_HANDLER_UNSPECIFIED = 0,
+  SCROLL_AFFECTS_SCROLL_HANDLER = 1,
+  SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = 2,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState
+using ChromeCompositorStateMachine_MinorState_ScrollHandlerState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MinorState::ScrollHandlerState;
+
+
+constexpr ChromeCompositorStateMachine_MinorState_ScrollHandlerState ChromeCompositorStateMachine_MinorState_ScrollHandlerState_MIN = ChromeCompositorStateMachine_MinorState_ScrollHandlerState::SCROLL_HANDLER_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MinorState_ScrollHandlerState ChromeCompositorStateMachine_MinorState_ScrollHandlerState_MAX = ChromeCompositorStateMachine_MinorState_ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MinorState_ScrollHandlerState_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState::SCROLL_HANDLER_UNSPECIFIED:
+    return "SCROLL_HANDLER_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER:
+    return "SCROLL_AFFECTS_SCROLL_HANDLER";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER:
+    return "SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum BeginImplFrameState : int32_t {
+  BEGIN_IMPL_FRAME_UNSPECIFIED = 0,
+  BEGIN_IMPL_FRAME_IDLE = 1,
+  BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = 2,
+  BEGIN_IMPL_FRAME_INSIDE_DEADLINE = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_BeginImplFrameState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::BeginImplFrameState;
+
+
+constexpr ChromeCompositorStateMachine_MajorState_BeginImplFrameState ChromeCompositorStateMachine_MajorState_BeginImplFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MajorState_BeginImplFrameState ChromeCompositorStateMachine_MajorState_BeginImplFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MajorState_BeginImplFrameState_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_UNSPECIFIED:
+    return "BEGIN_IMPL_FRAME_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_IDLE:
+    return "BEGIN_IMPL_FRAME_IDLE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME:
+    return "BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState::BEGIN_IMPL_FRAME_INSIDE_DEADLINE:
+    return "BEGIN_IMPL_FRAME_INSIDE_DEADLINE";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum BeginMainFrameState : int32_t {
+  BEGIN_MAIN_FRAME_UNSPECIFIED = 0,
+  BEGIN_MAIN_FRAME_IDLE = 1,
+  BEGIN_MAIN_FRAME_SENT = 2,
+  BEGIN_MAIN_FRAME_READY_TO_COMMIT = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_BeginMainFrameState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::BeginMainFrameState;
+
+
+constexpr ChromeCompositorStateMachine_MajorState_BeginMainFrameState ChromeCompositorStateMachine_MajorState_BeginMainFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MajorState_BeginMainFrameState ChromeCompositorStateMachine_MajorState_BeginMainFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_READY_TO_COMMIT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MajorState_BeginMainFrameState_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_UNSPECIFIED:
+    return "BEGIN_MAIN_FRAME_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_IDLE:
+    return "BEGIN_MAIN_FRAME_IDLE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_SENT:
+    return "BEGIN_MAIN_FRAME_SENT";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState::BEGIN_MAIN_FRAME_READY_TO_COMMIT:
+    return "BEGIN_MAIN_FRAME_READY_TO_COMMIT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum LayerTreeFrameSinkState : int32_t {
+  LAYER_TREE_FRAME_UNSPECIFIED = 0,
+  LAYER_TREE_FRAME_NONE = 1,
+  LAYER_TREE_FRAME_ACTIVE = 2,
+  LAYER_TREE_FRAME_CREATING = 3,
+  LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = 4,
+  LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = 5,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::LayerTreeFrameSinkState;
+
+
+constexpr ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_MIN = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_MAX = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_UNSPECIFIED:
+    return "LAYER_TREE_FRAME_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_NONE:
+    return "LAYER_TREE_FRAME_NONE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_ACTIVE:
+    return "LAYER_TREE_FRAME_ACTIVE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_CREATING:
+    return "LAYER_TREE_FRAME_CREATING";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT:
+    return "LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION:
+    return "LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState {
+enum ForcedRedrawOnTimeoutState : int32_t {
+  FORCED_REDRAW_UNSPECIFIED = 0,
+  FORCED_REDRAW_IDLE = 1,
+  FORCED_REDRAW_WAITING_FOR_COMMIT = 2,
+  FORCED_REDRAW_WAITING_FOR_ACTIVATION = 3,
+  FORCED_REDRAW_WAITING_FOR_DRAW = 4,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState
+using ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState = perfetto_pbzero_enum_ChromeCompositorStateMachine_MajorState::ForcedRedrawOnTimeoutState;
+
+
+constexpr ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_MIN = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_UNSPECIFIED;
+constexpr ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_MAX = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_DRAW;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_Name(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_UNSPECIFIED:
+    return "FORCED_REDRAW_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_IDLE:
+    return "FORCED_REDRAW_IDLE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_COMMIT:
+    return "FORCED_REDRAW_WAITING_FOR_COMMIT";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_ACTIVATION:
+    return "FORCED_REDRAW_WAITING_FOR_ACTIVATION";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_DRAW:
+    return "FORCED_REDRAW_WAITING_FOR_DRAW";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeCompositorSchedulerState {
+enum BeginImplFrameDeadlineMode : int32_t {
+  DEADLINE_MODE_UNSPECIFIED = 0,
+  DEADLINE_MODE_NONE = 1,
+  DEADLINE_MODE_IMMEDIATE = 2,
+  DEADLINE_MODE_REGULAR = 3,
+  DEADLINE_MODE_LATE = 4,
+  DEADLINE_MODE_BLOCKED = 5,
+};
+} // namespace perfetto_pbzero_enum_ChromeCompositorSchedulerState
+using ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode = perfetto_pbzero_enum_ChromeCompositorSchedulerState::BeginImplFrameDeadlineMode;
+
+
+constexpr ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_MIN = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_UNSPECIFIED;
+constexpr ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_MAX = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_BLOCKED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_Name(::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_UNSPECIFIED:
+    return "DEADLINE_MODE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_NONE:
+    return "DEADLINE_MODE_NONE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_IMMEDIATE:
+    return "DEADLINE_MODE_IMMEDIATE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_REGULAR:
+    return "DEADLINE_MODE_REGULAR";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_LATE:
+    return "DEADLINE_MODE_LATE";
+
+  case ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode::DEADLINE_MODE_BLOCKED:
+    return "DEADLINE_MODE_BLOCKED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class CompositorTimingHistory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  CompositorTimingHistory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CompositorTimingHistory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CompositorTimingHistory_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_begin_main_frame_queue_critical_estimate_delta_us() const { return at<1>().valid(); }
+  int64_t begin_main_frame_queue_critical_estimate_delta_us() const { return at<1>().as_int64(); }
+  bool has_begin_main_frame_queue_not_critical_estimate_delta_us() const { return at<2>().valid(); }
+  int64_t begin_main_frame_queue_not_critical_estimate_delta_us() const { return at<2>().as_int64(); }
+  bool has_begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const { return at<3>().valid(); }
+  int64_t begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const { return at<3>().as_int64(); }
+  bool has_commit_to_ready_to_activate_estimate_delta_us() const { return at<4>().valid(); }
+  int64_t commit_to_ready_to_activate_estimate_delta_us() const { return at<4>().as_int64(); }
+  bool has_prepare_tiles_estimate_delta_us() const { return at<5>().valid(); }
+  int64_t prepare_tiles_estimate_delta_us() const { return at<5>().as_int64(); }
+  bool has_activate_estimate_delta_us() const { return at<6>().valid(); }
+  int64_t activate_estimate_delta_us() const { return at<6>().as_int64(); }
+  bool has_draw_estimate_delta_us() const { return at<7>().valid(); }
+  int64_t draw_estimate_delta_us() const { return at<7>().as_int64(); }
+};
+
+class CompositorTimingHistory : public ::protozero::Message {
+ public:
+  using Decoder = CompositorTimingHistory_Decoder;
+  enum : int32_t {
+    kBeginMainFrameQueueCriticalEstimateDeltaUsFieldNumber = 1,
+    kBeginMainFrameQueueNotCriticalEstimateDeltaUsFieldNumber = 2,
+    kBeginMainFrameStartToReadyToCommitEstimateDeltaUsFieldNumber = 3,
+    kCommitToReadyToActivateEstimateDeltaUsFieldNumber = 4,
+    kPrepareTilesEstimateDeltaUsFieldNumber = 5,
+    kActivateEstimateDeltaUsFieldNumber = 6,
+    kDrawEstimateDeltaUsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CompositorTimingHistory"; }
+
+
+  using FieldMetadata_BeginMainFrameQueueCriticalEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_BeginMainFrameQueueCriticalEstimateDeltaUs kBeginMainFrameQueueCriticalEstimateDeltaUs{};
+  void set_begin_main_frame_queue_critical_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginMainFrameQueueCriticalEstimateDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BeginMainFrameQueueNotCriticalEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_BeginMainFrameQueueNotCriticalEstimateDeltaUs kBeginMainFrameQueueNotCriticalEstimateDeltaUs{};
+  void set_begin_main_frame_queue_not_critical_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginMainFrameQueueNotCriticalEstimateDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BeginMainFrameStartToReadyToCommitEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_BeginMainFrameStartToReadyToCommitEstimateDeltaUs kBeginMainFrameStartToReadyToCommitEstimateDeltaUs{};
+  void set_begin_main_frame_start_to_ready_to_commit_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginMainFrameStartToReadyToCommitEstimateDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CommitToReadyToActivateEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_CommitToReadyToActivateEstimateDeltaUs kCommitToReadyToActivateEstimateDeltaUs{};
+  void set_commit_to_ready_to_activate_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CommitToReadyToActivateEstimateDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PrepareTilesEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_PrepareTilesEstimateDeltaUs kPrepareTilesEstimateDeltaUs{};
+  void set_prepare_tiles_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PrepareTilesEstimateDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ActivateEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_ActivateEstimateDeltaUs kActivateEstimateDeltaUs{};
+  void set_activate_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActivateEstimateDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DrawEstimateDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      CompositorTimingHistory>;
+
+  static constexpr FieldMetadata_DrawEstimateDeltaUs kDrawEstimateDeltaUs{};
+  void set_draw_estimate_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DrawEstimateDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BeginFrameSourceState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BeginFrameSourceState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BeginFrameSourceState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BeginFrameSourceState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_source_id() const { return at<1>().valid(); }
+  uint32_t source_id() const { return at<1>().as_uint32(); }
+  bool has_paused() const { return at<2>().valid(); }
+  bool paused() const { return at<2>().as_bool(); }
+  bool has_num_observers() const { return at<3>().valid(); }
+  uint32_t num_observers() const { return at<3>().as_uint32(); }
+  bool has_last_begin_frame_args() const { return at<4>().valid(); }
+  ::protozero::ConstBytes last_begin_frame_args() const { return at<4>().as_bytes(); }
+};
+
+class BeginFrameSourceState : public ::protozero::Message {
+ public:
+  using Decoder = BeginFrameSourceState_Decoder;
+  enum : int32_t {
+    kSourceIdFieldNumber = 1,
+    kPausedFieldNumber = 2,
+    kNumObserversFieldNumber = 3,
+    kLastBeginFrameArgsFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BeginFrameSourceState"; }
+
+
+  using FieldMetadata_SourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BeginFrameSourceState>;
+
+  static constexpr FieldMetadata_SourceId kSourceId{};
+  void set_source_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Paused =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      BeginFrameSourceState>;
+
+  static constexpr FieldMetadata_Paused kPaused{};
+  void set_paused(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Paused::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumObservers =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      BeginFrameSourceState>;
+
+  static constexpr FieldMetadata_NumObservers kNumObservers{};
+  void set_num_observers(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumObservers::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LastBeginFrameArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameArgs,
+      BeginFrameSourceState>;
+
+  static constexpr FieldMetadata_LastBeginFrameArgs kLastBeginFrameArgs{};
+  template <typename T = BeginFrameArgs> T* set_last_begin_frame_args() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class BeginFrameObserverState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BeginFrameObserverState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BeginFrameObserverState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BeginFrameObserverState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dropped_begin_frame_args() const { return at<1>().valid(); }
+  int64_t dropped_begin_frame_args() const { return at<1>().as_int64(); }
+  bool has_last_begin_frame_args() const { return at<2>().valid(); }
+  ::protozero::ConstBytes last_begin_frame_args() const { return at<2>().as_bytes(); }
+};
+
+class BeginFrameObserverState : public ::protozero::Message {
+ public:
+  using Decoder = BeginFrameObserverState_Decoder;
+  enum : int32_t {
+    kDroppedBeginFrameArgsFieldNumber = 1,
+    kLastBeginFrameArgsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BeginFrameObserverState"; }
+
+
+  using FieldMetadata_DroppedBeginFrameArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameObserverState>;
+
+  static constexpr FieldMetadata_DroppedBeginFrameArgs kDroppedBeginFrameArgs{};
+  void set_dropped_begin_frame_args(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DroppedBeginFrameArgs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LastBeginFrameArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameArgs,
+      BeginFrameObserverState>;
+
+  static constexpr FieldMetadata_LastBeginFrameArgs kLastBeginFrameArgs{};
+  template <typename T = BeginFrameArgs> T* set_last_begin_frame_args() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class BeginImplFrameArgs_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BeginImplFrameArgs_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BeginImplFrameArgs_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BeginImplFrameArgs_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_updated_at_us() const { return at<1>().valid(); }
+  int64_t updated_at_us() const { return at<1>().as_int64(); }
+  bool has_finished_at_us() const { return at<2>().valid(); }
+  int64_t finished_at_us() const { return at<2>().as_int64(); }
+  bool has_state() const { return at<3>().valid(); }
+  int32_t state() const { return at<3>().as_int32(); }
+  bool has_current_args() const { return at<4>().valid(); }
+  ::protozero::ConstBytes current_args() const { return at<4>().as_bytes(); }
+  bool has_last_args() const { return at<5>().valid(); }
+  ::protozero::ConstBytes last_args() const { return at<5>().as_bytes(); }
+  bool has_timestamps_in_us() const { return at<6>().valid(); }
+  ::protozero::ConstBytes timestamps_in_us() const { return at<6>().as_bytes(); }
+};
+
+class BeginImplFrameArgs : public ::protozero::Message {
+ public:
+  using Decoder = BeginImplFrameArgs_Decoder;
+  enum : int32_t {
+    kUpdatedAtUsFieldNumber = 1,
+    kFinishedAtUsFieldNumber = 2,
+    kStateFieldNumber = 3,
+    kCurrentArgsFieldNumber = 4,
+    kLastArgsFieldNumber = 5,
+    kTimestampsInUsFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BeginImplFrameArgs"; }
+
+  using TimestampsInUs = ::perfetto::protos::pbzero::BeginImplFrameArgs_TimestampsInUs;
+
+  using State = ::perfetto::protos::pbzero::BeginImplFrameArgs_State;
+  static inline const char* State_Name(State value) {
+    return ::perfetto::protos::pbzero::BeginImplFrameArgs_State_Name(value);
+  }
+  static inline const State BEGIN_FRAME_FINISHED = State::BEGIN_FRAME_FINISHED;
+  static inline const State BEGIN_FRAME_USING = State::BEGIN_FRAME_USING;
+
+  using FieldMetadata_UpdatedAtUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_UpdatedAtUs kUpdatedAtUs{};
+  void set_updated_at_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UpdatedAtUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FinishedAtUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_FinishedAtUs kFinishedAtUs{};
+  void set_finished_at_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FinishedAtUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::BeginImplFrameArgs_State,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(::perfetto::protos::pbzero::BeginImplFrameArgs_State value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CurrentArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameArgs,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_CurrentArgs kCurrentArgs{};
+  template <typename T = BeginFrameArgs> T* set_current_args() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_LastArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameArgs,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_LastArgs kLastArgs{};
+  template <typename T = BeginFrameArgs> T* set_last_args() {
+    return BeginNestedMessage<T>(5);
+  }
+
+
+  using FieldMetadata_TimestampsInUs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginImplFrameArgs_TimestampsInUs,
+      BeginImplFrameArgs>;
+
+  static constexpr FieldMetadata_TimestampsInUs kTimestampsInUs{};
+  template <typename T = BeginImplFrameArgs_TimestampsInUs> T* set_timestamps_in_us() {
+    return BeginNestedMessage<T>(6);
+  }
+
+};
+
+class BeginImplFrameArgs_TimestampsInUs_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BeginImplFrameArgs_TimestampsInUs_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BeginImplFrameArgs_TimestampsInUs_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BeginImplFrameArgs_TimestampsInUs_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_interval_delta() const { return at<1>().valid(); }
+  int64_t interval_delta() const { return at<1>().as_int64(); }
+  bool has_now_to_deadline_delta() const { return at<2>().valid(); }
+  int64_t now_to_deadline_delta() const { return at<2>().as_int64(); }
+  bool has_frame_time_to_now_delta() const { return at<3>().valid(); }
+  int64_t frame_time_to_now_delta() const { return at<3>().as_int64(); }
+  bool has_frame_time_to_deadline_delta() const { return at<4>().valid(); }
+  int64_t frame_time_to_deadline_delta() const { return at<4>().as_int64(); }
+  bool has_now() const { return at<5>().valid(); }
+  int64_t now() const { return at<5>().as_int64(); }
+  bool has_frame_time() const { return at<6>().valid(); }
+  int64_t frame_time() const { return at<6>().as_int64(); }
+  bool has_deadline() const { return at<7>().valid(); }
+  int64_t deadline() const { return at<7>().as_int64(); }
+};
+
+class BeginImplFrameArgs_TimestampsInUs : public ::protozero::Message {
+ public:
+  using Decoder = BeginImplFrameArgs_TimestampsInUs_Decoder;
+  enum : int32_t {
+    kIntervalDeltaFieldNumber = 1,
+    kNowToDeadlineDeltaFieldNumber = 2,
+    kFrameTimeToNowDeltaFieldNumber = 3,
+    kFrameTimeToDeadlineDeltaFieldNumber = 4,
+    kNowFieldNumber = 5,
+    kFrameTimeFieldNumber = 6,
+    kDeadlineFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BeginImplFrameArgs.TimestampsInUs"; }
+
+
+  using FieldMetadata_IntervalDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_IntervalDelta kIntervalDelta{};
+  void set_interval_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntervalDelta::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NowToDeadlineDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_NowToDeadlineDelta kNowToDeadlineDelta{};
+  void set_now_to_deadline_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NowToDeadlineDelta::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameTimeToNowDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_FrameTimeToNowDelta kFrameTimeToNowDelta{};
+  void set_frame_time_to_now_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameTimeToNowDelta::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameTimeToDeadlineDelta =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_FrameTimeToDeadlineDelta kFrameTimeToDeadlineDelta{};
+  void set_frame_time_to_deadline_delta(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameTimeToDeadlineDelta::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Now =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_Now kNow{};
+  void set_now(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Now::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameTime =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_FrameTime kFrameTime{};
+  void set_frame_time(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameTime::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Deadline =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginImplFrameArgs_TimestampsInUs>;
+
+  static constexpr FieldMetadata_Deadline kDeadline{};
+  void set_deadline(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Deadline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class BeginFrameArgs_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/12, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BeginFrameArgs_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BeginFrameArgs_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BeginFrameArgs_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_type() const { return at<1>().valid(); }
+  int32_t type() const { return at<1>().as_int32(); }
+  bool has_source_id() const { return at<2>().valid(); }
+  uint64_t source_id() const { return at<2>().as_uint64(); }
+  bool has_sequence_number() const { return at<3>().valid(); }
+  uint64_t sequence_number() const { return at<3>().as_uint64(); }
+  bool has_frame_time_us() const { return at<4>().valid(); }
+  int64_t frame_time_us() const { return at<4>().as_int64(); }
+  bool has_deadline_us() const { return at<5>().valid(); }
+  int64_t deadline_us() const { return at<5>().as_int64(); }
+  bool has_interval_delta_us() const { return at<6>().valid(); }
+  int64_t interval_delta_us() const { return at<6>().as_int64(); }
+  bool has_on_critical_path() const { return at<7>().valid(); }
+  bool on_critical_path() const { return at<7>().as_bool(); }
+  bool has_animate_only() const { return at<8>().valid(); }
+  bool animate_only() const { return at<8>().as_bool(); }
+  bool has_source_location_iid() const { return at<9>().valid(); }
+  uint64_t source_location_iid() const { return at<9>().as_uint64(); }
+  bool has_source_location() const { return at<10>().valid(); }
+  ::protozero::ConstBytes source_location() const { return at<10>().as_bytes(); }
+  bool has_frames_throttled_since_last() const { return at<12>().valid(); }
+  int64_t frames_throttled_since_last() const { return at<12>().as_int64(); }
+};
+
+class BeginFrameArgs : public ::protozero::Message {
+ public:
+  using Decoder = BeginFrameArgs_Decoder;
+  enum : int32_t {
+    kTypeFieldNumber = 1,
+    kSourceIdFieldNumber = 2,
+    kSequenceNumberFieldNumber = 3,
+    kFrameTimeUsFieldNumber = 4,
+    kDeadlineUsFieldNumber = 5,
+    kIntervalDeltaUsFieldNumber = 6,
+    kOnCriticalPathFieldNumber = 7,
+    kAnimateOnlyFieldNumber = 8,
+    kSourceLocationIidFieldNumber = 9,
+    kSourceLocationFieldNumber = 10,
+    kFramesThrottledSinceLastFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BeginFrameArgs"; }
+
+
+  using BeginFrameArgsType = ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType;
+  static inline const char* BeginFrameArgsType_Name(BeginFrameArgsType value) {
+    return ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType_Name(value);
+  }
+  static inline const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
+  static inline const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_INVALID = BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_INVALID;
+  static inline const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_NORMAL = BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_NORMAL;
+  static inline const BeginFrameArgsType BEGIN_FRAME_ARGS_TYPE_MISSED = BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_MISSED;
+
+  using FieldMetadata_Type =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_Type kType{};
+  void set_type(::perfetto::protos::pbzero::BeginFrameArgs_BeginFrameArgsType value) {
+    static constexpr uint32_t field_id = FieldMetadata_Type::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_SourceId kSourceId{};
+  void set_source_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SequenceNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_SequenceNumber kSequenceNumber{};
+  void set_sequence_number(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SequenceNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_FrameTimeUs kFrameTimeUs{};
+  void set_frame_time_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameTimeUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeadlineUs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_DeadlineUs kDeadlineUs{};
+  void set_deadline_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeadlineUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntervalDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_IntervalDeltaUs kIntervalDeltaUs{};
+  void set_interval_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntervalDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OnCriticalPath =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_OnCriticalPath kOnCriticalPath{};
+  void set_on_critical_path(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_OnCriticalPath::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AnimateOnly =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_AnimateOnly kAnimateOnly{};
+  void set_animate_only(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AnimateOnly::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SourceLocationIid =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid{};
+  void set_source_location_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceLocationIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SourceLocation =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SourceLocation,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_SourceLocation kSourceLocation{};
+  template <typename T = SourceLocation> T* set_source_location() {
+    return BeginNestedMessage<T>(10);
+  }
+
+
+  using FieldMetadata_FramesThrottledSinceLast =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BeginFrameArgs>;
+
+  static constexpr FieldMetadata_FramesThrottledSinceLast kFramesThrottledSinceLast{};
+  void set_frames_throttled_since_last(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FramesThrottledSinceLast::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeCompositorStateMachine_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeCompositorStateMachine_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeCompositorStateMachine_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeCompositorStateMachine_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_major_state() const { return at<1>().valid(); }
+  ::protozero::ConstBytes major_state() const { return at<1>().as_bytes(); }
+  bool has_minor_state() const { return at<2>().valid(); }
+  ::protozero::ConstBytes minor_state() const { return at<2>().as_bytes(); }
+};
+
+class ChromeCompositorStateMachine : public ::protozero::Message {
+ public:
+  using Decoder = ChromeCompositorStateMachine_Decoder;
+  enum : int32_t {
+    kMajorStateFieldNumber = 1,
+    kMinorStateFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeCompositorStateMachine"; }
+
+  using MajorState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState;
+  using MinorState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState;
+
+  using FieldMetadata_MajorState =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeCompositorStateMachine_MajorState,
+      ChromeCompositorStateMachine>;
+
+  static constexpr FieldMetadata_MajorState kMajorState{};
+  template <typename T = ChromeCompositorStateMachine_MajorState> T* set_major_state() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_MinorState =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeCompositorStateMachine_MinorState,
+      ChromeCompositorStateMachine>;
+
+  static constexpr FieldMetadata_MinorState kMinorState{};
+  template <typename T = ChromeCompositorStateMachine_MinorState> T* set_minor_state() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class ChromeCompositorStateMachine_MinorState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/46, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeCompositorStateMachine_MinorState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeCompositorStateMachine_MinorState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeCompositorStateMachine_MinorState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_commit_count() const { return at<1>().valid(); }
+  int32_t commit_count() const { return at<1>().as_int32(); }
+  bool has_current_frame_number() const { return at<2>().valid(); }
+  int32_t current_frame_number() const { return at<2>().as_int32(); }
+  bool has_last_frame_number_submit_performed() const { return at<3>().valid(); }
+  int32_t last_frame_number_submit_performed() const { return at<3>().as_int32(); }
+  bool has_last_frame_number_draw_performed() const { return at<4>().valid(); }
+  int32_t last_frame_number_draw_performed() const { return at<4>().as_int32(); }
+  bool has_last_frame_number_begin_main_frame_sent() const { return at<5>().valid(); }
+  int32_t last_frame_number_begin_main_frame_sent() const { return at<5>().as_int32(); }
+  bool has_did_draw() const { return at<6>().valid(); }
+  bool did_draw() const { return at<6>().as_bool(); }
+  bool has_did_send_begin_main_frame_for_current_frame() const { return at<7>().valid(); }
+  bool did_send_begin_main_frame_for_current_frame() const { return at<7>().as_bool(); }
+  bool has_did_notify_begin_main_frame_not_expected_until() const { return at<8>().valid(); }
+  bool did_notify_begin_main_frame_not_expected_until() const { return at<8>().as_bool(); }
+  bool has_did_notify_begin_main_frame_not_expected_soon() const { return at<9>().valid(); }
+  bool did_notify_begin_main_frame_not_expected_soon() const { return at<9>().as_bool(); }
+  bool has_wants_begin_main_frame_not_expected() const { return at<10>().valid(); }
+  bool wants_begin_main_frame_not_expected() const { return at<10>().as_bool(); }
+  bool has_did_commit_during_frame() const { return at<11>().valid(); }
+  bool did_commit_during_frame() const { return at<11>().as_bool(); }
+  bool has_did_invalidate_layer_tree_frame_sink() const { return at<12>().valid(); }
+  bool did_invalidate_layer_tree_frame_sink() const { return at<12>().as_bool(); }
+  bool has_did_perform_impl_side_invalidaion() const { return at<13>().valid(); }
+  bool did_perform_impl_side_invalidaion() const { return at<13>().as_bool(); }
+  bool has_did_prepare_tiles() const { return at<14>().valid(); }
+  bool did_prepare_tiles() const { return at<14>().as_bool(); }
+  bool has_consecutive_checkerboard_animations() const { return at<15>().valid(); }
+  int32_t consecutive_checkerboard_animations() const { return at<15>().as_int32(); }
+  bool has_pending_submit_frames() const { return at<16>().valid(); }
+  int32_t pending_submit_frames() const { return at<16>().as_int32(); }
+  bool has_submit_frames_with_current_layer_tree_frame_sink() const { return at<17>().valid(); }
+  int32_t submit_frames_with_current_layer_tree_frame_sink() const { return at<17>().as_int32(); }
+  bool has_needs_redraw() const { return at<18>().valid(); }
+  bool needs_redraw() const { return at<18>().as_bool(); }
+  bool has_needs_prepare_tiles() const { return at<19>().valid(); }
+  bool needs_prepare_tiles() const { return at<19>().as_bool(); }
+  bool has_needs_begin_main_frame() const { return at<20>().valid(); }
+  bool needs_begin_main_frame() const { return at<20>().as_bool(); }
+  bool has_needs_one_begin_impl_frame() const { return at<21>().valid(); }
+  bool needs_one_begin_impl_frame() const { return at<21>().as_bool(); }
+  bool has_visible() const { return at<22>().valid(); }
+  bool visible() const { return at<22>().as_bool(); }
+  bool has_begin_frame_source_paused() const { return at<23>().valid(); }
+  bool begin_frame_source_paused() const { return at<23>().as_bool(); }
+  bool has_can_draw() const { return at<24>().valid(); }
+  bool can_draw() const { return at<24>().as_bool(); }
+  bool has_resourceless_draw() const { return at<25>().valid(); }
+  bool resourceless_draw() const { return at<25>().as_bool(); }
+  bool has_has_pending_tree() const { return at<26>().valid(); }
+  bool has_pending_tree() const { return at<26>().as_bool(); }
+  bool has_pending_tree_is_ready_for_activation() const { return at<27>().valid(); }
+  bool pending_tree_is_ready_for_activation() const { return at<27>().as_bool(); }
+  bool has_active_tree_needs_first_draw() const { return at<28>().valid(); }
+  bool active_tree_needs_first_draw() const { return at<28>().as_bool(); }
+  bool has_active_tree_is_ready_to_draw() const { return at<29>().valid(); }
+  bool active_tree_is_ready_to_draw() const { return at<29>().as_bool(); }
+  bool has_did_create_and_initialize_first_layer_tree_frame_sink() const { return at<30>().valid(); }
+  bool did_create_and_initialize_first_layer_tree_frame_sink() const { return at<30>().as_bool(); }
+  bool has_tree_priority() const { return at<31>().valid(); }
+  int32_t tree_priority() const { return at<31>().as_int32(); }
+  bool has_scroll_handler_state() const { return at<32>().valid(); }
+  int32_t scroll_handler_state() const { return at<32>().as_int32(); }
+  bool has_critical_begin_main_frame_to_activate_is_fast() const { return at<33>().valid(); }
+  bool critical_begin_main_frame_to_activate_is_fast() const { return at<33>().as_bool(); }
+  bool has_main_thread_missed_last_deadline() const { return at<34>().valid(); }
+  bool main_thread_missed_last_deadline() const { return at<34>().as_bool(); }
+  bool has_video_needs_begin_frames() const { return at<36>().valid(); }
+  bool video_needs_begin_frames() const { return at<36>().as_bool(); }
+  bool has_defer_begin_main_frame() const { return at<37>().valid(); }
+  bool defer_begin_main_frame() const { return at<37>().as_bool(); }
+  bool has_last_commit_had_no_updates() const { return at<38>().valid(); }
+  bool last_commit_had_no_updates() const { return at<38>().as_bool(); }
+  bool has_did_draw_in_last_frame() const { return at<39>().valid(); }
+  bool did_draw_in_last_frame() const { return at<39>().as_bool(); }
+  bool has_did_submit_in_last_frame() const { return at<40>().valid(); }
+  bool did_submit_in_last_frame() const { return at<40>().as_bool(); }
+  bool has_needs_impl_side_invalidation() const { return at<41>().valid(); }
+  bool needs_impl_side_invalidation() const { return at<41>().as_bool(); }
+  bool has_current_pending_tree_is_impl_side() const { return at<42>().valid(); }
+  bool current_pending_tree_is_impl_side() const { return at<42>().as_bool(); }
+  bool has_previous_pending_tree_was_impl_side() const { return at<43>().valid(); }
+  bool previous_pending_tree_was_impl_side() const { return at<43>().as_bool(); }
+  bool has_processing_animation_worklets_for_active_tree() const { return at<44>().valid(); }
+  bool processing_animation_worklets_for_active_tree() const { return at<44>().as_bool(); }
+  bool has_processing_animation_worklets_for_pending_tree() const { return at<45>().valid(); }
+  bool processing_animation_worklets_for_pending_tree() const { return at<45>().as_bool(); }
+  bool has_processing_paint_worklets_for_pending_tree() const { return at<46>().valid(); }
+  bool processing_paint_worklets_for_pending_tree() const { return at<46>().as_bool(); }
+};
+
+class ChromeCompositorStateMachine_MinorState : public ::protozero::Message {
+ public:
+  using Decoder = ChromeCompositorStateMachine_MinorState_Decoder;
+  enum : int32_t {
+    kCommitCountFieldNumber = 1,
+    kCurrentFrameNumberFieldNumber = 2,
+    kLastFrameNumberSubmitPerformedFieldNumber = 3,
+    kLastFrameNumberDrawPerformedFieldNumber = 4,
+    kLastFrameNumberBeginMainFrameSentFieldNumber = 5,
+    kDidDrawFieldNumber = 6,
+    kDidSendBeginMainFrameForCurrentFrameFieldNumber = 7,
+    kDidNotifyBeginMainFrameNotExpectedUntilFieldNumber = 8,
+    kDidNotifyBeginMainFrameNotExpectedSoonFieldNumber = 9,
+    kWantsBeginMainFrameNotExpectedFieldNumber = 10,
+    kDidCommitDuringFrameFieldNumber = 11,
+    kDidInvalidateLayerTreeFrameSinkFieldNumber = 12,
+    kDidPerformImplSideInvalidaionFieldNumber = 13,
+    kDidPrepareTilesFieldNumber = 14,
+    kConsecutiveCheckerboardAnimationsFieldNumber = 15,
+    kPendingSubmitFramesFieldNumber = 16,
+    kSubmitFramesWithCurrentLayerTreeFrameSinkFieldNumber = 17,
+    kNeedsRedrawFieldNumber = 18,
+    kNeedsPrepareTilesFieldNumber = 19,
+    kNeedsBeginMainFrameFieldNumber = 20,
+    kNeedsOneBeginImplFrameFieldNumber = 21,
+    kVisibleFieldNumber = 22,
+    kBeginFrameSourcePausedFieldNumber = 23,
+    kCanDrawFieldNumber = 24,
+    kResourcelessDrawFieldNumber = 25,
+    kHasPendingTreeFieldNumber = 26,
+    kPendingTreeIsReadyForActivationFieldNumber = 27,
+    kActiveTreeNeedsFirstDrawFieldNumber = 28,
+    kActiveTreeIsReadyToDrawFieldNumber = 29,
+    kDidCreateAndInitializeFirstLayerTreeFrameSinkFieldNumber = 30,
+    kTreePriorityFieldNumber = 31,
+    kScrollHandlerStateFieldNumber = 32,
+    kCriticalBeginMainFrameToActivateIsFastFieldNumber = 33,
+    kMainThreadMissedLastDeadlineFieldNumber = 34,
+    kVideoNeedsBeginFramesFieldNumber = 36,
+    kDeferBeginMainFrameFieldNumber = 37,
+    kLastCommitHadNoUpdatesFieldNumber = 38,
+    kDidDrawInLastFrameFieldNumber = 39,
+    kDidSubmitInLastFrameFieldNumber = 40,
+    kNeedsImplSideInvalidationFieldNumber = 41,
+    kCurrentPendingTreeIsImplSideFieldNumber = 42,
+    kPreviousPendingTreeWasImplSideFieldNumber = 43,
+    kProcessingAnimationWorkletsForActiveTreeFieldNumber = 44,
+    kProcessingAnimationWorkletsForPendingTreeFieldNumber = 45,
+    kProcessingPaintWorkletsForPendingTreeFieldNumber = 46,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeCompositorStateMachine.MinorState"; }
+
+
+  using TreePriority = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority;
+  static inline const char* TreePriority_Name(TreePriority value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority_Name(value);
+  }
+
+  using ScrollHandlerState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState;
+  static inline const char* ScrollHandlerState_Name(ScrollHandlerState value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState_Name(value);
+  }
+  static inline const TreePriority TREE_PRIORITY_UNSPECIFIED = TreePriority::TREE_PRIORITY_UNSPECIFIED;
+  static inline const TreePriority TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = TreePriority::TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES;
+  static inline const TreePriority TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = TreePriority::TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY;
+  static inline const TreePriority TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = TreePriority::TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+  static inline const ScrollHandlerState SCROLL_HANDLER_UNSPECIFIED = ScrollHandlerState::SCROLL_HANDLER_UNSPECIFIED;
+  static inline const ScrollHandlerState SCROLL_AFFECTS_SCROLL_HANDLER = ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER;
+  static inline const ScrollHandlerState SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
+
+  using FieldMetadata_CommitCount =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_CommitCount kCommitCount{};
+  void set_commit_count(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CommitCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CurrentFrameNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_CurrentFrameNumber kCurrentFrameNumber{};
+  void set_current_frame_number(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentFrameNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LastFrameNumberSubmitPerformed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_LastFrameNumberSubmitPerformed kLastFrameNumberSubmitPerformed{};
+  void set_last_frame_number_submit_performed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastFrameNumberSubmitPerformed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LastFrameNumberDrawPerformed =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_LastFrameNumberDrawPerformed kLastFrameNumberDrawPerformed{};
+  void set_last_frame_number_draw_performed(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastFrameNumberDrawPerformed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LastFrameNumberBeginMainFrameSent =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_LastFrameNumberBeginMainFrameSent kLastFrameNumberBeginMainFrameSent{};
+  void set_last_frame_number_begin_main_frame_sent(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastFrameNumberBeginMainFrameSent::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidDraw =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidDraw kDidDraw{};
+  void set_did_draw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidDraw::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidSendBeginMainFrameForCurrentFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidSendBeginMainFrameForCurrentFrame kDidSendBeginMainFrameForCurrentFrame{};
+  void set_did_send_begin_main_frame_for_current_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidSendBeginMainFrameForCurrentFrame::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidNotifyBeginMainFrameNotExpectedUntil =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidNotifyBeginMainFrameNotExpectedUntil kDidNotifyBeginMainFrameNotExpectedUntil{};
+  void set_did_notify_begin_main_frame_not_expected_until(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidNotifyBeginMainFrameNotExpectedUntil::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidNotifyBeginMainFrameNotExpectedSoon =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidNotifyBeginMainFrameNotExpectedSoon kDidNotifyBeginMainFrameNotExpectedSoon{};
+  void set_did_notify_begin_main_frame_not_expected_soon(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidNotifyBeginMainFrameNotExpectedSoon::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WantsBeginMainFrameNotExpected =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_WantsBeginMainFrameNotExpected kWantsBeginMainFrameNotExpected{};
+  void set_wants_begin_main_frame_not_expected(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_WantsBeginMainFrameNotExpected::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidCommitDuringFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidCommitDuringFrame kDidCommitDuringFrame{};
+  void set_did_commit_during_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidCommitDuringFrame::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidInvalidateLayerTreeFrameSink =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidInvalidateLayerTreeFrameSink kDidInvalidateLayerTreeFrameSink{};
+  void set_did_invalidate_layer_tree_frame_sink(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidInvalidateLayerTreeFrameSink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidPerformImplSideInvalidaion =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidPerformImplSideInvalidaion kDidPerformImplSideInvalidaion{};
+  void set_did_perform_impl_side_invalidaion(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidPerformImplSideInvalidaion::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidPrepareTiles =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidPrepareTiles kDidPrepareTiles{};
+  void set_did_prepare_tiles(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidPrepareTiles::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ConsecutiveCheckerboardAnimations =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ConsecutiveCheckerboardAnimations kConsecutiveCheckerboardAnimations{};
+  void set_consecutive_checkerboard_animations(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ConsecutiveCheckerboardAnimations::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PendingSubmitFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_PendingSubmitFrames kPendingSubmitFrames{};
+  void set_pending_submit_frames(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PendingSubmitFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SubmitFramesWithCurrentLayerTreeFrameSink =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_SubmitFramesWithCurrentLayerTreeFrameSink kSubmitFramesWithCurrentLayerTreeFrameSink{};
+  void set_submit_frames_with_current_layer_tree_frame_sink(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SubmitFramesWithCurrentLayerTreeFrameSink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NeedsRedraw =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_NeedsRedraw kNeedsRedraw{};
+  void set_needs_redraw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedsRedraw::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NeedsPrepareTiles =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_NeedsPrepareTiles kNeedsPrepareTiles{};
+  void set_needs_prepare_tiles(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedsPrepareTiles::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NeedsBeginMainFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_NeedsBeginMainFrame kNeedsBeginMainFrame{};
+  void set_needs_begin_main_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedsBeginMainFrame::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NeedsOneBeginImplFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      21,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_NeedsOneBeginImplFrame kNeedsOneBeginImplFrame{};
+  void set_needs_one_begin_impl_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedsOneBeginImplFrame::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Visible =
+    ::protozero::proto_utils::FieldMetadata<
+      22,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_Visible kVisible{};
+  void set_visible(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Visible::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BeginFrameSourcePaused =
+    ::protozero::proto_utils::FieldMetadata<
+      23,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_BeginFrameSourcePaused kBeginFrameSourcePaused{};
+  void set_begin_frame_source_paused(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginFrameSourcePaused::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CanDraw =
+    ::protozero::proto_utils::FieldMetadata<
+      24,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_CanDraw kCanDraw{};
+  void set_can_draw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CanDraw::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ResourcelessDraw =
+    ::protozero::proto_utils::FieldMetadata<
+      25,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ResourcelessDraw kResourcelessDraw{};
+  void set_resourceless_draw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ResourcelessDraw::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasPendingTree =
+    ::protozero::proto_utils::FieldMetadata<
+      26,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_HasPendingTree kHasPendingTree{};
+  void set_has_pending_tree(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasPendingTree::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PendingTreeIsReadyForActivation =
+    ::protozero::proto_utils::FieldMetadata<
+      27,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_PendingTreeIsReadyForActivation kPendingTreeIsReadyForActivation{};
+  void set_pending_tree_is_ready_for_activation(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PendingTreeIsReadyForActivation::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ActiveTreeNeedsFirstDraw =
+    ::protozero::proto_utils::FieldMetadata<
+      28,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ActiveTreeNeedsFirstDraw kActiveTreeNeedsFirstDraw{};
+  void set_active_tree_needs_first_draw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActiveTreeNeedsFirstDraw::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ActiveTreeIsReadyToDraw =
+    ::protozero::proto_utils::FieldMetadata<
+      29,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ActiveTreeIsReadyToDraw kActiveTreeIsReadyToDraw{};
+  void set_active_tree_is_ready_to_draw(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActiveTreeIsReadyToDraw::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidCreateAndInitializeFirstLayerTreeFrameSink =
+    ::protozero::proto_utils::FieldMetadata<
+      30,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidCreateAndInitializeFirstLayerTreeFrameSink kDidCreateAndInitializeFirstLayerTreeFrameSink{};
+  void set_did_create_and_initialize_first_layer_tree_frame_sink(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidCreateAndInitializeFirstLayerTreeFrameSink::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TreePriority =
+    ::protozero::proto_utils::FieldMetadata<
+      31,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_TreePriority kTreePriority{};
+  void set_tree_priority(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_TreePriority value) {
+    static constexpr uint32_t field_id = FieldMetadata_TreePriority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ScrollHandlerState =
+    ::protozero::proto_utils::FieldMetadata<
+      32,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ScrollHandlerState kScrollHandlerState{};
+  void set_scroll_handler_state(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MinorState_ScrollHandlerState value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScrollHandlerState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CriticalBeginMainFrameToActivateIsFast =
+    ::protozero::proto_utils::FieldMetadata<
+      33,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_CriticalBeginMainFrameToActivateIsFast kCriticalBeginMainFrameToActivateIsFast{};
+  void set_critical_begin_main_frame_to_activate_is_fast(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CriticalBeginMainFrameToActivateIsFast::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MainThreadMissedLastDeadline =
+    ::protozero::proto_utils::FieldMetadata<
+      34,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_MainThreadMissedLastDeadline kMainThreadMissedLastDeadline{};
+  void set_main_thread_missed_last_deadline(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_MainThreadMissedLastDeadline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VideoNeedsBeginFrames =
+    ::protozero::proto_utils::FieldMetadata<
+      36,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_VideoNeedsBeginFrames kVideoNeedsBeginFrames{};
+  void set_video_needs_begin_frames(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_VideoNeedsBeginFrames::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeferBeginMainFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      37,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DeferBeginMainFrame kDeferBeginMainFrame{};
+  void set_defer_begin_main_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeferBeginMainFrame::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LastCommitHadNoUpdates =
+    ::protozero::proto_utils::FieldMetadata<
+      38,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_LastCommitHadNoUpdates kLastCommitHadNoUpdates{};
+  void set_last_commit_had_no_updates(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastCommitHadNoUpdates::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidDrawInLastFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      39,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidDrawInLastFrame kDidDrawInLastFrame{};
+  void set_did_draw_in_last_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidDrawInLastFrame::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DidSubmitInLastFrame =
+    ::protozero::proto_utils::FieldMetadata<
+      40,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_DidSubmitInLastFrame kDidSubmitInLastFrame{};
+  void set_did_submit_in_last_frame(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_DidSubmitInLastFrame::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NeedsImplSideInvalidation =
+    ::protozero::proto_utils::FieldMetadata<
+      41,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_NeedsImplSideInvalidation kNeedsImplSideInvalidation{};
+  void set_needs_impl_side_invalidation(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_NeedsImplSideInvalidation::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CurrentPendingTreeIsImplSide =
+    ::protozero::proto_utils::FieldMetadata<
+      42,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_CurrentPendingTreeIsImplSide kCurrentPendingTreeIsImplSide{};
+  void set_current_pending_tree_is_impl_side(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentPendingTreeIsImplSide::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PreviousPendingTreeWasImplSide =
+    ::protozero::proto_utils::FieldMetadata<
+      43,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_PreviousPendingTreeWasImplSide kPreviousPendingTreeWasImplSide{};
+  void set_previous_pending_tree_was_impl_side(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PreviousPendingTreeWasImplSide::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessingAnimationWorkletsForActiveTree =
+    ::protozero::proto_utils::FieldMetadata<
+      44,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ProcessingAnimationWorkletsForActiveTree kProcessingAnimationWorkletsForActiveTree{};
+  void set_processing_animation_worklets_for_active_tree(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessingAnimationWorkletsForActiveTree::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessingAnimationWorkletsForPendingTree =
+    ::protozero::proto_utils::FieldMetadata<
+      45,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ProcessingAnimationWorkletsForPendingTree kProcessingAnimationWorkletsForPendingTree{};
+  void set_processing_animation_worklets_for_pending_tree(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessingAnimationWorkletsForPendingTree::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessingPaintWorkletsForPendingTree =
+    ::protozero::proto_utils::FieldMetadata<
+      46,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorStateMachine_MinorState>;
+
+  static constexpr FieldMetadata_ProcessingPaintWorkletsForPendingTree kProcessingPaintWorkletsForPendingTree{};
+  void set_processing_paint_worklets_for_pending_tree(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessingPaintWorkletsForPendingTree::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeCompositorStateMachine_MajorState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeCompositorStateMachine_MajorState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeCompositorStateMachine_MajorState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeCompositorStateMachine_MajorState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_next_action() const { return at<1>().valid(); }
+  int32_t next_action() const { return at<1>().as_int32(); }
+  bool has_begin_impl_frame_state() const { return at<2>().valid(); }
+  int32_t begin_impl_frame_state() const { return at<2>().as_int32(); }
+  bool has_begin_main_frame_state() const { return at<3>().valid(); }
+  int32_t begin_main_frame_state() const { return at<3>().as_int32(); }
+  bool has_layer_tree_frame_sink_state() const { return at<4>().valid(); }
+  int32_t layer_tree_frame_sink_state() const { return at<4>().as_int32(); }
+  bool has_forced_redraw_state() const { return at<5>().valid(); }
+  int32_t forced_redraw_state() const { return at<5>().as_int32(); }
+};
+
+class ChromeCompositorStateMachine_MajorState : public ::protozero::Message {
+ public:
+  using Decoder = ChromeCompositorStateMachine_MajorState_Decoder;
+  enum : int32_t {
+    kNextActionFieldNumber = 1,
+    kBeginImplFrameStateFieldNumber = 2,
+    kBeginMainFrameStateFieldNumber = 3,
+    kLayerTreeFrameSinkStateFieldNumber = 4,
+    kForcedRedrawStateFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeCompositorStateMachine.MajorState"; }
+
+
+  using BeginImplFrameState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState;
+  static inline const char* BeginImplFrameState_Name(BeginImplFrameState value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState_Name(value);
+  }
+
+  using BeginMainFrameState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState;
+  static inline const char* BeginMainFrameState_Name(BeginMainFrameState value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState_Name(value);
+  }
+
+  using LayerTreeFrameSinkState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState;
+  static inline const char* LayerTreeFrameSinkState_Name(LayerTreeFrameSinkState value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_Name(value);
+  }
+
+  using ForcedRedrawOnTimeoutState = ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState;
+  static inline const char* ForcedRedrawOnTimeoutState_Name(ForcedRedrawOnTimeoutState value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_Name(value);
+  }
+  static inline const BeginImplFrameState BEGIN_IMPL_FRAME_UNSPECIFIED = BeginImplFrameState::BEGIN_IMPL_FRAME_UNSPECIFIED;
+  static inline const BeginImplFrameState BEGIN_IMPL_FRAME_IDLE = BeginImplFrameState::BEGIN_IMPL_FRAME_IDLE;
+  static inline const BeginImplFrameState BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = BeginImplFrameState::BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME;
+  static inline const BeginImplFrameState BEGIN_IMPL_FRAME_INSIDE_DEADLINE = BeginImplFrameState::BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
+  static inline const BeginMainFrameState BEGIN_MAIN_FRAME_UNSPECIFIED = BeginMainFrameState::BEGIN_MAIN_FRAME_UNSPECIFIED;
+  static inline const BeginMainFrameState BEGIN_MAIN_FRAME_IDLE = BeginMainFrameState::BEGIN_MAIN_FRAME_IDLE;
+  static inline const BeginMainFrameState BEGIN_MAIN_FRAME_SENT = BeginMainFrameState::BEGIN_MAIN_FRAME_SENT;
+  static inline const BeginMainFrameState BEGIN_MAIN_FRAME_READY_TO_COMMIT = BeginMainFrameState::BEGIN_MAIN_FRAME_READY_TO_COMMIT;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_UNSPECIFIED = LayerTreeFrameSinkState::LAYER_TREE_FRAME_UNSPECIFIED;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_NONE = LayerTreeFrameSinkState::LAYER_TREE_FRAME_NONE;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_ACTIVE = LayerTreeFrameSinkState::LAYER_TREE_FRAME_ACTIVE;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_CREATING = LayerTreeFrameSinkState::LAYER_TREE_FRAME_CREATING;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = LayerTreeFrameSinkState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT;
+  static inline const LayerTreeFrameSinkState LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = LayerTreeFrameSinkState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
+  static inline const ForcedRedrawOnTimeoutState FORCED_REDRAW_UNSPECIFIED = ForcedRedrawOnTimeoutState::FORCED_REDRAW_UNSPECIFIED;
+  static inline const ForcedRedrawOnTimeoutState FORCED_REDRAW_IDLE = ForcedRedrawOnTimeoutState::FORCED_REDRAW_IDLE;
+  static inline const ForcedRedrawOnTimeoutState FORCED_REDRAW_WAITING_FOR_COMMIT = ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_COMMIT;
+  static inline const ForcedRedrawOnTimeoutState FORCED_REDRAW_WAITING_FOR_ACTIVATION = ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_ACTIVATION;
+  static inline const ForcedRedrawOnTimeoutState FORCED_REDRAW_WAITING_FOR_DRAW = ForcedRedrawOnTimeoutState::FORCED_REDRAW_WAITING_FOR_DRAW;
+
+  using FieldMetadata_NextAction =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction,
+      ChromeCompositorStateMachine_MajorState>;
+
+  static constexpr FieldMetadata_NextAction kNextAction{};
+  void set_next_action(::perfetto::protos::pbzero::ChromeCompositorSchedulerAction value) {
+    static constexpr uint32_t field_id = FieldMetadata_NextAction::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BeginImplFrameState =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState,
+      ChromeCompositorStateMachine_MajorState>;
+
+  static constexpr FieldMetadata_BeginImplFrameState kBeginImplFrameState{};
+  void set_begin_impl_frame_state(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginImplFrameState value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginImplFrameState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BeginMainFrameState =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState,
+      ChromeCompositorStateMachine_MajorState>;
+
+  static constexpr FieldMetadata_BeginMainFrameState kBeginMainFrameState{};
+  void set_begin_main_frame_state(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_BeginMainFrameState value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginMainFrameState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerTreeFrameSinkState =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState,
+      ChromeCompositorStateMachine_MajorState>;
+
+  static constexpr FieldMetadata_LayerTreeFrameSinkState kLayerTreeFrameSinkState{};
+  void set_layer_tree_frame_sink_state(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerTreeFrameSinkState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ForcedRedrawState =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState,
+      ChromeCompositorStateMachine_MajorState>;
+
+  static constexpr FieldMetadata_ForcedRedrawState kForcedRedrawState{};
+  void set_forced_redraw_state(::perfetto::protos::pbzero::ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value) {
+    static constexpr uint32_t field_id = FieldMetadata_ForcedRedrawState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeCompositorSchedulerState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/17, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeCompositorSchedulerState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeCompositorSchedulerState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeCompositorSchedulerState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_state_machine() const { return at<1>().valid(); }
+  ::protozero::ConstBytes state_machine() const { return at<1>().as_bytes(); }
+  bool has_observing_begin_frame_source() const { return at<2>().valid(); }
+  bool observing_begin_frame_source() const { return at<2>().as_bool(); }
+  bool has_begin_impl_frame_deadline_task() const { return at<3>().valid(); }
+  bool begin_impl_frame_deadline_task() const { return at<3>().as_bool(); }
+  bool has_pending_begin_frame_task() const { return at<4>().valid(); }
+  bool pending_begin_frame_task() const { return at<4>().as_bool(); }
+  bool has_skipped_last_frame_missed_exceeded_deadline() const { return at<5>().valid(); }
+  bool skipped_last_frame_missed_exceeded_deadline() const { return at<5>().as_bool(); }
+  bool has_inside_action() const { return at<7>().valid(); }
+  int32_t inside_action() const { return at<7>().as_int32(); }
+  bool has_deadline_mode() const { return at<8>().valid(); }
+  int32_t deadline_mode() const { return at<8>().as_int32(); }
+  bool has_deadline_us() const { return at<9>().valid(); }
+  int64_t deadline_us() const { return at<9>().as_int64(); }
+  bool has_deadline_scheduled_at_us() const { return at<10>().valid(); }
+  int64_t deadline_scheduled_at_us() const { return at<10>().as_int64(); }
+  bool has_now_us() const { return at<11>().valid(); }
+  int64_t now_us() const { return at<11>().as_int64(); }
+  bool has_now_to_deadline_delta_us() const { return at<12>().valid(); }
+  int64_t now_to_deadline_delta_us() const { return at<12>().as_int64(); }
+  bool has_now_to_deadline_scheduled_at_delta_us() const { return at<13>().valid(); }
+  int64_t now_to_deadline_scheduled_at_delta_us() const { return at<13>().as_int64(); }
+  bool has_begin_impl_frame_args() const { return at<14>().valid(); }
+  ::protozero::ConstBytes begin_impl_frame_args() const { return at<14>().as_bytes(); }
+  bool has_begin_frame_observer_state() const { return at<15>().valid(); }
+  ::protozero::ConstBytes begin_frame_observer_state() const { return at<15>().as_bytes(); }
+  bool has_begin_frame_source_state() const { return at<16>().valid(); }
+  ::protozero::ConstBytes begin_frame_source_state() const { return at<16>().as_bytes(); }
+  bool has_compositor_timing_history() const { return at<17>().valid(); }
+  ::protozero::ConstBytes compositor_timing_history() const { return at<17>().as_bytes(); }
+};
+
+class ChromeCompositorSchedulerState : public ::protozero::Message {
+ public:
+  using Decoder = ChromeCompositorSchedulerState_Decoder;
+  enum : int32_t {
+    kStateMachineFieldNumber = 1,
+    kObservingBeginFrameSourceFieldNumber = 2,
+    kBeginImplFrameDeadlineTaskFieldNumber = 3,
+    kPendingBeginFrameTaskFieldNumber = 4,
+    kSkippedLastFrameMissedExceededDeadlineFieldNumber = 5,
+    kInsideActionFieldNumber = 7,
+    kDeadlineModeFieldNumber = 8,
+    kDeadlineUsFieldNumber = 9,
+    kDeadlineScheduledAtUsFieldNumber = 10,
+    kNowUsFieldNumber = 11,
+    kNowToDeadlineDeltaUsFieldNumber = 12,
+    kNowToDeadlineScheduledAtDeltaUsFieldNumber = 13,
+    kBeginImplFrameArgsFieldNumber = 14,
+    kBeginFrameObserverStateFieldNumber = 15,
+    kBeginFrameSourceStateFieldNumber = 16,
+    kCompositorTimingHistoryFieldNumber = 17,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeCompositorSchedulerState"; }
+
+
+  using BeginImplFrameDeadlineMode = ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode;
+  static inline const char* BeginImplFrameDeadlineMode_Name(BeginImplFrameDeadlineMode value) {
+    return ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_Name(value);
+  }
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_UNSPECIFIED = BeginImplFrameDeadlineMode::DEADLINE_MODE_UNSPECIFIED;
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_NONE = BeginImplFrameDeadlineMode::DEADLINE_MODE_NONE;
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_IMMEDIATE = BeginImplFrameDeadlineMode::DEADLINE_MODE_IMMEDIATE;
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_REGULAR = BeginImplFrameDeadlineMode::DEADLINE_MODE_REGULAR;
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_LATE = BeginImplFrameDeadlineMode::DEADLINE_MODE_LATE;
+  static inline const BeginImplFrameDeadlineMode DEADLINE_MODE_BLOCKED = BeginImplFrameDeadlineMode::DEADLINE_MODE_BLOCKED;
+
+  using FieldMetadata_StateMachine =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeCompositorStateMachine,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_StateMachine kStateMachine{};
+  template <typename T = ChromeCompositorStateMachine> T* set_state_machine() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ObservingBeginFrameSource =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_ObservingBeginFrameSource kObservingBeginFrameSource{};
+  void set_observing_begin_frame_source(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ObservingBeginFrameSource::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BeginImplFrameDeadlineTask =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_BeginImplFrameDeadlineTask kBeginImplFrameDeadlineTask{};
+  void set_begin_impl_frame_deadline_task(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_BeginImplFrameDeadlineTask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PendingBeginFrameTask =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_PendingBeginFrameTask kPendingBeginFrameTask{};
+  void set_pending_begin_frame_task(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_PendingBeginFrameTask::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SkippedLastFrameMissedExceededDeadline =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_SkippedLastFrameMissedExceededDeadline kSkippedLastFrameMissedExceededDeadline{};
+  void set_skipped_last_frame_missed_exceeded_deadline(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SkippedLastFrameMissedExceededDeadline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_InsideAction =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeCompositorSchedulerAction,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_InsideAction kInsideAction{};
+  void set_inside_action(::perfetto::protos::pbzero::ChromeCompositorSchedulerAction value) {
+    static constexpr uint32_t field_id = FieldMetadata_InsideAction::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeadlineMode =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_DeadlineMode kDeadlineMode{};
+  void set_deadline_mode(::perfetto::protos::pbzero::ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeadlineMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeadlineUs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_DeadlineUs kDeadlineUs{};
+  void set_deadline_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeadlineUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DeadlineScheduledAtUs =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_DeadlineScheduledAtUs kDeadlineScheduledAtUs{};
+  void set_deadline_scheduled_at_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeadlineScheduledAtUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NowUs =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_NowUs kNowUs{};
+  void set_now_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NowUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NowToDeadlineDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_NowToDeadlineDeltaUs kNowToDeadlineDeltaUs{};
+  void set_now_to_deadline_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NowToDeadlineDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NowToDeadlineScheduledAtDeltaUs =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_NowToDeadlineScheduledAtDeltaUs kNowToDeadlineScheduledAtDeltaUs{};
+  void set_now_to_deadline_scheduled_at_delta_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NowToDeadlineScheduledAtDeltaUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BeginImplFrameArgs =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginImplFrameArgs,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_BeginImplFrameArgs kBeginImplFrameArgs{};
+  template <typename T = BeginImplFrameArgs> T* set_begin_impl_frame_args() {
+    return BeginNestedMessage<T>(14);
+  }
+
+
+  using FieldMetadata_BeginFrameObserverState =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameObserverState,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_BeginFrameObserverState kBeginFrameObserverState{};
+  template <typename T = BeginFrameObserverState> T* set_begin_frame_observer_state() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_BeginFrameSourceState =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      BeginFrameSourceState,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_BeginFrameSourceState kBeginFrameSourceState{};
+  template <typename T = BeginFrameSourceState> T* set_begin_frame_source_state() {
+    return BeginNestedMessage<T>(16);
+  }
+
+
+  using FieldMetadata_CompositorTimingHistory =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CompositorTimingHistory,
+      ChromeCompositorSchedulerState>;
+
+  static constexpr FieldMetadata_CompositorTimingHistory kCompositorTimingHistory{};
+  template <typename T = CompositorTimingHistory> T* set_compositor_timing_history() {
+    return BeginNestedMessage<T>(17);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ChromeContentSettingsEventInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeContentSettingsEventInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeContentSettingsEventInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeContentSettingsEventInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_number_of_exceptions() const { return at<1>().valid(); }
+  uint32_t number_of_exceptions() const { return at<1>().as_uint32(); }
+};
+
+class ChromeContentSettingsEventInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeContentSettingsEventInfo_Decoder;
+  enum : int32_t {
+    kNumberOfExceptionsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeContentSettingsEventInfo"; }
+
+
+  using FieldMetadata_NumberOfExceptions =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeContentSettingsEventInfo>;
+
+  static constexpr FieldMetadata_NumberOfExceptions kNumberOfExceptions{};
+  void set_number_of_exceptions(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumberOfExceptions::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum FrameDropReason : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_FrameDropReason = perfetto_pbzero_enum_ChromeFrameReporter::FrameDropReason;
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum FrameType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_FrameType = perfetto_pbzero_enum_ChromeFrameReporter::FrameType;
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum ScrollState : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_ScrollState = perfetto_pbzero_enum_ChromeFrameReporter::ScrollState;
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum State : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_State = perfetto_pbzero_enum_ChromeFrameReporter::State;
+
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum State : int32_t {
+  STATE_NO_UPDATE_DESIRED = 0,
+  STATE_PRESENTED_ALL = 1,
+  STATE_PRESENTED_PARTIAL = 2,
+  STATE_DROPPED = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_State = perfetto_pbzero_enum_ChromeFrameReporter::State;
+
+
+constexpr ChromeFrameReporter_State ChromeFrameReporter_State_MIN = ChromeFrameReporter_State::STATE_NO_UPDATE_DESIRED;
+constexpr ChromeFrameReporter_State ChromeFrameReporter_State_MAX = ChromeFrameReporter_State::STATE_DROPPED;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeFrameReporter_State_Name(::perfetto::protos::pbzero::ChromeFrameReporter_State value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_State::STATE_NO_UPDATE_DESIRED:
+    return "STATE_NO_UPDATE_DESIRED";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_State::STATE_PRESENTED_ALL:
+    return "STATE_PRESENTED_ALL";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_State::STATE_PRESENTED_PARTIAL:
+    return "STATE_PRESENTED_PARTIAL";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_State::STATE_DROPPED:
+    return "STATE_DROPPED";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum FrameDropReason : int32_t {
+  REASON_UNSPECIFIED = 0,
+  REASON_DISPLAY_COMPOSITOR = 1,
+  REASON_MAIN_THREAD = 2,
+  REASON_CLIENT_COMPOSITOR = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_FrameDropReason = perfetto_pbzero_enum_ChromeFrameReporter::FrameDropReason;
+
+
+constexpr ChromeFrameReporter_FrameDropReason ChromeFrameReporter_FrameDropReason_MIN = ChromeFrameReporter_FrameDropReason::REASON_UNSPECIFIED;
+constexpr ChromeFrameReporter_FrameDropReason ChromeFrameReporter_FrameDropReason_MAX = ChromeFrameReporter_FrameDropReason::REASON_CLIENT_COMPOSITOR;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeFrameReporter_FrameDropReason_Name(::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason::REASON_UNSPECIFIED:
+    return "REASON_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason::REASON_DISPLAY_COMPOSITOR:
+    return "REASON_DISPLAY_COMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason::REASON_MAIN_THREAD:
+    return "REASON_MAIN_THREAD";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason::REASON_CLIENT_COMPOSITOR:
+    return "REASON_CLIENT_COMPOSITOR";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum ScrollState : int32_t {
+  SCROLL_NONE = 0,
+  SCROLL_MAIN_THREAD = 1,
+  SCROLL_COMPOSITOR_THREAD = 2,
+  SCROLL_UNKNOWN = 3,
+};
+} // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_ScrollState = perfetto_pbzero_enum_ChromeFrameReporter::ScrollState;
+
+
+constexpr ChromeFrameReporter_ScrollState ChromeFrameReporter_ScrollState_MIN = ChromeFrameReporter_ScrollState::SCROLL_NONE;
+constexpr ChromeFrameReporter_ScrollState ChromeFrameReporter_ScrollState_MAX = ChromeFrameReporter_ScrollState::SCROLL_UNKNOWN;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeFrameReporter_ScrollState_Name(::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState::SCROLL_NONE:
+    return "SCROLL_NONE";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState::SCROLL_MAIN_THREAD:
+    return "SCROLL_MAIN_THREAD";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState::SCROLL_COMPOSITOR_THREAD:
+    return "SCROLL_COMPOSITOR_THREAD";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState::SCROLL_UNKNOWN:
+    return "SCROLL_UNKNOWN";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeFrameReporter {
+enum FrameType : int32_t {
+  FORKED = 0,
+  BACKFILL = 1,
+};
+} // namespace perfetto_pbzero_enum_ChromeFrameReporter
+using ChromeFrameReporter_FrameType = perfetto_pbzero_enum_ChromeFrameReporter::FrameType;
+
+
+constexpr ChromeFrameReporter_FrameType ChromeFrameReporter_FrameType_MIN = ChromeFrameReporter_FrameType::FORKED;
+constexpr ChromeFrameReporter_FrameType ChromeFrameReporter_FrameType_MAX = ChromeFrameReporter_FrameType::BACKFILL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeFrameReporter_FrameType_Name(::perfetto::protos::pbzero::ChromeFrameReporter_FrameType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameType::FORKED:
+    return "FORKED";
+
+  case ::perfetto::protos::pbzero::ChromeFrameReporter_FrameType::BACKFILL:
+    return "BACKFILL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeFrameReporter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/14, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeFrameReporter_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeFrameReporter_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeFrameReporter_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_state() const { return at<1>().valid(); }
+  int32_t state() const { return at<1>().as_int32(); }
+  bool has_reason() const { return at<2>().valid(); }
+  int32_t reason() const { return at<2>().as_int32(); }
+  bool has_frame_source() const { return at<3>().valid(); }
+  uint64_t frame_source() const { return at<3>().as_uint64(); }
+  bool has_frame_sequence() const { return at<4>().valid(); }
+  uint64_t frame_sequence() const { return at<4>().as_uint64(); }
+  bool has_affects_smoothness() const { return at<5>().valid(); }
+  bool affects_smoothness() const { return at<5>().as_bool(); }
+  bool has_scroll_state() const { return at<6>().valid(); }
+  int32_t scroll_state() const { return at<6>().as_int32(); }
+  bool has_has_main_animation() const { return at<7>().valid(); }
+  bool has_main_animation() const { return at<7>().as_bool(); }
+  bool has_has_compositor_animation() const { return at<8>().valid(); }
+  bool has_compositor_animation() const { return at<8>().as_bool(); }
+  bool has_has_smooth_input_main() const { return at<9>().valid(); }
+  bool has_smooth_input_main() const { return at<9>().as_bool(); }
+  bool has_has_missing_content() const { return at<10>().valid(); }
+  bool has_missing_content() const { return at<10>().as_bool(); }
+  bool has_layer_tree_host_id() const { return at<11>().valid(); }
+  uint64_t layer_tree_host_id() const { return at<11>().as_uint64(); }
+  bool has_has_high_latency() const { return at<12>().valid(); }
+  bool has_high_latency() const { return at<12>().as_bool(); }
+  bool has_frame_type() const { return at<13>().valid(); }
+  int32_t frame_type() const { return at<13>().as_int32(); }
+  bool has_high_latency_contribution_stage() const { return at<14>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> high_latency_contribution_stage() const { return GetRepeated<::protozero::ConstChars>(14); }
+};
+
+class ChromeFrameReporter : public ::protozero::Message {
+ public:
+  using Decoder = ChromeFrameReporter_Decoder;
+  enum : int32_t {
+    kStateFieldNumber = 1,
+    kReasonFieldNumber = 2,
+    kFrameSourceFieldNumber = 3,
+    kFrameSequenceFieldNumber = 4,
+    kAffectsSmoothnessFieldNumber = 5,
+    kScrollStateFieldNumber = 6,
+    kHasMainAnimationFieldNumber = 7,
+    kHasCompositorAnimationFieldNumber = 8,
+    kHasSmoothInputMainFieldNumber = 9,
+    kHasMissingContentFieldNumber = 10,
+    kLayerTreeHostIdFieldNumber = 11,
+    kHasHighLatencyFieldNumber = 12,
+    kFrameTypeFieldNumber = 13,
+    kHighLatencyContributionStageFieldNumber = 14,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeFrameReporter"; }
+
+
+  using State = ::perfetto::protos::pbzero::ChromeFrameReporter_State;
+  static inline const char* State_Name(State value) {
+    return ::perfetto::protos::pbzero::ChromeFrameReporter_State_Name(value);
+  }
+
+  using FrameDropReason = ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason;
+  static inline const char* FrameDropReason_Name(FrameDropReason value) {
+    return ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason_Name(value);
+  }
+
+  using ScrollState = ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState;
+  static inline const char* ScrollState_Name(ScrollState value) {
+    return ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState_Name(value);
+  }
+
+  using FrameType = ::perfetto::protos::pbzero::ChromeFrameReporter_FrameType;
+  static inline const char* FrameType_Name(FrameType value) {
+    return ::perfetto::protos::pbzero::ChromeFrameReporter_FrameType_Name(value);
+  }
+  static inline const State STATE_NO_UPDATE_DESIRED = State::STATE_NO_UPDATE_DESIRED;
+  static inline const State STATE_PRESENTED_ALL = State::STATE_PRESENTED_ALL;
+  static inline const State STATE_PRESENTED_PARTIAL = State::STATE_PRESENTED_PARTIAL;
+  static inline const State STATE_DROPPED = State::STATE_DROPPED;
+  static inline const FrameDropReason REASON_UNSPECIFIED = FrameDropReason::REASON_UNSPECIFIED;
+  static inline const FrameDropReason REASON_DISPLAY_COMPOSITOR = FrameDropReason::REASON_DISPLAY_COMPOSITOR;
+  static inline const FrameDropReason REASON_MAIN_THREAD = FrameDropReason::REASON_MAIN_THREAD;
+  static inline const FrameDropReason REASON_CLIENT_COMPOSITOR = FrameDropReason::REASON_CLIENT_COMPOSITOR;
+  static inline const ScrollState SCROLL_NONE = ScrollState::SCROLL_NONE;
+  static inline const ScrollState SCROLL_MAIN_THREAD = ScrollState::SCROLL_MAIN_THREAD;
+  static inline const ScrollState SCROLL_COMPOSITOR_THREAD = ScrollState::SCROLL_COMPOSITOR_THREAD;
+  static inline const ScrollState SCROLL_UNKNOWN = ScrollState::SCROLL_UNKNOWN;
+  static inline const FrameType FORKED = FrameType::FORKED;
+  static inline const FrameType BACKFILL = FrameType::BACKFILL;
+
+  using FieldMetadata_State =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeFrameReporter_State,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_State kState{};
+  void set_state(::perfetto::protos::pbzero::ChromeFrameReporter_State value) {
+    static constexpr uint32_t field_id = FieldMetadata_State::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Reason =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_Reason kReason{};
+  void set_reason(::perfetto::protos::pbzero::ChromeFrameReporter_FrameDropReason value) {
+    static constexpr uint32_t field_id = FieldMetadata_Reason::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameSource =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_FrameSource kFrameSource{};
+  void set_frame_source(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameSource::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameSequence =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_FrameSequence kFrameSequence{};
+  void set_frame_sequence(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameSequence::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AffectsSmoothness =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_AffectsSmoothness kAffectsSmoothness{};
+  void set_affects_smoothness(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AffectsSmoothness::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ScrollState =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_ScrollState kScrollState{};
+  void set_scroll_state(::perfetto::protos::pbzero::ChromeFrameReporter_ScrollState value) {
+    static constexpr uint32_t field_id = FieldMetadata_ScrollState::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasMainAnimation =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HasMainAnimation kHasMainAnimation{};
+  void set_has_main_animation(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasMainAnimation::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasCompositorAnimation =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HasCompositorAnimation kHasCompositorAnimation{};
+  void set_has_compositor_animation(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasCompositorAnimation::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasSmoothInputMain =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HasSmoothInputMain kHasSmoothInputMain{};
+  void set_has_smooth_input_main(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasSmoothInputMain::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasMissingContent =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HasMissingContent kHasMissingContent{};
+  void set_has_missing_content(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasMissingContent::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LayerTreeHostId =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_LayerTreeHostId kLayerTreeHostId{};
+  void set_layer_tree_host_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LayerTreeHostId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasHighLatency =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HasHighLatency kHasHighLatency{};
+  void set_has_high_latency(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasHighLatency::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameType =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeFrameReporter_FrameType,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_FrameType kFrameType{};
+  void set_frame_type(::perfetto::protos::pbzero::ChromeFrameReporter_FrameType value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HighLatencyContributionStage =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeFrameReporter>;
+
+  static constexpr FieldMetadata_HighLatencyContributionStage kHighLatencyContributionStage{};
+  void add_high_latency_contribution_stage(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HighLatencyContributionStage::kFieldId, data, size);
+  }
+  void add_high_latency_contribution_stage(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HighLatencyContributionStage::kFieldId, chars.data, chars.size);
+  }
+  void add_high_latency_contribution_stage(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HighLatencyContributionStage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ChromeHistogramSample_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeHistogramSample_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeHistogramSample_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeHistogramSample_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name_hash() const { return at<1>().valid(); }
+  uint64_t name_hash() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_sample() const { return at<3>().valid(); }
+  int64_t sample() const { return at<3>().as_int64(); }
+  bool has_name_iid() const { return at<4>().valid(); }
+  uint64_t name_iid() const { return at<4>().as_uint64(); }
+};
+
+class ChromeHistogramSample : public ::protozero::Message {
+ public:
+  using Decoder = ChromeHistogramSample_Decoder;
+  enum : int32_t {
+    kNameHashFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kSampleFieldNumber = 3,
+    kNameIidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeHistogramSample"; }
+
+
+  using FieldMetadata_NameHash =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeHistogramSample>;
+
+  static constexpr FieldMetadata_NameHash kNameHash{};
+  void set_name_hash(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeHistogramSample>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Sample =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeHistogramSample>;
+
+  static constexpr FieldMetadata_Sample kSample{};
+  void set_sample(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Sample::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeHistogramSample>;
+
+  static constexpr FieldMetadata_NameIid kNameIid{};
+  void set_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NameIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class HistogramName_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  HistogramName_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit HistogramName_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit HistogramName_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+};
+
+class HistogramName : public ::protozero::Message {
+ public:
+  using Decoder = HistogramName_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.HistogramName"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      HistogramName>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      HistogramName>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ChromeKeyedService_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeKeyedService_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeKeyedService_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeKeyedService_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+};
+
+class ChromeKeyedService : public ::protozero::Message {
+ public:
+  using Decoder = ChromeKeyedService_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeKeyedService"; }
+
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeKeyedService>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeLatencyInfo_ComponentInfo;
+namespace perfetto_pbzero_enum_ChromeLatencyInfo {
+enum LatencyComponentType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeLatencyInfo
+using ChromeLatencyInfo_LatencyComponentType = perfetto_pbzero_enum_ChromeLatencyInfo::LatencyComponentType;
+namespace perfetto_pbzero_enum_ChromeLatencyInfo {
+enum Step : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeLatencyInfo
+using ChromeLatencyInfo_Step = perfetto_pbzero_enum_ChromeLatencyInfo::Step;
+
+namespace perfetto_pbzero_enum_ChromeLatencyInfo {
+enum Step : int32_t {
+  STEP_UNSPECIFIED = 0,
+  STEP_SEND_INPUT_EVENT_UI = 3,
+  STEP_HANDLE_INPUT_EVENT_IMPL = 5,
+  STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = 8,
+  STEP_HANDLE_INPUT_EVENT_MAIN = 4,
+  STEP_MAIN_THREAD_SCROLL_UPDATE = 2,
+  STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = 1,
+  STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = 9,
+  STEP_HANDLED_INPUT_EVENT_IMPL = 10,
+  STEP_SWAP_BUFFERS = 6,
+  STEP_DRAW_AND_SWAP = 7,
+  STEP_FINISHED_SWAP_BUFFERS = 11,
+};
+} // namespace perfetto_pbzero_enum_ChromeLatencyInfo
+using ChromeLatencyInfo_Step = perfetto_pbzero_enum_ChromeLatencyInfo::Step;
+
+
+constexpr ChromeLatencyInfo_Step ChromeLatencyInfo_Step_MIN = ChromeLatencyInfo_Step::STEP_UNSPECIFIED;
+constexpr ChromeLatencyInfo_Step ChromeLatencyInfo_Step_MAX = ChromeLatencyInfo_Step::STEP_FINISHED_SWAP_BUFFERS;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeLatencyInfo_Step_Name(::perfetto::protos::pbzero::ChromeLatencyInfo_Step value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_UNSPECIFIED:
+    return "STEP_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_SEND_INPUT_EVENT_UI:
+    return "STEP_SEND_INPUT_EVENT_UI";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_HANDLE_INPUT_EVENT_IMPL:
+    return "STEP_HANDLE_INPUT_EVENT_IMPL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_DID_HANDLE_INPUT_AND_OVERSCROLL:
+    return "STEP_DID_HANDLE_INPUT_AND_OVERSCROLL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_HANDLE_INPUT_EVENT_MAIN:
+    return "STEP_HANDLE_INPUT_EVENT_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_MAIN_THREAD_SCROLL_UPDATE:
+    return "STEP_MAIN_THREAD_SCROLL_UPDATE";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT:
+    return "STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL:
+    return "STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_HANDLED_INPUT_EVENT_IMPL:
+    return "STEP_HANDLED_INPUT_EVENT_IMPL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_SWAP_BUFFERS:
+    return "STEP_SWAP_BUFFERS";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_DRAW_AND_SWAP:
+    return "STEP_DRAW_AND_SWAP";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_Step::STEP_FINISHED_SWAP_BUFFERS:
+    return "STEP_FINISHED_SWAP_BUFFERS";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_ChromeLatencyInfo {
+enum LatencyComponentType : int32_t {
+  COMPONENT_UNSPECIFIED = 0,
+  COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = 1,
+  COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = 2,
+  COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = 3,
+  COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = 4,
+  COMPONENT_INPUT_EVENT_LATENCY_UI = 5,
+  COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = 6,
+  COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = 7,
+  COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = 8,
+  COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = 9,
+  COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = 10,
+  COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = 11,
+  COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = 12,
+  COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = 13,
+  COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = 14,
+};
+} // namespace perfetto_pbzero_enum_ChromeLatencyInfo
+using ChromeLatencyInfo_LatencyComponentType = perfetto_pbzero_enum_ChromeLatencyInfo::LatencyComponentType;
+
+
+constexpr ChromeLatencyInfo_LatencyComponentType ChromeLatencyInfo_LatencyComponentType_MIN = ChromeLatencyInfo_LatencyComponentType::COMPONENT_UNSPECIFIED;
+constexpr ChromeLatencyInfo_LatencyComponentType ChromeLatencyInfo_LatencyComponentType_MAX = ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeLatencyInfo_LatencyComponentType_Name(::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_UNSPECIFIED:
+    return "COMPONENT_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH:
+    return "COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL:
+    return "COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL:
+    return "COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL:
+    return "COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_UI:
+    return "COMPONENT_INPUT_EVENT_LATENCY_UI";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN:
+    return "COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN:
+    return "COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL:
+    return "COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT:
+    return "COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH:
+    return "COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP:
+    return "COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME:
+    return "COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER:
+    return "COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER";
+
+  case ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP:
+    return "COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeLatencyInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeLatencyInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeLatencyInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeLatencyInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_trace_id() const { return at<1>().valid(); }
+  int64_t trace_id() const { return at<1>().as_int64(); }
+  bool has_step() const { return at<2>().valid(); }
+  int32_t step() const { return at<2>().as_int32(); }
+  bool has_frame_tree_node_id() const { return at<3>().valid(); }
+  int32_t frame_tree_node_id() const { return at<3>().as_int32(); }
+  bool has_component_info() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> component_info() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_is_coalesced() const { return at<5>().valid(); }
+  bool is_coalesced() const { return at<5>().as_bool(); }
+  bool has_gesture_scroll_id() const { return at<6>().valid(); }
+  int64_t gesture_scroll_id() const { return at<6>().as_int64(); }
+  bool has_touch_id() const { return at<7>().valid(); }
+  int64_t touch_id() const { return at<7>().as_int64(); }
+};
+
+class ChromeLatencyInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeLatencyInfo_Decoder;
+  enum : int32_t {
+    kTraceIdFieldNumber = 1,
+    kStepFieldNumber = 2,
+    kFrameTreeNodeIdFieldNumber = 3,
+    kComponentInfoFieldNumber = 4,
+    kIsCoalescedFieldNumber = 5,
+    kGestureScrollIdFieldNumber = 6,
+    kTouchIdFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeLatencyInfo"; }
+
+  using ComponentInfo = ::perfetto::protos::pbzero::ChromeLatencyInfo_ComponentInfo;
+
+  using Step = ::perfetto::protos::pbzero::ChromeLatencyInfo_Step;
+  static inline const char* Step_Name(Step value) {
+    return ::perfetto::protos::pbzero::ChromeLatencyInfo_Step_Name(value);
+  }
+
+  using LatencyComponentType = ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType;
+  static inline const char* LatencyComponentType_Name(LatencyComponentType value) {
+    return ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType_Name(value);
+  }
+  static inline const Step STEP_UNSPECIFIED = Step::STEP_UNSPECIFIED;
+  static inline const Step STEP_SEND_INPUT_EVENT_UI = Step::STEP_SEND_INPUT_EVENT_UI;
+  static inline const Step STEP_HANDLE_INPUT_EVENT_IMPL = Step::STEP_HANDLE_INPUT_EVENT_IMPL;
+  static inline const Step STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = Step::STEP_DID_HANDLE_INPUT_AND_OVERSCROLL;
+  static inline const Step STEP_HANDLE_INPUT_EVENT_MAIN = Step::STEP_HANDLE_INPUT_EVENT_MAIN;
+  static inline const Step STEP_MAIN_THREAD_SCROLL_UPDATE = Step::STEP_MAIN_THREAD_SCROLL_UPDATE;
+  static inline const Step STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = Step::STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT;
+  static inline const Step STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = Step::STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL;
+  static inline const Step STEP_HANDLED_INPUT_EVENT_IMPL = Step::STEP_HANDLED_INPUT_EVENT_IMPL;
+  static inline const Step STEP_SWAP_BUFFERS = Step::STEP_SWAP_BUFFERS;
+  static inline const Step STEP_DRAW_AND_SWAP = Step::STEP_DRAW_AND_SWAP;
+  static inline const Step STEP_FINISHED_SWAP_BUFFERS = Step::STEP_FINISHED_SWAP_BUFFERS;
+  static inline const LatencyComponentType COMPONENT_UNSPECIFIED = LatencyComponentType::COMPONENT_UNSPECIFIED;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_UI = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_UI;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP;
+  static inline const LatencyComponentType COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = LatencyComponentType::COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = LatencyComponentType::COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER;
+  static inline const LatencyComponentType COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = LatencyComponentType::COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
+
+  using FieldMetadata_TraceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_TraceId kTraceId{};
+  void set_trace_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TraceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Step =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeLatencyInfo_Step,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_Step kStep{};
+  void set_step(::perfetto::protos::pbzero::ChromeLatencyInfo_Step value) {
+    static constexpr uint32_t field_id = FieldMetadata_Step::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FrameTreeNodeId =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_FrameTreeNodeId kFrameTreeNodeId{};
+  void set_frame_tree_node_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FrameTreeNodeId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ComponentInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeLatencyInfo_ComponentInfo,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_ComponentInfo kComponentInfo{};
+  template <typename T = ChromeLatencyInfo_ComponentInfo> T* add_component_info() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_IsCoalesced =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_IsCoalesced kIsCoalesced{};
+  void set_is_coalesced(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsCoalesced::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_GestureScrollId =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_GestureScrollId kGestureScrollId{};
+  void set_gesture_scroll_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GestureScrollId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TouchId =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ChromeLatencyInfo>;
+
+  static constexpr FieldMetadata_TouchId kTouchId{};
+  void set_touch_id(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TouchId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeLatencyInfo_ComponentInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeLatencyInfo_ComponentInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeLatencyInfo_ComponentInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeLatencyInfo_ComponentInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_component_type() const { return at<1>().valid(); }
+  int32_t component_type() const { return at<1>().as_int32(); }
+  bool has_time_us() const { return at<2>().valid(); }
+  uint64_t time_us() const { return at<2>().as_uint64(); }
+};
+
+class ChromeLatencyInfo_ComponentInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeLatencyInfo_ComponentInfo_Decoder;
+  enum : int32_t {
+    kComponentTypeFieldNumber = 1,
+    kTimeUsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeLatencyInfo.ComponentInfo"; }
+
+
+  using FieldMetadata_ComponentType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType,
+      ChromeLatencyInfo_ComponentInfo>;
+
+  static constexpr FieldMetadata_ComponentType kComponentType{};
+  void set_component_type(::perfetto::protos::pbzero::ChromeLatencyInfo_LatencyComponentType value) {
+    static constexpr uint32_t field_id = FieldMetadata_ComponentType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeLatencyInfo_ComponentInfo>;
+
+  static constexpr FieldMetadata_TimeUs kTimeUs{};
+  void set_time_us(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimeUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeLegacyIpc {
+enum MessageClass : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeLegacyIpc
+using ChromeLegacyIpc_MessageClass = perfetto_pbzero_enum_ChromeLegacyIpc::MessageClass;
+
+namespace perfetto_pbzero_enum_ChromeLegacyIpc {
+enum MessageClass : int32_t {
+  CLASS_UNSPECIFIED = 0,
+  CLASS_AUTOMATION = 1,
+  CLASS_FRAME = 2,
+  CLASS_PAGE = 3,
+  CLASS_VIEW = 4,
+  CLASS_WIDGET = 5,
+  CLASS_INPUT = 6,
+  CLASS_TEST = 7,
+  CLASS_WORKER = 8,
+  CLASS_NACL = 9,
+  CLASS_GPU_CHANNEL = 10,
+  CLASS_MEDIA = 11,
+  CLASS_PPAPI = 12,
+  CLASS_CHROME = 13,
+  CLASS_DRAG = 14,
+  CLASS_PRINT = 15,
+  CLASS_EXTENSION = 16,
+  CLASS_TEXT_INPUT_CLIENT = 17,
+  CLASS_BLINK_TEST = 18,
+  CLASS_ACCESSIBILITY = 19,
+  CLASS_PRERENDER = 20,
+  CLASS_CHROMOTING = 21,
+  CLASS_BROWSER_PLUGIN = 22,
+  CLASS_ANDROID_WEB_VIEW = 23,
+  CLASS_NACL_HOST = 24,
+  CLASS_ENCRYPTED_MEDIA = 25,
+  CLASS_CAST = 26,
+  CLASS_GIN_JAVA_BRIDGE = 27,
+  CLASS_CHROME_UTILITY_PRINTING = 28,
+  CLASS_OZONE_GPU = 29,
+  CLASS_WEB_TEST = 30,
+  CLASS_NETWORK_HINTS = 31,
+  CLASS_EXTENSIONS_GUEST_VIEW = 32,
+  CLASS_GUEST_VIEW = 33,
+  CLASS_MEDIA_PLAYER_DELEGATE = 34,
+  CLASS_EXTENSION_WORKER = 35,
+  CLASS_SUBRESOURCE_FILTER = 36,
+  CLASS_UNFREEZABLE_FRAME = 37,
+};
+} // namespace perfetto_pbzero_enum_ChromeLegacyIpc
+using ChromeLegacyIpc_MessageClass = perfetto_pbzero_enum_ChromeLegacyIpc::MessageClass;
+
+
+constexpr ChromeLegacyIpc_MessageClass ChromeLegacyIpc_MessageClass_MIN = ChromeLegacyIpc_MessageClass::CLASS_UNSPECIFIED;
+constexpr ChromeLegacyIpc_MessageClass ChromeLegacyIpc_MessageClass_MAX = ChromeLegacyIpc_MessageClass::CLASS_UNFREEZABLE_FRAME;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeLegacyIpc_MessageClass_Name(::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_UNSPECIFIED:
+    return "CLASS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_AUTOMATION:
+    return "CLASS_AUTOMATION";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_FRAME:
+    return "CLASS_FRAME";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_PAGE:
+    return "CLASS_PAGE";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_VIEW:
+    return "CLASS_VIEW";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_WIDGET:
+    return "CLASS_WIDGET";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_INPUT:
+    return "CLASS_INPUT";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_TEST:
+    return "CLASS_TEST";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_WORKER:
+    return "CLASS_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_NACL:
+    return "CLASS_NACL";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_GPU_CHANNEL:
+    return "CLASS_GPU_CHANNEL";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_MEDIA:
+    return "CLASS_MEDIA";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_PPAPI:
+    return "CLASS_PPAPI";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_CHROME:
+    return "CLASS_CHROME";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_DRAG:
+    return "CLASS_DRAG";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_PRINT:
+    return "CLASS_PRINT";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_EXTENSION:
+    return "CLASS_EXTENSION";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_TEXT_INPUT_CLIENT:
+    return "CLASS_TEXT_INPUT_CLIENT";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_BLINK_TEST:
+    return "CLASS_BLINK_TEST";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_ACCESSIBILITY:
+    return "CLASS_ACCESSIBILITY";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_PRERENDER:
+    return "CLASS_PRERENDER";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_CHROMOTING:
+    return "CLASS_CHROMOTING";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_BROWSER_PLUGIN:
+    return "CLASS_BROWSER_PLUGIN";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_ANDROID_WEB_VIEW:
+    return "CLASS_ANDROID_WEB_VIEW";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_NACL_HOST:
+    return "CLASS_NACL_HOST";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_ENCRYPTED_MEDIA:
+    return "CLASS_ENCRYPTED_MEDIA";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_CAST:
+    return "CLASS_CAST";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_GIN_JAVA_BRIDGE:
+    return "CLASS_GIN_JAVA_BRIDGE";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_CHROME_UTILITY_PRINTING:
+    return "CLASS_CHROME_UTILITY_PRINTING";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_OZONE_GPU:
+    return "CLASS_OZONE_GPU";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_WEB_TEST:
+    return "CLASS_WEB_TEST";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_NETWORK_HINTS:
+    return "CLASS_NETWORK_HINTS";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_EXTENSIONS_GUEST_VIEW:
+    return "CLASS_EXTENSIONS_GUEST_VIEW";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_GUEST_VIEW:
+    return "CLASS_GUEST_VIEW";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_MEDIA_PLAYER_DELEGATE:
+    return "CLASS_MEDIA_PLAYER_DELEGATE";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_EXTENSION_WORKER:
+    return "CLASS_EXTENSION_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_SUBRESOURCE_FILTER:
+    return "CLASS_SUBRESOURCE_FILTER";
+
+  case ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass::CLASS_UNFREEZABLE_FRAME:
+    return "CLASS_UNFREEZABLE_FRAME";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeLegacyIpc_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeLegacyIpc_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeLegacyIpc_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeLegacyIpc_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_message_class() const { return at<1>().valid(); }
+  int32_t message_class() const { return at<1>().as_int32(); }
+  bool has_message_line() const { return at<2>().valid(); }
+  uint32_t message_line() const { return at<2>().as_uint32(); }
+};
+
+class ChromeLegacyIpc : public ::protozero::Message {
+ public:
+  using Decoder = ChromeLegacyIpc_Decoder;
+  enum : int32_t {
+    kMessageClassFieldNumber = 1,
+    kMessageLineFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeLegacyIpc"; }
+
+
+  using MessageClass = ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass;
+  static inline const char* MessageClass_Name(MessageClass value) {
+    return ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass_Name(value);
+  }
+  static inline const MessageClass CLASS_UNSPECIFIED = MessageClass::CLASS_UNSPECIFIED;
+  static inline const MessageClass CLASS_AUTOMATION = MessageClass::CLASS_AUTOMATION;
+  static inline const MessageClass CLASS_FRAME = MessageClass::CLASS_FRAME;
+  static inline const MessageClass CLASS_PAGE = MessageClass::CLASS_PAGE;
+  static inline const MessageClass CLASS_VIEW = MessageClass::CLASS_VIEW;
+  static inline const MessageClass CLASS_WIDGET = MessageClass::CLASS_WIDGET;
+  static inline const MessageClass CLASS_INPUT = MessageClass::CLASS_INPUT;
+  static inline const MessageClass CLASS_TEST = MessageClass::CLASS_TEST;
+  static inline const MessageClass CLASS_WORKER = MessageClass::CLASS_WORKER;
+  static inline const MessageClass CLASS_NACL = MessageClass::CLASS_NACL;
+  static inline const MessageClass CLASS_GPU_CHANNEL = MessageClass::CLASS_GPU_CHANNEL;
+  static inline const MessageClass CLASS_MEDIA = MessageClass::CLASS_MEDIA;
+  static inline const MessageClass CLASS_PPAPI = MessageClass::CLASS_PPAPI;
+  static inline const MessageClass CLASS_CHROME = MessageClass::CLASS_CHROME;
+  static inline const MessageClass CLASS_DRAG = MessageClass::CLASS_DRAG;
+  static inline const MessageClass CLASS_PRINT = MessageClass::CLASS_PRINT;
+  static inline const MessageClass CLASS_EXTENSION = MessageClass::CLASS_EXTENSION;
+  static inline const MessageClass CLASS_TEXT_INPUT_CLIENT = MessageClass::CLASS_TEXT_INPUT_CLIENT;
+  static inline const MessageClass CLASS_BLINK_TEST = MessageClass::CLASS_BLINK_TEST;
+  static inline const MessageClass CLASS_ACCESSIBILITY = MessageClass::CLASS_ACCESSIBILITY;
+  static inline const MessageClass CLASS_PRERENDER = MessageClass::CLASS_PRERENDER;
+  static inline const MessageClass CLASS_CHROMOTING = MessageClass::CLASS_CHROMOTING;
+  static inline const MessageClass CLASS_BROWSER_PLUGIN = MessageClass::CLASS_BROWSER_PLUGIN;
+  static inline const MessageClass CLASS_ANDROID_WEB_VIEW = MessageClass::CLASS_ANDROID_WEB_VIEW;
+  static inline const MessageClass CLASS_NACL_HOST = MessageClass::CLASS_NACL_HOST;
+  static inline const MessageClass CLASS_ENCRYPTED_MEDIA = MessageClass::CLASS_ENCRYPTED_MEDIA;
+  static inline const MessageClass CLASS_CAST = MessageClass::CLASS_CAST;
+  static inline const MessageClass CLASS_GIN_JAVA_BRIDGE = MessageClass::CLASS_GIN_JAVA_BRIDGE;
+  static inline const MessageClass CLASS_CHROME_UTILITY_PRINTING = MessageClass::CLASS_CHROME_UTILITY_PRINTING;
+  static inline const MessageClass CLASS_OZONE_GPU = MessageClass::CLASS_OZONE_GPU;
+  static inline const MessageClass CLASS_WEB_TEST = MessageClass::CLASS_WEB_TEST;
+  static inline const MessageClass CLASS_NETWORK_HINTS = MessageClass::CLASS_NETWORK_HINTS;
+  static inline const MessageClass CLASS_EXTENSIONS_GUEST_VIEW = MessageClass::CLASS_EXTENSIONS_GUEST_VIEW;
+  static inline const MessageClass CLASS_GUEST_VIEW = MessageClass::CLASS_GUEST_VIEW;
+  static inline const MessageClass CLASS_MEDIA_PLAYER_DELEGATE = MessageClass::CLASS_MEDIA_PLAYER_DELEGATE;
+  static inline const MessageClass CLASS_EXTENSION_WORKER = MessageClass::CLASS_EXTENSION_WORKER;
+  static inline const MessageClass CLASS_SUBRESOURCE_FILTER = MessageClass::CLASS_SUBRESOURCE_FILTER;
+  static inline const MessageClass CLASS_UNFREEZABLE_FRAME = MessageClass::CLASS_UNFREEZABLE_FRAME;
+
+  using FieldMetadata_MessageClass =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass,
+      ChromeLegacyIpc>;
+
+  static constexpr FieldMetadata_MessageClass kMessageClass{};
+  void set_message_class(::perfetto::protos::pbzero::ChromeLegacyIpc_MessageClass value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageClass::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MessageLine =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeLegacyIpc>;
+
+  static constexpr FieldMetadata_MessageLine kMessageLine{};
+  void set_message_line(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageLine::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ChromeMessagePump_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeMessagePump_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeMessagePump_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeMessagePump_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_sent_messages_in_queue() const { return at<1>().valid(); }
+  bool sent_messages_in_queue() const { return at<1>().as_bool(); }
+  bool has_io_handler_location_iid() const { return at<2>().valid(); }
+  uint64_t io_handler_location_iid() const { return at<2>().as_uint64(); }
+};
+
+class ChromeMessagePump : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMessagePump_Decoder;
+  enum : int32_t {
+    kSentMessagesInQueueFieldNumber = 1,
+    kIoHandlerLocationIidFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeMessagePump"; }
+
+
+  using FieldMetadata_SentMessagesInQueue =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeMessagePump>;
+
+  static constexpr FieldMetadata_SentMessagesInQueue kSentMessagesInQueue{};
+  void set_sent_messages_in_queue(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SentMessagesInQueue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IoHandlerLocationIid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeMessagePump>;
+
+  static constexpr FieldMetadata_IoHandlerLocationIid kIoHandlerLocationIid{};
+  void set_io_handler_location_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IoHandlerLocationIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ChromeMojoEventInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeMojoEventInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeMojoEventInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeMojoEventInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_watcher_notify_interface_tag() const { return at<1>().valid(); }
+  ::protozero::ConstChars watcher_notify_interface_tag() const { return at<1>().as_string(); }
+  bool has_ipc_hash() const { return at<2>().valid(); }
+  uint32_t ipc_hash() const { return at<2>().as_uint32(); }
+  bool has_mojo_interface_tag() const { return at<3>().valid(); }
+  ::protozero::ConstChars mojo_interface_tag() const { return at<3>().as_string(); }
+  bool has_mojo_interface_method_iid() const { return at<4>().valid(); }
+  uint64_t mojo_interface_method_iid() const { return at<4>().as_uint64(); }
+  bool has_is_reply() const { return at<5>().valid(); }
+  bool is_reply() const { return at<5>().as_bool(); }
+  bool has_payload_size() const { return at<6>().valid(); }
+  uint64_t payload_size() const { return at<6>().as_uint64(); }
+  bool has_data_num_bytes() const { return at<7>().valid(); }
+  uint64_t data_num_bytes() const { return at<7>().as_uint64(); }
+};
+
+class ChromeMojoEventInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeMojoEventInfo_Decoder;
+  enum : int32_t {
+    kWatcherNotifyInterfaceTagFieldNumber = 1,
+    kIpcHashFieldNumber = 2,
+    kMojoInterfaceTagFieldNumber = 3,
+    kMojoInterfaceMethodIidFieldNumber = 4,
+    kIsReplyFieldNumber = 5,
+    kPayloadSizeFieldNumber = 6,
+    kDataNumBytesFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeMojoEventInfo"; }
+
+
+  using FieldMetadata_WatcherNotifyInterfaceTag =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_WatcherNotifyInterfaceTag kWatcherNotifyInterfaceTag{};
+  void set_watcher_notify_interface_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_WatcherNotifyInterfaceTag::kFieldId, data, size);
+  }
+  void set_watcher_notify_interface_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_WatcherNotifyInterfaceTag::kFieldId, chars.data, chars.size);
+  }
+  void set_watcher_notify_interface_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_WatcherNotifyInterfaceTag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IpcHash =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_IpcHash kIpcHash{};
+  void set_ipc_hash(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IpcHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MojoInterfaceTag =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_MojoInterfaceTag kMojoInterfaceTag{};
+  void set_mojo_interface_tag(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_MojoInterfaceTag::kFieldId, data, size);
+  }
+  void set_mojo_interface_tag(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_MojoInterfaceTag::kFieldId, chars.data, chars.size);
+  }
+  void set_mojo_interface_tag(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_MojoInterfaceTag::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MojoInterfaceMethodIid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_MojoInterfaceMethodIid kMojoInterfaceMethodIid{};
+  void set_mojo_interface_method_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MojoInterfaceMethodIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsReply =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_IsReply kIsReply{};
+  void set_is_reply(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsReply::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PayloadSize =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_PayloadSize kPayloadSize{};
+  void set_payload_size(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PayloadSize::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DataNumBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeMojoEventInfo>;
+
+  static constexpr FieldMetadata_DataNumBytes kDataNumBytes{};
+  void set_data_num_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DataNumBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeProcessDescriptor {
+enum ProcessType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeProcessDescriptor
+using ChromeProcessDescriptor_ProcessType = perfetto_pbzero_enum_ChromeProcessDescriptor::ProcessType;
+
+namespace perfetto_pbzero_enum_ChromeProcessDescriptor {
+enum ProcessType : int32_t {
+  PROCESS_UNSPECIFIED = 0,
+  PROCESS_BROWSER = 1,
+  PROCESS_RENDERER = 2,
+  PROCESS_UTILITY = 3,
+  PROCESS_ZYGOTE = 4,
+  PROCESS_SANDBOX_HELPER = 5,
+  PROCESS_GPU = 6,
+  PROCESS_PPAPI_PLUGIN = 7,
+  PROCESS_PPAPI_BROKER = 8,
+  PROCESS_SERVICE_NETWORK = 9,
+  PROCESS_SERVICE_TRACING = 10,
+  PROCESS_SERVICE_STORAGE = 11,
+  PROCESS_SERVICE_AUDIO = 12,
+  PROCESS_SERVICE_DATA_DECODER = 13,
+  PROCESS_SERVICE_UTIL_WIN = 14,
+  PROCESS_SERVICE_PROXY_RESOLVER = 15,
+  PROCESS_SERVICE_CDM = 16,
+  PROCESS_SERVICE_VIDEO_CAPTURE = 17,
+  PROCESS_SERVICE_UNZIPPER = 18,
+  PROCESS_SERVICE_MIRRORING = 19,
+  PROCESS_SERVICE_FILEPATCHER = 20,
+  PROCESS_SERVICE_TTS = 21,
+  PROCESS_SERVICE_PRINTING = 22,
+  PROCESS_SERVICE_QUARANTINE = 23,
+  PROCESS_SERVICE_CROS_LOCALSEARCH = 24,
+  PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = 25,
+  PROCESS_SERVICE_FILEUTIL = 26,
+  PROCESS_SERVICE_PRINTCOMPOSITOR = 27,
+  PROCESS_SERVICE_PAINTPREVIEW = 28,
+  PROCESS_SERVICE_SPEECHRECOGNITION = 29,
+  PROCESS_SERVICE_XRDEVICE = 30,
+  PROCESS_SERVICE_READICON = 31,
+  PROCESS_SERVICE_LANGUAGEDETECTION = 32,
+  PROCESS_SERVICE_SHARING = 33,
+  PROCESS_SERVICE_MEDIAPARSER = 34,
+  PROCESS_SERVICE_QRCODEGENERATOR = 35,
+  PROCESS_SERVICE_PROFILEIMPORT = 36,
+  PROCESS_SERVICE_IME = 37,
+  PROCESS_SERVICE_RECORDING = 38,
+  PROCESS_SERVICE_SHAPEDETECTION = 39,
+  PROCESS_RENDERER_EXTENSION = 40,
+  PROCESS_SERVICE_MEDIA_FOUNDATION = 41,
+};
+} // namespace perfetto_pbzero_enum_ChromeProcessDescriptor
+using ChromeProcessDescriptor_ProcessType = perfetto_pbzero_enum_ChromeProcessDescriptor::ProcessType;
+
+
+constexpr ChromeProcessDescriptor_ProcessType ChromeProcessDescriptor_ProcessType_MIN = ChromeProcessDescriptor_ProcessType::PROCESS_UNSPECIFIED;
+constexpr ChromeProcessDescriptor_ProcessType ChromeProcessDescriptor_ProcessType_MAX = ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_MEDIA_FOUNDATION;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeProcessDescriptor_ProcessType_Name(::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_UNSPECIFIED:
+    return "PROCESS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_BROWSER:
+    return "PROCESS_BROWSER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_RENDERER:
+    return "PROCESS_RENDERER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_UTILITY:
+    return "PROCESS_UTILITY";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_ZYGOTE:
+    return "PROCESS_ZYGOTE";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SANDBOX_HELPER:
+    return "PROCESS_SANDBOX_HELPER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_GPU:
+    return "PROCESS_GPU";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_PPAPI_PLUGIN:
+    return "PROCESS_PPAPI_PLUGIN";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_PPAPI_BROKER:
+    return "PROCESS_PPAPI_BROKER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_NETWORK:
+    return "PROCESS_SERVICE_NETWORK";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_TRACING:
+    return "PROCESS_SERVICE_TRACING";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_STORAGE:
+    return "PROCESS_SERVICE_STORAGE";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_AUDIO:
+    return "PROCESS_SERVICE_AUDIO";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_DATA_DECODER:
+    return "PROCESS_SERVICE_DATA_DECODER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_UTIL_WIN:
+    return "PROCESS_SERVICE_UTIL_WIN";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_PROXY_RESOLVER:
+    return "PROCESS_SERVICE_PROXY_RESOLVER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_CDM:
+    return "PROCESS_SERVICE_CDM";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_VIDEO_CAPTURE:
+    return "PROCESS_SERVICE_VIDEO_CAPTURE";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_UNZIPPER:
+    return "PROCESS_SERVICE_UNZIPPER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_MIRRORING:
+    return "PROCESS_SERVICE_MIRRORING";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_FILEPATCHER:
+    return "PROCESS_SERVICE_FILEPATCHER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_TTS:
+    return "PROCESS_SERVICE_TTS";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_PRINTING:
+    return "PROCESS_SERVICE_PRINTING";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_QUARANTINE:
+    return "PROCESS_SERVICE_QUARANTINE";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_CROS_LOCALSEARCH:
+    return "PROCESS_SERVICE_CROS_LOCALSEARCH";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER:
+    return "PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_FILEUTIL:
+    return "PROCESS_SERVICE_FILEUTIL";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_PRINTCOMPOSITOR:
+    return "PROCESS_SERVICE_PRINTCOMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_PAINTPREVIEW:
+    return "PROCESS_SERVICE_PAINTPREVIEW";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_SPEECHRECOGNITION:
+    return "PROCESS_SERVICE_SPEECHRECOGNITION";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_XRDEVICE:
+    return "PROCESS_SERVICE_XRDEVICE";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_READICON:
+    return "PROCESS_SERVICE_READICON";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_LANGUAGEDETECTION:
+    return "PROCESS_SERVICE_LANGUAGEDETECTION";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_SHARING:
+    return "PROCESS_SERVICE_SHARING";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_MEDIAPARSER:
+    return "PROCESS_SERVICE_MEDIAPARSER";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_QRCODEGENERATOR:
+    return "PROCESS_SERVICE_QRCODEGENERATOR";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_PROFILEIMPORT:
+    return "PROCESS_SERVICE_PROFILEIMPORT";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_IME:
+    return "PROCESS_SERVICE_IME";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_RECORDING:
+    return "PROCESS_SERVICE_RECORDING";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_SHAPEDETECTION:
+    return "PROCESS_SERVICE_SHAPEDETECTION";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_RENDERER_EXTENSION:
+    return "PROCESS_RENDERER_EXTENSION";
+
+  case ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType::PROCESS_SERVICE_MEDIA_FOUNDATION:
+    return "PROCESS_SERVICE_MEDIA_FOUNDATION";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeProcessDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeProcessDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeProcessDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeProcessDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_process_type() const { return at<1>().valid(); }
+  int32_t process_type() const { return at<1>().as_int32(); }
+  bool has_process_priority() const { return at<2>().valid(); }
+  int32_t process_priority() const { return at<2>().as_int32(); }
+  bool has_legacy_sort_index() const { return at<3>().valid(); }
+  int32_t legacy_sort_index() const { return at<3>().as_int32(); }
+  bool has_host_app_package_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars host_app_package_name() const { return at<4>().as_string(); }
+  bool has_crash_trace_id() const { return at<5>().valid(); }
+  uint64_t crash_trace_id() const { return at<5>().as_uint64(); }
+};
+
+class ChromeProcessDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = ChromeProcessDescriptor_Decoder;
+  enum : int32_t {
+    kProcessTypeFieldNumber = 1,
+    kProcessPriorityFieldNumber = 2,
+    kLegacySortIndexFieldNumber = 3,
+    kHostAppPackageNameFieldNumber = 4,
+    kCrashTraceIdFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeProcessDescriptor"; }
+
+
+  using ProcessType = ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType;
+  static inline const char* ProcessType_Name(ProcessType value) {
+    return ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType_Name(value);
+  }
+  static inline const ProcessType PROCESS_UNSPECIFIED = ProcessType::PROCESS_UNSPECIFIED;
+  static inline const ProcessType PROCESS_BROWSER = ProcessType::PROCESS_BROWSER;
+  static inline const ProcessType PROCESS_RENDERER = ProcessType::PROCESS_RENDERER;
+  static inline const ProcessType PROCESS_UTILITY = ProcessType::PROCESS_UTILITY;
+  static inline const ProcessType PROCESS_ZYGOTE = ProcessType::PROCESS_ZYGOTE;
+  static inline const ProcessType PROCESS_SANDBOX_HELPER = ProcessType::PROCESS_SANDBOX_HELPER;
+  static inline const ProcessType PROCESS_GPU = ProcessType::PROCESS_GPU;
+  static inline const ProcessType PROCESS_PPAPI_PLUGIN = ProcessType::PROCESS_PPAPI_PLUGIN;
+  static inline const ProcessType PROCESS_PPAPI_BROKER = ProcessType::PROCESS_PPAPI_BROKER;
+  static inline const ProcessType PROCESS_SERVICE_NETWORK = ProcessType::PROCESS_SERVICE_NETWORK;
+  static inline const ProcessType PROCESS_SERVICE_TRACING = ProcessType::PROCESS_SERVICE_TRACING;
+  static inline const ProcessType PROCESS_SERVICE_STORAGE = ProcessType::PROCESS_SERVICE_STORAGE;
+  static inline const ProcessType PROCESS_SERVICE_AUDIO = ProcessType::PROCESS_SERVICE_AUDIO;
+  static inline const ProcessType PROCESS_SERVICE_DATA_DECODER = ProcessType::PROCESS_SERVICE_DATA_DECODER;
+  static inline const ProcessType PROCESS_SERVICE_UTIL_WIN = ProcessType::PROCESS_SERVICE_UTIL_WIN;
+  static inline const ProcessType PROCESS_SERVICE_PROXY_RESOLVER = ProcessType::PROCESS_SERVICE_PROXY_RESOLVER;
+  static inline const ProcessType PROCESS_SERVICE_CDM = ProcessType::PROCESS_SERVICE_CDM;
+  static inline const ProcessType PROCESS_SERVICE_VIDEO_CAPTURE = ProcessType::PROCESS_SERVICE_VIDEO_CAPTURE;
+  static inline const ProcessType PROCESS_SERVICE_UNZIPPER = ProcessType::PROCESS_SERVICE_UNZIPPER;
+  static inline const ProcessType PROCESS_SERVICE_MIRRORING = ProcessType::PROCESS_SERVICE_MIRRORING;
+  static inline const ProcessType PROCESS_SERVICE_FILEPATCHER = ProcessType::PROCESS_SERVICE_FILEPATCHER;
+  static inline const ProcessType PROCESS_SERVICE_TTS = ProcessType::PROCESS_SERVICE_TTS;
+  static inline const ProcessType PROCESS_SERVICE_PRINTING = ProcessType::PROCESS_SERVICE_PRINTING;
+  static inline const ProcessType PROCESS_SERVICE_QUARANTINE = ProcessType::PROCESS_SERVICE_QUARANTINE;
+  static inline const ProcessType PROCESS_SERVICE_CROS_LOCALSEARCH = ProcessType::PROCESS_SERVICE_CROS_LOCALSEARCH;
+  static inline const ProcessType PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = ProcessType::PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER;
+  static inline const ProcessType PROCESS_SERVICE_FILEUTIL = ProcessType::PROCESS_SERVICE_FILEUTIL;
+  static inline const ProcessType PROCESS_SERVICE_PRINTCOMPOSITOR = ProcessType::PROCESS_SERVICE_PRINTCOMPOSITOR;
+  static inline const ProcessType PROCESS_SERVICE_PAINTPREVIEW = ProcessType::PROCESS_SERVICE_PAINTPREVIEW;
+  static inline const ProcessType PROCESS_SERVICE_SPEECHRECOGNITION = ProcessType::PROCESS_SERVICE_SPEECHRECOGNITION;
+  static inline const ProcessType PROCESS_SERVICE_XRDEVICE = ProcessType::PROCESS_SERVICE_XRDEVICE;
+  static inline const ProcessType PROCESS_SERVICE_READICON = ProcessType::PROCESS_SERVICE_READICON;
+  static inline const ProcessType PROCESS_SERVICE_LANGUAGEDETECTION = ProcessType::PROCESS_SERVICE_LANGUAGEDETECTION;
+  static inline const ProcessType PROCESS_SERVICE_SHARING = ProcessType::PROCESS_SERVICE_SHARING;
+  static inline const ProcessType PROCESS_SERVICE_MEDIAPARSER = ProcessType::PROCESS_SERVICE_MEDIAPARSER;
+  static inline const ProcessType PROCESS_SERVICE_QRCODEGENERATOR = ProcessType::PROCESS_SERVICE_QRCODEGENERATOR;
+  static inline const ProcessType PROCESS_SERVICE_PROFILEIMPORT = ProcessType::PROCESS_SERVICE_PROFILEIMPORT;
+  static inline const ProcessType PROCESS_SERVICE_IME = ProcessType::PROCESS_SERVICE_IME;
+  static inline const ProcessType PROCESS_SERVICE_RECORDING = ProcessType::PROCESS_SERVICE_RECORDING;
+  static inline const ProcessType PROCESS_SERVICE_SHAPEDETECTION = ProcessType::PROCESS_SERVICE_SHAPEDETECTION;
+  static inline const ProcessType PROCESS_RENDERER_EXTENSION = ProcessType::PROCESS_RENDERER_EXTENSION;
+  static inline const ProcessType PROCESS_SERVICE_MEDIA_FOUNDATION = ProcessType::PROCESS_SERVICE_MEDIA_FOUNDATION;
+
+  using FieldMetadata_ProcessType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType,
+      ChromeProcessDescriptor>;
+
+  static constexpr FieldMetadata_ProcessType kProcessType{};
+  void set_process_type(::perfetto::protos::pbzero::ChromeProcessDescriptor_ProcessType value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeProcessDescriptor>;
+
+  static constexpr FieldMetadata_ProcessPriority kProcessPriority{};
+  void set_process_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessPriority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LegacySortIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeProcessDescriptor>;
+
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex{};
+  void set_legacy_sort_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HostAppPackageName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeProcessDescriptor>;
+
+  static constexpr FieldMetadata_HostAppPackageName kHostAppPackageName{};
+  void set_host_app_package_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_HostAppPackageName::kFieldId, data, size);
+  }
+  void set_host_app_package_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_HostAppPackageName::kFieldId, chars.data, chars.size);
+  }
+  void set_host_app_package_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_HostAppPackageName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CrashTraceId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeProcessDescriptor>;
+
+  static constexpr FieldMetadata_CrashTraceId kCrashTraceId{};
+  void set_crash_trace_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CrashTraceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+enum ChromeRAILMode : int32_t;
+
+enum ChromeRAILMode : int32_t {
+  RAIL_MODE_NONE = 0,
+  RAIL_MODE_RESPONSE = 1,
+  RAIL_MODE_ANIMATION = 2,
+  RAIL_MODE_IDLE = 3,
+  RAIL_MODE_LOAD = 4,
+};
+
+constexpr ChromeRAILMode ChromeRAILMode_MIN = ChromeRAILMode::RAIL_MODE_NONE;
+constexpr ChromeRAILMode ChromeRAILMode_MAX = ChromeRAILMode::RAIL_MODE_LOAD;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeRAILMode_Name(::perfetto::protos::pbzero::ChromeRAILMode value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeRAILMode::RAIL_MODE_NONE:
+    return "RAIL_MODE_NONE";
+
+  case ::perfetto::protos::pbzero::ChromeRAILMode::RAIL_MODE_RESPONSE:
+    return "RAIL_MODE_RESPONSE";
+
+  case ::perfetto::protos::pbzero::ChromeRAILMode::RAIL_MODE_ANIMATION:
+    return "RAIL_MODE_ANIMATION";
+
+  case ::perfetto::protos::pbzero::ChromeRAILMode::RAIL_MODE_IDLE:
+    return "RAIL_MODE_IDLE";
+
+  case ::perfetto::protos::pbzero::ChromeRAILMode::RAIL_MODE_LOAD:
+    return "RAIL_MODE_LOAD";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeRendererSchedulerState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeRendererSchedulerState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeRendererSchedulerState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeRendererSchedulerState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rail_mode() const { return at<1>().valid(); }
+  int32_t rail_mode() const { return at<1>().as_int32(); }
+  bool has_is_backgrounded() const { return at<2>().valid(); }
+  bool is_backgrounded() const { return at<2>().as_bool(); }
+  bool has_is_hidden() const { return at<3>().valid(); }
+  bool is_hidden() const { return at<3>().as_bool(); }
+};
+
+class ChromeRendererSchedulerState : public ::protozero::Message {
+ public:
+  using Decoder = ChromeRendererSchedulerState_Decoder;
+  enum : int32_t {
+    kRailModeFieldNumber = 1,
+    kIsBackgroundedFieldNumber = 2,
+    kIsHiddenFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeRendererSchedulerState"; }
+
+
+  using FieldMetadata_RailMode =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeRAILMode,
+      ChromeRendererSchedulerState>;
+
+  static constexpr FieldMetadata_RailMode kRailMode{};
+  void set_rail_mode(::perfetto::protos::pbzero::ChromeRAILMode value) {
+    static constexpr uint32_t field_id = FieldMetadata_RailMode::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsBackgrounded =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeRendererSchedulerState>;
+
+  static constexpr FieldMetadata_IsBackgrounded kIsBackgrounded{};
+  void set_is_backgrounded(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsBackgrounded::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsHidden =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ChromeRendererSchedulerState>;
+
+  static constexpr FieldMetadata_IsHidden kIsHidden{};
+  void set_is_hidden(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsHidden::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ChromeThreadDescriptor {
+enum ThreadType : int32_t;
+}  // namespace perfetto_pbzero_enum_ChromeThreadDescriptor
+using ChromeThreadDescriptor_ThreadType = perfetto_pbzero_enum_ChromeThreadDescriptor::ThreadType;
+
+namespace perfetto_pbzero_enum_ChromeThreadDescriptor {
+enum ThreadType : int32_t {
+  THREAD_UNSPECIFIED = 0,
+  THREAD_MAIN = 1,
+  THREAD_IO = 2,
+  THREAD_POOL_BG_WORKER = 3,
+  THREAD_POOL_FG_WORKER = 4,
+  THREAD_POOL_FG_BLOCKING = 5,
+  THREAD_POOL_BG_BLOCKING = 6,
+  THREAD_POOL_SERVICE = 7,
+  THREAD_COMPOSITOR = 8,
+  THREAD_VIZ_COMPOSITOR = 9,
+  THREAD_COMPOSITOR_WORKER = 10,
+  THREAD_SERVICE_WORKER = 11,
+  THREAD_NETWORK_SERVICE = 12,
+  THREAD_CHILD_IO = 13,
+  THREAD_BROWSER_IO = 14,
+  THREAD_BROWSER_MAIN = 15,
+  THREAD_RENDERER_MAIN = 16,
+  THREAD_UTILITY_MAIN = 17,
+  THREAD_GPU_MAIN = 18,
+  THREAD_CACHE_BLOCKFILE = 19,
+  THREAD_MEDIA = 20,
+  THREAD_AUDIO_OUTPUTDEVICE = 21,
+  THREAD_AUDIO_INPUTDEVICE = 22,
+  THREAD_GPU_MEMORY = 23,
+  THREAD_GPU_VSYNC = 24,
+  THREAD_DXA_VIDEODECODER = 25,
+  THREAD_BROWSER_WATCHDOG = 26,
+  THREAD_WEBRTC_NETWORK = 27,
+  THREAD_WINDOW_OWNER = 28,
+  THREAD_WEBRTC_SIGNALING = 29,
+  THREAD_WEBRTC_WORKER = 30,
+  THREAD_PPAPI_MAIN = 31,
+  THREAD_GPU_WATCHDOG = 32,
+  THREAD_SWAPPER = 33,
+  THREAD_GAMEPAD_POLLING = 34,
+  THREAD_WEBCRYPTO = 35,
+  THREAD_DATABASE = 36,
+  THREAD_PROXYRESOLVER = 37,
+  THREAD_DEVTOOLSADB = 38,
+  THREAD_NETWORKCONFIGWATCHER = 39,
+  THREAD_WASAPI_RENDER = 40,
+  THREAD_LOADER_LOCK_SAMPLER = 41,
+  THREAD_MEMORY_INFRA = 50,
+  THREAD_SAMPLING_PROFILER = 51,
+};
+} // namespace perfetto_pbzero_enum_ChromeThreadDescriptor
+using ChromeThreadDescriptor_ThreadType = perfetto_pbzero_enum_ChromeThreadDescriptor::ThreadType;
+
+
+constexpr ChromeThreadDescriptor_ThreadType ChromeThreadDescriptor_ThreadType_MIN = ChromeThreadDescriptor_ThreadType::THREAD_UNSPECIFIED;
+constexpr ChromeThreadDescriptor_ThreadType ChromeThreadDescriptor_ThreadType_MAX = ChromeThreadDescriptor_ThreadType::THREAD_SAMPLING_PROFILER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ChromeThreadDescriptor_ThreadType_Name(::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_UNSPECIFIED:
+    return "THREAD_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_MAIN:
+    return "THREAD_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_IO:
+    return "THREAD_IO";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_POOL_BG_WORKER:
+    return "THREAD_POOL_BG_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_POOL_FG_WORKER:
+    return "THREAD_POOL_FG_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_POOL_FG_BLOCKING:
+    return "THREAD_POOL_FG_BLOCKING";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_POOL_BG_BLOCKING:
+    return "THREAD_POOL_BG_BLOCKING";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_POOL_SERVICE:
+    return "THREAD_POOL_SERVICE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_COMPOSITOR:
+    return "THREAD_COMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_VIZ_COMPOSITOR:
+    return "THREAD_VIZ_COMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_COMPOSITOR_WORKER:
+    return "THREAD_COMPOSITOR_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_SERVICE_WORKER:
+    return "THREAD_SERVICE_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_NETWORK_SERVICE:
+    return "THREAD_NETWORK_SERVICE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_CHILD_IO:
+    return "THREAD_CHILD_IO";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_BROWSER_IO:
+    return "THREAD_BROWSER_IO";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_BROWSER_MAIN:
+    return "THREAD_BROWSER_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_RENDERER_MAIN:
+    return "THREAD_RENDERER_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_UTILITY_MAIN:
+    return "THREAD_UTILITY_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_GPU_MAIN:
+    return "THREAD_GPU_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_CACHE_BLOCKFILE:
+    return "THREAD_CACHE_BLOCKFILE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_MEDIA:
+    return "THREAD_MEDIA";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_AUDIO_OUTPUTDEVICE:
+    return "THREAD_AUDIO_OUTPUTDEVICE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_AUDIO_INPUTDEVICE:
+    return "THREAD_AUDIO_INPUTDEVICE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_GPU_MEMORY:
+    return "THREAD_GPU_MEMORY";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_GPU_VSYNC:
+    return "THREAD_GPU_VSYNC";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_DXA_VIDEODECODER:
+    return "THREAD_DXA_VIDEODECODER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_BROWSER_WATCHDOG:
+    return "THREAD_BROWSER_WATCHDOG";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WEBRTC_NETWORK:
+    return "THREAD_WEBRTC_NETWORK";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WINDOW_OWNER:
+    return "THREAD_WINDOW_OWNER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WEBRTC_SIGNALING:
+    return "THREAD_WEBRTC_SIGNALING";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WEBRTC_WORKER:
+    return "THREAD_WEBRTC_WORKER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_PPAPI_MAIN:
+    return "THREAD_PPAPI_MAIN";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_GPU_WATCHDOG:
+    return "THREAD_GPU_WATCHDOG";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_SWAPPER:
+    return "THREAD_SWAPPER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_GAMEPAD_POLLING:
+    return "THREAD_GAMEPAD_POLLING";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WEBCRYPTO:
+    return "THREAD_WEBCRYPTO";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_DATABASE:
+    return "THREAD_DATABASE";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_PROXYRESOLVER:
+    return "THREAD_PROXYRESOLVER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_DEVTOOLSADB:
+    return "THREAD_DEVTOOLSADB";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_NETWORKCONFIGWATCHER:
+    return "THREAD_NETWORKCONFIGWATCHER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_WASAPI_RENDER:
+    return "THREAD_WASAPI_RENDER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_LOADER_LOCK_SAMPLER:
+    return "THREAD_LOADER_LOCK_SAMPLER";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_MEMORY_INFRA:
+    return "THREAD_MEMORY_INFRA";
+
+  case ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType::THREAD_SAMPLING_PROFILER:
+    return "THREAD_SAMPLING_PROFILER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ChromeThreadDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeThreadDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeThreadDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeThreadDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_thread_type() const { return at<1>().valid(); }
+  int32_t thread_type() const { return at<1>().as_int32(); }
+  bool has_legacy_sort_index() const { return at<2>().valid(); }
+  int32_t legacy_sort_index() const { return at<2>().as_int32(); }
+};
+
+class ChromeThreadDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = ChromeThreadDescriptor_Decoder;
+  enum : int32_t {
+    kThreadTypeFieldNumber = 1,
+    kLegacySortIndexFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeThreadDescriptor"; }
+
+
+  using ThreadType = ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType;
+  static inline const char* ThreadType_Name(ThreadType value) {
+    return ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType_Name(value);
+  }
+  static inline const ThreadType THREAD_UNSPECIFIED = ThreadType::THREAD_UNSPECIFIED;
+  static inline const ThreadType THREAD_MAIN = ThreadType::THREAD_MAIN;
+  static inline const ThreadType THREAD_IO = ThreadType::THREAD_IO;
+  static inline const ThreadType THREAD_POOL_BG_WORKER = ThreadType::THREAD_POOL_BG_WORKER;
+  static inline const ThreadType THREAD_POOL_FG_WORKER = ThreadType::THREAD_POOL_FG_WORKER;
+  static inline const ThreadType THREAD_POOL_FG_BLOCKING = ThreadType::THREAD_POOL_FG_BLOCKING;
+  static inline const ThreadType THREAD_POOL_BG_BLOCKING = ThreadType::THREAD_POOL_BG_BLOCKING;
+  static inline const ThreadType THREAD_POOL_SERVICE = ThreadType::THREAD_POOL_SERVICE;
+  static inline const ThreadType THREAD_COMPOSITOR = ThreadType::THREAD_COMPOSITOR;
+  static inline const ThreadType THREAD_VIZ_COMPOSITOR = ThreadType::THREAD_VIZ_COMPOSITOR;
+  static inline const ThreadType THREAD_COMPOSITOR_WORKER = ThreadType::THREAD_COMPOSITOR_WORKER;
+  static inline const ThreadType THREAD_SERVICE_WORKER = ThreadType::THREAD_SERVICE_WORKER;
+  static inline const ThreadType THREAD_NETWORK_SERVICE = ThreadType::THREAD_NETWORK_SERVICE;
+  static inline const ThreadType THREAD_CHILD_IO = ThreadType::THREAD_CHILD_IO;
+  static inline const ThreadType THREAD_BROWSER_IO = ThreadType::THREAD_BROWSER_IO;
+  static inline const ThreadType THREAD_BROWSER_MAIN = ThreadType::THREAD_BROWSER_MAIN;
+  static inline const ThreadType THREAD_RENDERER_MAIN = ThreadType::THREAD_RENDERER_MAIN;
+  static inline const ThreadType THREAD_UTILITY_MAIN = ThreadType::THREAD_UTILITY_MAIN;
+  static inline const ThreadType THREAD_GPU_MAIN = ThreadType::THREAD_GPU_MAIN;
+  static inline const ThreadType THREAD_CACHE_BLOCKFILE = ThreadType::THREAD_CACHE_BLOCKFILE;
+  static inline const ThreadType THREAD_MEDIA = ThreadType::THREAD_MEDIA;
+  static inline const ThreadType THREAD_AUDIO_OUTPUTDEVICE = ThreadType::THREAD_AUDIO_OUTPUTDEVICE;
+  static inline const ThreadType THREAD_AUDIO_INPUTDEVICE = ThreadType::THREAD_AUDIO_INPUTDEVICE;
+  static inline const ThreadType THREAD_GPU_MEMORY = ThreadType::THREAD_GPU_MEMORY;
+  static inline const ThreadType THREAD_GPU_VSYNC = ThreadType::THREAD_GPU_VSYNC;
+  static inline const ThreadType THREAD_DXA_VIDEODECODER = ThreadType::THREAD_DXA_VIDEODECODER;
+  static inline const ThreadType THREAD_BROWSER_WATCHDOG = ThreadType::THREAD_BROWSER_WATCHDOG;
+  static inline const ThreadType THREAD_WEBRTC_NETWORK = ThreadType::THREAD_WEBRTC_NETWORK;
+  static inline const ThreadType THREAD_WINDOW_OWNER = ThreadType::THREAD_WINDOW_OWNER;
+  static inline const ThreadType THREAD_WEBRTC_SIGNALING = ThreadType::THREAD_WEBRTC_SIGNALING;
+  static inline const ThreadType THREAD_WEBRTC_WORKER = ThreadType::THREAD_WEBRTC_WORKER;
+  static inline const ThreadType THREAD_PPAPI_MAIN = ThreadType::THREAD_PPAPI_MAIN;
+  static inline const ThreadType THREAD_GPU_WATCHDOG = ThreadType::THREAD_GPU_WATCHDOG;
+  static inline const ThreadType THREAD_SWAPPER = ThreadType::THREAD_SWAPPER;
+  static inline const ThreadType THREAD_GAMEPAD_POLLING = ThreadType::THREAD_GAMEPAD_POLLING;
+  static inline const ThreadType THREAD_WEBCRYPTO = ThreadType::THREAD_WEBCRYPTO;
+  static inline const ThreadType THREAD_DATABASE = ThreadType::THREAD_DATABASE;
+  static inline const ThreadType THREAD_PROXYRESOLVER = ThreadType::THREAD_PROXYRESOLVER;
+  static inline const ThreadType THREAD_DEVTOOLSADB = ThreadType::THREAD_DEVTOOLSADB;
+  static inline const ThreadType THREAD_NETWORKCONFIGWATCHER = ThreadType::THREAD_NETWORKCONFIGWATCHER;
+  static inline const ThreadType THREAD_WASAPI_RENDER = ThreadType::THREAD_WASAPI_RENDER;
+  static inline const ThreadType THREAD_LOADER_LOCK_SAMPLER = ThreadType::THREAD_LOADER_LOCK_SAMPLER;
+  static inline const ThreadType THREAD_MEMORY_INFRA = ThreadType::THREAD_MEMORY_INFRA;
+  static inline const ThreadType THREAD_SAMPLING_PROFILER = ThreadType::THREAD_SAMPLING_PROFILER;
+
+  using FieldMetadata_ThreadType =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType,
+      ChromeThreadDescriptor>;
+
+  static constexpr FieldMetadata_ThreadType kThreadType{};
+  void set_thread_type(::perfetto::protos::pbzero::ChromeThreadDescriptor_ThreadType value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LegacySortIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ChromeThreadDescriptor>;
+
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex{};
+  void set_legacy_sort_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_user_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ChromeUserEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeUserEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeUserEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeUserEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_action() const { return at<1>().valid(); }
+  ::protozero::ConstChars action() const { return at<1>().as_string(); }
+  bool has_action_hash() const { return at<2>().valid(); }
+  uint64_t action_hash() const { return at<2>().as_uint64(); }
+};
+
+class ChromeUserEvent : public ::protozero::Message {
+ public:
+  using Decoder = ChromeUserEvent_Decoder;
+  enum : int32_t {
+    kActionFieldNumber = 1,
+    kActionHashFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeUserEvent"; }
+
+
+  using FieldMetadata_Action =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeUserEvent>;
+
+  static constexpr FieldMetadata_Action kAction{};
+  void set_action(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Action::kFieldId, data, size);
+  }
+  void set_action(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Action::kFieldId, chars.data, chars.size);
+  }
+  void set_action(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Action::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ActionHash =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeUserEvent>;
+
+  static constexpr FieldMetadata_ActionHash kActionHash{};
+  void set_action_hash(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ActionHash::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class ChromeWindowHandleEventInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeWindowHandleEventInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeWindowHandleEventInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeWindowHandleEventInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_dpi() const { return at<1>().valid(); }
+  uint32_t dpi() const { return at<1>().as_uint32(); }
+  bool has_message_id() const { return at<2>().valid(); }
+  uint32_t message_id() const { return at<2>().as_uint32(); }
+  bool has_hwnd_ptr() const { return at<3>().valid(); }
+  uint64_t hwnd_ptr() const { return at<3>().as_uint64(); }
+};
+
+class ChromeWindowHandleEventInfo : public ::protozero::Message {
+ public:
+  using Decoder = ChromeWindowHandleEventInfo_Decoder;
+  enum : int32_t {
+    kDpiFieldNumber = 1,
+    kMessageIdFieldNumber = 2,
+    kHwndPtrFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeWindowHandleEventInfo"; }
+
+
+  using FieldMetadata_Dpi =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeWindowHandleEventInfo>;
+
+  static constexpr FieldMetadata_Dpi kDpi{};
+  void set_dpi(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Dpi::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MessageId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromeWindowHandleEventInfo>;
+
+  static constexpr FieldMetadata_MessageId kMessageId{};
+  void set_message_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MessageId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HwndPtr =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64,
+      uint64_t,
+      ChromeWindowHandleEventInfo>;
+
+  static constexpr FieldMetadata_HwndPtr kHwndPtr{};
+  void set_hwnd_ptr(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_HwndPtr::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFixed64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/log_message.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_LogMessage {
+enum Priority : int32_t;
+}  // namespace perfetto_pbzero_enum_LogMessage
+using LogMessage_Priority = perfetto_pbzero_enum_LogMessage::Priority;
+
+namespace perfetto_pbzero_enum_LogMessage {
+enum Priority : int32_t {
+  PRIO_UNSPECIFIED = 0,
+  PRIO_UNUSED = 1,
+  PRIO_VERBOSE = 2,
+  PRIO_DEBUG = 3,
+  PRIO_INFO = 4,
+  PRIO_WARN = 5,
+  PRIO_ERROR = 6,
+  PRIO_FATAL = 7,
+};
+} // namespace perfetto_pbzero_enum_LogMessage
+using LogMessage_Priority = perfetto_pbzero_enum_LogMessage::Priority;
+
+
+constexpr LogMessage_Priority LogMessage_Priority_MIN = LogMessage_Priority::PRIO_UNSPECIFIED;
+constexpr LogMessage_Priority LogMessage_Priority_MAX = LogMessage_Priority::PRIO_FATAL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* LogMessage_Priority_Name(::perfetto::protos::pbzero::LogMessage_Priority value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_UNSPECIFIED:
+    return "PRIO_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_UNUSED:
+    return "PRIO_UNUSED";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_VERBOSE:
+    return "PRIO_VERBOSE";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_DEBUG:
+    return "PRIO_DEBUG";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_INFO:
+    return "PRIO_INFO";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_WARN:
+    return "PRIO_WARN";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_ERROR:
+    return "PRIO_ERROR";
+
+  case ::perfetto::protos::pbzero::LogMessage_Priority::PRIO_FATAL:
+    return "PRIO_FATAL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class LogMessageBody_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LogMessageBody_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LogMessageBody_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LogMessageBody_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_body() const { return at<2>().valid(); }
+  ::protozero::ConstChars body() const { return at<2>().as_string(); }
+};
+
+class LogMessageBody : public ::protozero::Message {
+ public:
+  using Decoder = LogMessageBody_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kBodyFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LogMessageBody"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LogMessageBody>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Body =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      LogMessageBody>;
+
+  static constexpr FieldMetadata_Body kBody{};
+  void set_body(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Body::kFieldId, data, size);
+  }
+  void set_body(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Body::kFieldId, chars.data, chars.size);
+  }
+  void set_body(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Body::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class LogMessage_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  LogMessage_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit LogMessage_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit LogMessage_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_source_location_iid() const { return at<1>().valid(); }
+  uint64_t source_location_iid() const { return at<1>().as_uint64(); }
+  bool has_body_iid() const { return at<2>().valid(); }
+  uint64_t body_iid() const { return at<2>().as_uint64(); }
+  bool has_prio() const { return at<3>().valid(); }
+  int32_t prio() const { return at<3>().as_int32(); }
+};
+
+class LogMessage : public ::protozero::Message {
+ public:
+  using Decoder = LogMessage_Decoder;
+  enum : int32_t {
+    kSourceLocationIidFieldNumber = 1,
+    kBodyIidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.LogMessage"; }
+
+
+  using Priority = ::perfetto::protos::pbzero::LogMessage_Priority;
+  static inline const char* Priority_Name(Priority value) {
+    return ::perfetto::protos::pbzero::LogMessage_Priority_Name(value);
+  }
+  static inline const Priority PRIO_UNSPECIFIED = Priority::PRIO_UNSPECIFIED;
+  static inline const Priority PRIO_UNUSED = Priority::PRIO_UNUSED;
+  static inline const Priority PRIO_VERBOSE = Priority::PRIO_VERBOSE;
+  static inline const Priority PRIO_DEBUG = Priority::PRIO_DEBUG;
+  static inline const Priority PRIO_INFO = Priority::PRIO_INFO;
+  static inline const Priority PRIO_WARN = Priority::PRIO_WARN;
+  static inline const Priority PRIO_ERROR = Priority::PRIO_ERROR;
+  static inline const Priority PRIO_FATAL = Priority::PRIO_FATAL;
+
+  using FieldMetadata_SourceLocationIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LogMessage>;
+
+  static constexpr FieldMetadata_SourceLocationIid kSourceLocationIid{};
+  void set_source_location_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceLocationIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BodyIid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      LogMessage>;
+
+  static constexpr FieldMetadata_BodyIid kBodyIid{};
+  void set_body_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_BodyIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Prio =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::LogMessage_Priority,
+      LogMessage>;
+
+  static constexpr FieldMetadata_Prio kPrio{};
+  void set_prio(::perfetto::protos::pbzero::LogMessage_Priority value) {
+    static constexpr uint32_t field_id = FieldMetadata_Prio::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ProcessDescriptor {
+enum ChromeProcessType : int32_t;
+}  // namespace perfetto_pbzero_enum_ProcessDescriptor
+using ProcessDescriptor_ChromeProcessType = perfetto_pbzero_enum_ProcessDescriptor::ChromeProcessType;
+
+namespace perfetto_pbzero_enum_ProcessDescriptor {
+enum ChromeProcessType : int32_t {
+  PROCESS_UNSPECIFIED = 0,
+  PROCESS_BROWSER = 1,
+  PROCESS_RENDERER = 2,
+  PROCESS_UTILITY = 3,
+  PROCESS_ZYGOTE = 4,
+  PROCESS_SANDBOX_HELPER = 5,
+  PROCESS_GPU = 6,
+  PROCESS_PPAPI_PLUGIN = 7,
+  PROCESS_PPAPI_BROKER = 8,
+};
+} // namespace perfetto_pbzero_enum_ProcessDescriptor
+using ProcessDescriptor_ChromeProcessType = perfetto_pbzero_enum_ProcessDescriptor::ChromeProcessType;
+
+
+constexpr ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType::PROCESS_UNSPECIFIED;
+constexpr ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType::PROCESS_PPAPI_BROKER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ProcessDescriptor_ChromeProcessType_Name(::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_UNSPECIFIED:
+    return "PROCESS_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_BROWSER:
+    return "PROCESS_BROWSER";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_RENDERER:
+    return "PROCESS_RENDERER";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_UTILITY:
+    return "PROCESS_UTILITY";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_ZYGOTE:
+    return "PROCESS_ZYGOTE";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_SANDBOX_HELPER:
+    return "PROCESS_SANDBOX_HELPER";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_GPU:
+    return "PROCESS_GPU";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_PPAPI_PLUGIN:
+    return "PROCESS_PPAPI_PLUGIN";
+
+  case ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType::PROCESS_PPAPI_BROKER:
+    return "PROCESS_PPAPI_BROKER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ProcessDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_cmdline() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> cmdline() const { return GetRepeated<::protozero::ConstChars>(2); }
+  bool has_process_name() const { return at<6>().valid(); }
+  ::protozero::ConstChars process_name() const { return at<6>().as_string(); }
+  bool has_process_priority() const { return at<5>().valid(); }
+  int32_t process_priority() const { return at<5>().as_int32(); }
+  bool has_start_timestamp_ns() const { return at<7>().valid(); }
+  int64_t start_timestamp_ns() const { return at<7>().as_int64(); }
+  bool has_chrome_process_type() const { return at<4>().valid(); }
+  int32_t chrome_process_type() const { return at<4>().as_int32(); }
+  bool has_legacy_sort_index() const { return at<3>().valid(); }
+  int32_t legacy_sort_index() const { return at<3>().as_int32(); }
+  bool has_process_labels() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> process_labels() const { return GetRepeated<::protozero::ConstChars>(8); }
+};
+
+class ProcessDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = ProcessDescriptor_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kCmdlineFieldNumber = 2,
+    kProcessNameFieldNumber = 6,
+    kProcessPriorityFieldNumber = 5,
+    kStartTimestampNsFieldNumber = 7,
+    kChromeProcessTypeFieldNumber = 4,
+    kLegacySortIndexFieldNumber = 3,
+    kProcessLabelsFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessDescriptor"; }
+
+
+  using ChromeProcessType = ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType;
+  static inline const char* ChromeProcessType_Name(ChromeProcessType value) {
+    return ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType_Name(value);
+  }
+  static inline const ChromeProcessType PROCESS_UNSPECIFIED = ChromeProcessType::PROCESS_UNSPECIFIED;
+  static inline const ChromeProcessType PROCESS_BROWSER = ChromeProcessType::PROCESS_BROWSER;
+  static inline const ChromeProcessType PROCESS_RENDERER = ChromeProcessType::PROCESS_RENDERER;
+  static inline const ChromeProcessType PROCESS_UTILITY = ChromeProcessType::PROCESS_UTILITY;
+  static inline const ChromeProcessType PROCESS_ZYGOTE = ChromeProcessType::PROCESS_ZYGOTE;
+  static inline const ChromeProcessType PROCESS_SANDBOX_HELPER = ChromeProcessType::PROCESS_SANDBOX_HELPER;
+  static inline const ChromeProcessType PROCESS_GPU = ChromeProcessType::PROCESS_GPU;
+  static inline const ChromeProcessType PROCESS_PPAPI_PLUGIN = ChromeProcessType::PROCESS_PPAPI_PLUGIN;
+  static inline const ChromeProcessType PROCESS_PPAPI_BROKER = ChromeProcessType::PROCESS_PPAPI_BROKER;
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void add_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void add_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessName =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_ProcessName kProcessName{};
+  void set_process_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessName::kFieldId, data, size);
+  }
+  void set_process_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProcessName::kFieldId, chars.data, chars.size);
+  }
+  void set_process_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessPriority =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_ProcessPriority kProcessPriority{};
+  void set_process_priority(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessPriority::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StartTimestampNs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_StartTimestampNs kStartTimestampNs{};
+  void set_start_timestamp_ns(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartTimestampNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChromeProcessType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_ChromeProcessType kChromeProcessType{};
+  void set_chrome_process_type(::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChromeProcessType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LegacySortIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex{};
+  void set_legacy_sort_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessLabels =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessDescriptor>;
+
+  static constexpr FieldMetadata_ProcessLabels kProcessLabels{};
+  void add_process_labels(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ProcessLabels::kFieldId, data, size);
+  }
+  void add_process_labels(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ProcessLabels::kFieldId, chars.data, chars.size);
+  }
+  void add_process_labels(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ProcessLabels::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/range_of_interest.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_RANGE_OF_INTEREST_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_RANGE_OF_INTEREST_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class TrackEventRangeOfInterest_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TrackEventRangeOfInterest_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TrackEventRangeOfInterest_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TrackEventRangeOfInterest_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_start_us() const { return at<1>().valid(); }
+  int64_t start_us() const { return at<1>().as_int64(); }
+};
+
+class TrackEventRangeOfInterest : public ::protozero::Message {
+ public:
+  using Decoder = TrackEventRangeOfInterest_Decoder;
+  enum : int32_t {
+    kStartUsFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TrackEventRangeOfInterest"; }
+
+
+  using FieldMetadata_StartUs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      TrackEventRangeOfInterest>;
+
+  static constexpr FieldMetadata_StartUs kStartUs{};
+  void set_start_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StartUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/screenshot.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SCREENSHOT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SCREENSHOT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class Screenshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Screenshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Screenshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Screenshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_jpg_image() const { return at<1>().valid(); }
+  ::protozero::ConstBytes jpg_image() const { return at<1>().as_bytes(); }
+};
+
+class Screenshot : public ::protozero::Message {
+ public:
+  using Decoder = Screenshot_Decoder;
+  enum : int32_t {
+    kJpgImageFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Screenshot"; }
+
+
+  using FieldMetadata_JpgImage =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBytes,
+      std::string,
+      Screenshot>;
+
+  static constexpr FieldMetadata_JpgImage kJpgImage{};
+  void set_jpg_image(const uint8_t* data, size_t size) {
+    AppendBytes(FieldMetadata_JpgImage::kFieldId, data, size);
+  }
+  void set_jpg_image(::protozero::ConstBytes bytes) {
+    AppendBytes(FieldMetadata_JpgImage::kFieldId, bytes.data, bytes.size);
+  }
+  void set_jpg_image(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_JpgImage::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBytes>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/source_location.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class SourceLocation_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SourceLocation_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SourceLocation_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SourceLocation_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_file_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars file_name() const { return at<2>().as_string(); }
+  bool has_function_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars function_name() const { return at<3>().as_string(); }
+  bool has_line_number() const { return at<4>().valid(); }
+  uint32_t line_number() const { return at<4>().as_uint32(); }
+};
+
+class SourceLocation : public ::protozero::Message {
+ public:
+  using Decoder = SourceLocation_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kFileNameFieldNumber = 2,
+    kFunctionNameFieldNumber = 3,
+    kLineNumberFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SourceLocation"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SourceLocation>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FileName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SourceLocation>;
+
+  static constexpr FieldMetadata_FileName kFileName{};
+  void set_file_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FileName::kFieldId, data, size);
+  }
+  void set_file_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FileName::kFieldId, chars.data, chars.size);
+  }
+  void set_file_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FileName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FunctionName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SourceLocation>;
+
+  static constexpr FieldMetadata_FunctionName kFunctionName{};
+  void set_function_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, data, size);
+  }
+  void set_function_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_FunctionName::kFieldId, chars.data, chars.size);
+  }
+  void set_function_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_FunctionName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LineNumber =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SourceLocation>;
+
+  static constexpr FieldMetadata_LineNumber kLineNumber{};
+  void set_line_number(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LineNumber::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class UnsymbolizedSourceLocation_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UnsymbolizedSourceLocation_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UnsymbolizedSourceLocation_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UnsymbolizedSourceLocation_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_mapping_id() const { return at<2>().valid(); }
+  uint64_t mapping_id() const { return at<2>().as_uint64(); }
+  bool has_rel_pc() const { return at<3>().valid(); }
+  uint64_t rel_pc() const { return at<3>().as_uint64(); }
+};
+
+class UnsymbolizedSourceLocation : public ::protozero::Message {
+ public:
+  using Decoder = UnsymbolizedSourceLocation_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kMappingIdFieldNumber = 2,
+    kRelPcFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UnsymbolizedSourceLocation"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      UnsymbolizedSourceLocation>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_MappingId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      UnsymbolizedSourceLocation>;
+
+  static constexpr FieldMetadata_MappingId kMappingId{};
+  void set_mapping_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_MappingId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RelPc =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      UnsymbolizedSourceLocation>;
+
+  static constexpr FieldMetadata_RelPc kRelPc{};
+  void set_rel_pc(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RelPc::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/task_execution.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class TaskExecution_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TaskExecution_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TaskExecution_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TaskExecution_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_posted_from_iid() const { return at<1>().valid(); }
+  uint64_t posted_from_iid() const { return at<1>().as_uint64(); }
+};
+
+class TaskExecution : public ::protozero::Message {
+ public:
+  using Decoder = TaskExecution_Decoder;
+  enum : int32_t {
+    kPostedFromIidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TaskExecution"; }
+
+
+  using FieldMetadata_PostedFromIid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TaskExecution>;
+
+  static constexpr FieldMetadata_PostedFromIid kPostedFromIid{};
+  void set_posted_from_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_PostedFromIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+namespace perfetto_pbzero_enum_ThreadDescriptor {
+enum ChromeThreadType : int32_t;
+}  // namespace perfetto_pbzero_enum_ThreadDescriptor
+using ThreadDescriptor_ChromeThreadType = perfetto_pbzero_enum_ThreadDescriptor::ChromeThreadType;
+
+namespace perfetto_pbzero_enum_ThreadDescriptor {
+enum ChromeThreadType : int32_t {
+  CHROME_THREAD_UNSPECIFIED = 0,
+  CHROME_THREAD_MAIN = 1,
+  CHROME_THREAD_IO = 2,
+  CHROME_THREAD_POOL_BG_WORKER = 3,
+  CHROME_THREAD_POOL_FG_WORKER = 4,
+  CHROME_THREAD_POOL_FB_BLOCKING = 5,
+  CHROME_THREAD_POOL_BG_BLOCKING = 6,
+  CHROME_THREAD_POOL_SERVICE = 7,
+  CHROME_THREAD_COMPOSITOR = 8,
+  CHROME_THREAD_VIZ_COMPOSITOR = 9,
+  CHROME_THREAD_COMPOSITOR_WORKER = 10,
+  CHROME_THREAD_SERVICE_WORKER = 11,
+  CHROME_THREAD_MEMORY_INFRA = 50,
+  CHROME_THREAD_SAMPLING_PROFILER = 51,
+};
+} // namespace perfetto_pbzero_enum_ThreadDescriptor
+using ThreadDescriptor_ChromeThreadType = perfetto_pbzero_enum_ThreadDescriptor::ChromeThreadType;
+
+
+constexpr ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType::CHROME_THREAD_UNSPECIFIED;
+constexpr ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType::CHROME_THREAD_SAMPLING_PROFILER;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* ThreadDescriptor_ChromeThreadType_Name(::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_UNSPECIFIED:
+    return "CHROME_THREAD_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_MAIN:
+    return "CHROME_THREAD_MAIN";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_IO:
+    return "CHROME_THREAD_IO";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_POOL_BG_WORKER:
+    return "CHROME_THREAD_POOL_BG_WORKER";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_POOL_FG_WORKER:
+    return "CHROME_THREAD_POOL_FG_WORKER";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_POOL_FB_BLOCKING:
+    return "CHROME_THREAD_POOL_FB_BLOCKING";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_POOL_BG_BLOCKING:
+    return "CHROME_THREAD_POOL_BG_BLOCKING";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_POOL_SERVICE:
+    return "CHROME_THREAD_POOL_SERVICE";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_COMPOSITOR:
+    return "CHROME_THREAD_COMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_VIZ_COMPOSITOR:
+    return "CHROME_THREAD_VIZ_COMPOSITOR";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_COMPOSITOR_WORKER:
+    return "CHROME_THREAD_COMPOSITOR_WORKER";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_SERVICE_WORKER:
+    return "CHROME_THREAD_SERVICE_WORKER";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_MEMORY_INFRA:
+    return "CHROME_THREAD_MEMORY_INFRA";
+
+  case ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType::CHROME_THREAD_SAMPLING_PROFILER:
+    return "CHROME_THREAD_SAMPLING_PROFILER";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class ThreadDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ThreadDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ThreadDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ThreadDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_tid() const { return at<2>().valid(); }
+  int32_t tid() const { return at<2>().as_int32(); }
+  bool has_thread_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars thread_name() const { return at<5>().as_string(); }
+  bool has_chrome_thread_type() const { return at<4>().valid(); }
+  int32_t chrome_thread_type() const { return at<4>().as_int32(); }
+  bool has_reference_timestamp_us() const { return at<6>().valid(); }
+  int64_t reference_timestamp_us() const { return at<6>().as_int64(); }
+  bool has_reference_thread_time_us() const { return at<7>().valid(); }
+  int64_t reference_thread_time_us() const { return at<7>().as_int64(); }
+  bool has_reference_thread_instruction_count() const { return at<8>().valid(); }
+  int64_t reference_thread_instruction_count() const { return at<8>().as_int64(); }
+  bool has_legacy_sort_index() const { return at<3>().valid(); }
+  int32_t legacy_sort_index() const { return at<3>().as_int32(); }
+};
+
+class ThreadDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = ThreadDescriptor_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kTidFieldNumber = 2,
+    kThreadNameFieldNumber = 5,
+    kChromeThreadTypeFieldNumber = 4,
+    kReferenceTimestampUsFieldNumber = 6,
+    kReferenceThreadTimeUsFieldNumber = 7,
+    kReferenceThreadInstructionCountFieldNumber = 8,
+    kLegacySortIndexFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ThreadDescriptor"; }
+
+
+  using ChromeThreadType = ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType;
+  static inline const char* ChromeThreadType_Name(ChromeThreadType value) {
+    return ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType_Name(value);
+  }
+  static inline const ChromeThreadType CHROME_THREAD_UNSPECIFIED = ChromeThreadType::CHROME_THREAD_UNSPECIFIED;
+  static inline const ChromeThreadType CHROME_THREAD_MAIN = ChromeThreadType::CHROME_THREAD_MAIN;
+  static inline const ChromeThreadType CHROME_THREAD_IO = ChromeThreadType::CHROME_THREAD_IO;
+  static inline const ChromeThreadType CHROME_THREAD_POOL_BG_WORKER = ChromeThreadType::CHROME_THREAD_POOL_BG_WORKER;
+  static inline const ChromeThreadType CHROME_THREAD_POOL_FG_WORKER = ChromeThreadType::CHROME_THREAD_POOL_FG_WORKER;
+  static inline const ChromeThreadType CHROME_THREAD_POOL_FB_BLOCKING = ChromeThreadType::CHROME_THREAD_POOL_FB_BLOCKING;
+  static inline const ChromeThreadType CHROME_THREAD_POOL_BG_BLOCKING = ChromeThreadType::CHROME_THREAD_POOL_BG_BLOCKING;
+  static inline const ChromeThreadType CHROME_THREAD_POOL_SERVICE = ChromeThreadType::CHROME_THREAD_POOL_SERVICE;
+  static inline const ChromeThreadType CHROME_THREAD_COMPOSITOR = ChromeThreadType::CHROME_THREAD_COMPOSITOR;
+  static inline const ChromeThreadType CHROME_THREAD_VIZ_COMPOSITOR = ChromeThreadType::CHROME_THREAD_VIZ_COMPOSITOR;
+  static inline const ChromeThreadType CHROME_THREAD_COMPOSITOR_WORKER = ChromeThreadType::CHROME_THREAD_COMPOSITOR_WORKER;
+  static inline const ChromeThreadType CHROME_THREAD_SERVICE_WORKER = ChromeThreadType::CHROME_THREAD_SERVICE_WORKER;
+  static inline const ChromeThreadType CHROME_THREAD_MEMORY_INFRA = ChromeThreadType::CHROME_THREAD_MEMORY_INFRA;
+  static inline const ChromeThreadType CHROME_THREAD_SAMPLING_PROFILER = ChromeThreadType::CHROME_THREAD_SAMPLING_PROFILER;
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadName =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_ThreadName kThreadName{};
+  void set_thread_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ThreadName::kFieldId, data, size);
+  }
+  void set_thread_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ThreadName::kFieldId, chars.data, chars.size);
+  }
+  void set_thread_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChromeThreadType =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_ChromeThreadType kChromeThreadType{};
+  void set_chrome_thread_type(::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChromeThreadType::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReferenceTimestampUs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_ReferenceTimestampUs kReferenceTimestampUs{};
+  void set_reference_timestamp_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReferenceTimestampUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReferenceThreadTimeUs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_ReferenceThreadTimeUs kReferenceThreadTimeUs{};
+  void set_reference_thread_time_us(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReferenceThreadTimeUs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReferenceThreadInstructionCount =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_ReferenceThreadInstructionCount kReferenceThreadInstructionCount{};
+  void set_reference_thread_instruction_count(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReferenceThreadInstructionCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LegacySortIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ThreadDescriptor>;
+
+  static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex{};
+  void set_legacy_sort_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_PERFETTO_METATRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_PERFETTO_METATRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PerfettoMetatrace_Arg;
+class PerfettoMetatrace_InternedString;
+
+class PerfettoMetatrace_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PerfettoMetatrace_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfettoMetatrace_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfettoMetatrace_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_event_id() const { return at<1>().valid(); }
+  uint32_t event_id() const { return at<1>().as_uint32(); }
+  bool has_counter_id() const { return at<2>().valid(); }
+  uint32_t counter_id() const { return at<2>().as_uint32(); }
+  bool has_event_name() const { return at<8>().valid(); }
+  ::protozero::ConstChars event_name() const { return at<8>().as_string(); }
+  bool has_event_name_iid() const { return at<11>().valid(); }
+  uint64_t event_name_iid() const { return at<11>().as_uint64(); }
+  bool has_counter_name() const { return at<9>().valid(); }
+  ::protozero::ConstChars counter_name() const { return at<9>().as_string(); }
+  bool has_event_duration_ns() const { return at<3>().valid(); }
+  uint64_t event_duration_ns() const { return at<3>().as_uint64(); }
+  bool has_counter_value() const { return at<4>().valid(); }
+  int32_t counter_value() const { return at<4>().as_int32(); }
+  bool has_thread_id() const { return at<5>().valid(); }
+  uint32_t thread_id() const { return at<5>().as_uint32(); }
+  bool has_has_overruns() const { return at<6>().valid(); }
+  bool has_overruns() const { return at<6>().as_bool(); }
+  bool has_args() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> args() const { return GetRepeated<::protozero::ConstBytes>(7); }
+  bool has_interned_strings() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> interned_strings() const { return GetRepeated<::protozero::ConstBytes>(10); }
+};
+
+class PerfettoMetatrace : public ::protozero::Message {
+ public:
+  using Decoder = PerfettoMetatrace_Decoder;
+  enum : int32_t {
+    kEventIdFieldNumber = 1,
+    kCounterIdFieldNumber = 2,
+    kEventNameFieldNumber = 8,
+    kEventNameIidFieldNumber = 11,
+    kCounterNameFieldNumber = 9,
+    kEventDurationNsFieldNumber = 3,
+    kCounterValueFieldNumber = 4,
+    kThreadIdFieldNumber = 5,
+    kHasOverrunsFieldNumber = 6,
+    kArgsFieldNumber = 7,
+    kInternedStringsFieldNumber = 10,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfettoMetatrace"; }
+
+  using Arg = ::perfetto::protos::pbzero::PerfettoMetatrace_Arg;
+  using InternedString = ::perfetto::protos::pbzero::PerfettoMetatrace_InternedString;
+
+  using FieldMetadata_EventId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_EventId kEventId{};
+  void set_event_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CounterId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_CounterId kCounterId{};
+  void set_counter_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EventName =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_EventName kEventName{};
+  void set_event_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, data, size);
+  }
+  void set_event_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EventName::kFieldId, chars.data, chars.size);
+  }
+  void set_event_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EventNameIid =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_EventNameIid kEventNameIid{};
+  void set_event_name_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventNameIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CounterName =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_CounterName kCounterName{};
+  void set_counter_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, data, size);
+  }
+  void set_counter_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_CounterName::kFieldId, chars.data, chars.size);
+  }
+  void set_counter_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EventDurationNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_EventDurationNs kEventDurationNs{};
+  void set_event_duration_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EventDurationNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CounterValue =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_CounterValue kCounterValue{};
+  void set_counter_value(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CounterValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadId =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_ThreadId kThreadId{};
+  void set_thread_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ThreadId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HasOverruns =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_HasOverruns kHasOverruns{};
+  void set_has_overruns(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_HasOverruns::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Args =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfettoMetatrace_Arg,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_Args kArgs{};
+  template <typename T = PerfettoMetatrace_Arg> T* add_args() {
+    return BeginNestedMessage<T>(7);
+  }
+
+
+  using FieldMetadata_InternedStrings =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfettoMetatrace_InternedString,
+      PerfettoMetatrace>;
+
+  static constexpr FieldMetadata_InternedStrings kInternedStrings{};
+  template <typename T = PerfettoMetatrace_InternedString> T* add_interned_strings() {
+    return BeginNestedMessage<T>(10);
+  }
+
+};
+
+class PerfettoMetatrace_InternedString_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfettoMetatrace_InternedString_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfettoMetatrace_InternedString_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfettoMetatrace_InternedString_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_iid() const { return at<1>().valid(); }
+  uint64_t iid() const { return at<1>().as_uint64(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class PerfettoMetatrace_InternedString : public ::protozero::Message {
+ public:
+  using Decoder = PerfettoMetatrace_InternedString_Decoder;
+  enum : int32_t {
+    kIidFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfettoMetatrace.InternedString"; }
+
+
+  using FieldMetadata_Iid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfettoMetatrace_InternedString>;
+
+  static constexpr FieldMetadata_Iid kIid{};
+  void set_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Iid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace_InternedString>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PerfettoMetatrace_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PerfettoMetatrace_Arg_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PerfettoMetatrace_Arg_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PerfettoMetatrace_Arg_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  ::protozero::ConstChars key() const { return at<1>().as_string(); }
+  bool has_key_iid() const { return at<3>().valid(); }
+  uint64_t key_iid() const { return at<3>().as_uint64(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+  bool has_value_iid() const { return at<4>().valid(); }
+  uint64_t value_iid() const { return at<4>().as_uint64(); }
+};
+
+class PerfettoMetatrace_Arg : public ::protozero::Message {
+ public:
+  using Decoder = PerfettoMetatrace_Arg_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kKeyIidFieldNumber = 3,
+    kValueFieldNumber = 2,
+    kValueIidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PerfettoMetatrace.Arg"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace_Arg>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Key::kFieldId, data, size);
+  }
+  void set_key(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Key::kFieldId, chars.data, chars.size);
+  }
+  void set_key(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_KeyIid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfettoMetatrace_Arg>;
+
+  static constexpr FieldMetadata_KeyIid kKeyIid{};
+  void set_key_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_KeyIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PerfettoMetatrace_Arg>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ValueIid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PerfettoMetatrace_Arg>;
+
+  static constexpr FieldMetadata_ValueIid kValueIid{};
+  void set_value_iid(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ValueIid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_TRACING_SERVICE_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_TRACING_SERVICE_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class TracingServiceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracingServiceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracingServiceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracingServiceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tracing_started() const { return at<2>().valid(); }
+  bool tracing_started() const { return at<2>().as_bool(); }
+  bool has_all_data_sources_started() const { return at<1>().valid(); }
+  bool all_data_sources_started() const { return at<1>().as_bool(); }
+  bool has_all_data_sources_flushed() const { return at<3>().valid(); }
+  bool all_data_sources_flushed() const { return at<3>().as_bool(); }
+  bool has_read_tracing_buffers_completed() const { return at<4>().valid(); }
+  bool read_tracing_buffers_completed() const { return at<4>().as_bool(); }
+  bool has_tracing_disabled() const { return at<5>().valid(); }
+  bool tracing_disabled() const { return at<5>().as_bool(); }
+  bool has_seized_for_bugreport() const { return at<6>().valid(); }
+  bool seized_for_bugreport() const { return at<6>().as_bool(); }
+};
+
+class TracingServiceEvent : public ::protozero::Message {
+ public:
+  using Decoder = TracingServiceEvent_Decoder;
+  enum : int32_t {
+    kTracingStartedFieldNumber = 2,
+    kAllDataSourcesStartedFieldNumber = 1,
+    kAllDataSourcesFlushedFieldNumber = 3,
+    kReadTracingBuffersCompletedFieldNumber = 4,
+    kTracingDisabledFieldNumber = 5,
+    kSeizedForBugreportFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracingServiceEvent"; }
+
+
+  using FieldMetadata_TracingStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_TracingStarted kTracingStarted{};
+  void set_tracing_started(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingStarted::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllDataSourcesStarted =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_AllDataSourcesStarted kAllDataSourcesStarted{};
+  void set_all_data_sources_started(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllDataSourcesStarted::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllDataSourcesFlushed =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_AllDataSourcesFlushed kAllDataSourcesFlushed{};
+  void set_all_data_sources_flushed(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_AllDataSourcesFlushed::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReadTracingBuffersCompleted =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_ReadTracingBuffersCompleted kReadTracingBuffersCompleted{};
+  void set_read_tracing_buffers_completed(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadTracingBuffersCompleted::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TracingDisabled =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_TracingDisabled kTracingDisabled{};
+  void set_tracing_disabled(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_TracingDisabled::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SeizedForBugreport =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TracingServiceEvent>;
+
+  static constexpr FieldMetadata_SeizedForBugreport kSeizedForBugreport{};
+  void set_seized_for_bugreport(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_SeizedForBugreport::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_ANDROID_ENERGY_ESTIMATION_BREAKDOWN_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_ANDROID_ENERGY_ESTIMATION_BREAKDOWN_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class AndroidEnergyConsumerDescriptor;
+class AndroidEnergyEstimationBreakdown_EnergyUidBreakdown;
+
+class AndroidEnergyEstimationBreakdown_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  AndroidEnergyEstimationBreakdown_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidEnergyEstimationBreakdown_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidEnergyEstimationBreakdown_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_energy_consumer_descriptor() const { return at<1>().valid(); }
+  ::protozero::ConstBytes energy_consumer_descriptor() const { return at<1>().as_bytes(); }
+  bool has_energy_consumer_id() const { return at<2>().valid(); }
+  int32_t energy_consumer_id() const { return at<2>().as_int32(); }
+  bool has_energy_uws() const { return at<3>().valid(); }
+  int64_t energy_uws() const { return at<3>().as_int64(); }
+  bool has_per_uid_breakdown() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> per_uid_breakdown() const { return GetRepeated<::protozero::ConstBytes>(4); }
+};
+
+class AndroidEnergyEstimationBreakdown : public ::protozero::Message {
+ public:
+  using Decoder = AndroidEnergyEstimationBreakdown_Decoder;
+  enum : int32_t {
+    kEnergyConsumerDescriptorFieldNumber = 1,
+    kEnergyConsumerIdFieldNumber = 2,
+    kEnergyUwsFieldNumber = 3,
+    kPerUidBreakdownFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidEnergyEstimationBreakdown"; }
+
+  using EnergyUidBreakdown = ::perfetto::protos::pbzero::AndroidEnergyEstimationBreakdown_EnergyUidBreakdown;
+
+  using FieldMetadata_EnergyConsumerDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidEnergyConsumerDescriptor,
+      AndroidEnergyEstimationBreakdown>;
+
+  static constexpr FieldMetadata_EnergyConsumerDescriptor kEnergyConsumerDescriptor{};
+  template <typename T = AndroidEnergyConsumerDescriptor> T* set_energy_consumer_descriptor() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_EnergyConsumerId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidEnergyEstimationBreakdown>;
+
+  static constexpr FieldMetadata_EnergyConsumerId kEnergyConsumerId{};
+  void set_energy_consumer_id(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnergyConsumerId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnergyUws =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidEnergyEstimationBreakdown>;
+
+  static constexpr FieldMetadata_EnergyUws kEnergyUws{};
+  void set_energy_uws(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnergyUws::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_PerUidBreakdown =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      AndroidEnergyEstimationBreakdown_EnergyUidBreakdown,
+      AndroidEnergyEstimationBreakdown>;
+
+  static constexpr FieldMetadata_PerUidBreakdown kPerUidBreakdown{};
+  template <typename T = AndroidEnergyEstimationBreakdown_EnergyUidBreakdown> T* add_per_uid_breakdown() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+class AndroidEnergyEstimationBreakdown_EnergyUidBreakdown_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  AndroidEnergyEstimationBreakdown_EnergyUidBreakdown_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit AndroidEnergyEstimationBreakdown_EnergyUidBreakdown_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit AndroidEnergyEstimationBreakdown_EnergyUidBreakdown_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_uid() const { return at<1>().valid(); }
+  int32_t uid() const { return at<1>().as_int32(); }
+  bool has_energy_uws() const { return at<2>().valid(); }
+  int64_t energy_uws() const { return at<2>().as_int64(); }
+};
+
+class AndroidEnergyEstimationBreakdown_EnergyUidBreakdown : public ::protozero::Message {
+ public:
+  using Decoder = AndroidEnergyEstimationBreakdown_EnergyUidBreakdown_Decoder;
+  enum : int32_t {
+    kUidFieldNumber = 1,
+    kEnergyUwsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.AndroidEnergyEstimationBreakdown.EnergyUidBreakdown"; }
+
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      AndroidEnergyEstimationBreakdown_EnergyUidBreakdown>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnergyUws =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      AndroidEnergyEstimationBreakdown_EnergyUidBreakdown>;
+
+  static constexpr FieldMetadata_EnergyUws kEnergyUws{};
+  void set_energy_uws(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnergyUws::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/power/android_entity_state_residency.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_ANDROID_ENTITY_STATE_RESIDENCY_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_ANDROID_ENTITY_STATE_RESIDENCY_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class EntityStateResidency_PowerEntityState;
+class EntityStateResidency_StateResidency;
+
+class EntityStateResidency_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  EntityStateResidency_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EntityStateResidency_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EntityStateResidency_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_power_entity_state() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> power_entity_state() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_residency() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> residency() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class EntityStateResidency : public ::protozero::Message {
+ public:
+  using Decoder = EntityStateResidency_Decoder;
+  enum : int32_t {
+    kPowerEntityStateFieldNumber = 1,
+    kResidencyFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EntityStateResidency"; }
+
+  using PowerEntityState = ::perfetto::protos::pbzero::EntityStateResidency_PowerEntityState;
+  using StateResidency = ::perfetto::protos::pbzero::EntityStateResidency_StateResidency;
+
+  using FieldMetadata_PowerEntityState =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EntityStateResidency_PowerEntityState,
+      EntityStateResidency>;
+
+  static constexpr FieldMetadata_PowerEntityState kPowerEntityState{};
+  template <typename T = EntityStateResidency_PowerEntityState> T* add_power_entity_state() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Residency =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      EntityStateResidency_StateResidency,
+      EntityStateResidency>;
+
+  static constexpr FieldMetadata_Residency kResidency{};
+  template <typename T = EntityStateResidency_StateResidency> T* add_residency() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class EntityStateResidency_StateResidency_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EntityStateResidency_StateResidency_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EntityStateResidency_StateResidency_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EntityStateResidency_StateResidency_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_entity_index() const { return at<1>().valid(); }
+  int32_t entity_index() const { return at<1>().as_int32(); }
+  bool has_state_index() const { return at<2>().valid(); }
+  int32_t state_index() const { return at<2>().as_int32(); }
+  bool has_total_time_in_state_ms() const { return at<3>().valid(); }
+  uint64_t total_time_in_state_ms() const { return at<3>().as_uint64(); }
+  bool has_total_state_entry_count() const { return at<4>().valid(); }
+  uint64_t total_state_entry_count() const { return at<4>().as_uint64(); }
+  bool has_last_entry_timestamp_ms() const { return at<5>().valid(); }
+  uint64_t last_entry_timestamp_ms() const { return at<5>().as_uint64(); }
+};
+
+class EntityStateResidency_StateResidency : public ::protozero::Message {
+ public:
+  using Decoder = EntityStateResidency_StateResidency_Decoder;
+  enum : int32_t {
+    kEntityIndexFieldNumber = 1,
+    kStateIndexFieldNumber = 2,
+    kTotalTimeInStateMsFieldNumber = 3,
+    kTotalStateEntryCountFieldNumber = 4,
+    kLastEntryTimestampMsFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EntityStateResidency.StateResidency"; }
+
+
+  using FieldMetadata_EntityIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      EntityStateResidency_StateResidency>;
+
+  static constexpr FieldMetadata_EntityIndex kEntityIndex{};
+  void set_entity_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EntityIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StateIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      EntityStateResidency_StateResidency>;
+
+  static constexpr FieldMetadata_StateIndex kStateIndex{};
+  void set_state_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StateIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalTimeInStateMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EntityStateResidency_StateResidency>;
+
+  static constexpr FieldMetadata_TotalTimeInStateMs kTotalTimeInStateMs{};
+  void set_total_time_in_state_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalTimeInStateMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalStateEntryCount =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EntityStateResidency_StateResidency>;
+
+  static constexpr FieldMetadata_TotalStateEntryCount kTotalStateEntryCount{};
+  void set_total_state_entry_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalStateEntryCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LastEntryTimestampMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      EntityStateResidency_StateResidency>;
+
+  static constexpr FieldMetadata_LastEntryTimestampMs kLastEntryTimestampMs{};
+  void set_last_entry_timestamp_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_LastEntryTimestampMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class EntityStateResidency_PowerEntityState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  EntityStateResidency_PowerEntityState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit EntityStateResidency_PowerEntityState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit EntityStateResidency_PowerEntityState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_entity_index() const { return at<1>().valid(); }
+  int32_t entity_index() const { return at<1>().as_int32(); }
+  bool has_state_index() const { return at<2>().valid(); }
+  int32_t state_index() const { return at<2>().as_int32(); }
+  bool has_entity_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars entity_name() const { return at<3>().as_string(); }
+  bool has_state_name() const { return at<4>().valid(); }
+  ::protozero::ConstChars state_name() const { return at<4>().as_string(); }
+};
+
+class EntityStateResidency_PowerEntityState : public ::protozero::Message {
+ public:
+  using Decoder = EntityStateResidency_PowerEntityState_Decoder;
+  enum : int32_t {
+    kEntityIndexFieldNumber = 1,
+    kStateIndexFieldNumber = 2,
+    kEntityNameFieldNumber = 3,
+    kStateNameFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.EntityStateResidency.PowerEntityState"; }
+
+
+  using FieldMetadata_EntityIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      EntityStateResidency_PowerEntityState>;
+
+  static constexpr FieldMetadata_EntityIndex kEntityIndex{};
+  void set_entity_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EntityIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StateIndex =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      EntityStateResidency_PowerEntityState>;
+
+  static constexpr FieldMetadata_StateIndex kStateIndex{};
+  void set_state_index(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_StateIndex::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EntityName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EntityStateResidency_PowerEntityState>;
+
+  static constexpr FieldMetadata_EntityName kEntityName{};
+  void set_entity_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_EntityName::kFieldId, data, size);
+  }
+  void set_entity_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_EntityName::kFieldId, chars.data, chars.size);
+  }
+  void set_entity_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_EntityName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StateName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      EntityStateResidency_PowerEntityState>;
+
+  static constexpr FieldMetadata_StateName kStateName{};
+  void set_state_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StateName::kFieldId, data, size);
+  }
+  void set_state_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StateName::kFieldId, chars.data, chars.size);
+  }
+  void set_state_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StateName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/power/battery_counters.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_BATTERY_COUNTERS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_BATTERY_COUNTERS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+
+class BatteryCounters_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  BatteryCounters_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit BatteryCounters_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit BatteryCounters_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_charge_counter_uah() const { return at<1>().valid(); }
+  int64_t charge_counter_uah() const { return at<1>().as_int64(); }
+  bool has_capacity_percent() const { return at<2>().valid(); }
+  float capacity_percent() const { return at<2>().as_float(); }
+  bool has_current_ua() const { return at<3>().valid(); }
+  int64_t current_ua() const { return at<3>().as_int64(); }
+  bool has_current_avg_ua() const { return at<4>().valid(); }
+  int64_t current_avg_ua() const { return at<4>().as_int64(); }
+  bool has_name() const { return at<5>().valid(); }
+  ::protozero::ConstChars name() const { return at<5>().as_string(); }
+  bool has_energy_counter_uwh() const { return at<6>().valid(); }
+  int64_t energy_counter_uwh() const { return at<6>().as_int64(); }
+  bool has_voltage_uv() const { return at<7>().valid(); }
+  int64_t voltage_uv() const { return at<7>().as_int64(); }
+};
+
+class BatteryCounters : public ::protozero::Message {
+ public:
+  using Decoder = BatteryCounters_Decoder;
+  enum : int32_t {
+    kChargeCounterUahFieldNumber = 1,
+    kCapacityPercentFieldNumber = 2,
+    kCurrentUaFieldNumber = 3,
+    kCurrentAvgUaFieldNumber = 4,
+    kNameFieldNumber = 5,
+    kEnergyCounterUwhFieldNumber = 6,
+    kVoltageUvFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.BatteryCounters"; }
+
+
+  using FieldMetadata_ChargeCounterUah =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_ChargeCounterUah kChargeCounterUah{};
+  void set_charge_counter_uah(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChargeCounterUah::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CapacityPercent =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kFloat,
+      float,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_CapacityPercent kCapacityPercent{};
+  void set_capacity_percent(float value) {
+    static constexpr uint32_t field_id = FieldMetadata_CapacityPercent::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kFloat>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CurrentUa =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_CurrentUa kCurrentUa{};
+  void set_current_ua(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentUa::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_CurrentAvgUa =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_CurrentAvgUa kCurrentAvgUa{};
+  void set_current_avg_ua(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CurrentAvgUa::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_EnergyCounterUwh =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_EnergyCounterUwh kEnergyCounterUwh{};
+  void set_energy_counter_uwh(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_EnergyCounterUwh::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VoltageUv =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      BatteryCounters>;
+
+  static constexpr FieldMetadata_VoltageUv kVoltageUv{};
+  void set_voltage_uv(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VoltageUv::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/power/power_rails.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_POWER_RAILS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_POWER_POWER_RAILS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PowerRails_EnergyData;
+class PowerRails_RailDescriptor;
+
+class PowerRails_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  PowerRails_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PowerRails_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PowerRails_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_rail_descriptor() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> rail_descriptor() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_energy_data() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> energy_data() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class PowerRails : public ::protozero::Message {
+ public:
+  using Decoder = PowerRails_Decoder;
+  enum : int32_t {
+    kRailDescriptorFieldNumber = 1,
+    kEnergyDataFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PowerRails"; }
+
+  using RailDescriptor = ::perfetto::protos::pbzero::PowerRails_RailDescriptor;
+  using EnergyData = ::perfetto::protos::pbzero::PowerRails_EnergyData;
+
+  using FieldMetadata_RailDescriptor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PowerRails_RailDescriptor,
+      PowerRails>;
+
+  static constexpr FieldMetadata_RailDescriptor kRailDescriptor{};
+  template <typename T = PowerRails_RailDescriptor> T* add_rail_descriptor() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_EnergyData =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PowerRails_EnergyData,
+      PowerRails>;
+
+  static constexpr FieldMetadata_EnergyData kEnergyData{};
+  template <typename T = PowerRails_EnergyData> T* add_energy_data() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class PowerRails_EnergyData_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PowerRails_EnergyData_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PowerRails_EnergyData_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PowerRails_EnergyData_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_index() const { return at<1>().valid(); }
+  uint32_t index() const { return at<1>().as_uint32(); }
+  bool has_timestamp_ms() const { return at<2>().valid(); }
+  uint64_t timestamp_ms() const { return at<2>().as_uint64(); }
+  bool has_energy() const { return at<3>().valid(); }
+  uint64_t energy() const { return at<3>().as_uint64(); }
+};
+
+class PowerRails_EnergyData : public ::protozero::Message {
+ public:
+  using Decoder = PowerRails_EnergyData_Decoder;
+  enum : int32_t {
+    kIndexFieldNumber = 1,
+    kTimestampMsFieldNumber = 2,
+    kEnergyFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PowerRails.EnergyData"; }
+
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PowerRails_EnergyData>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimestampMs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PowerRails_EnergyData>;
+
+  static constexpr FieldMetadata_TimestampMs kTimestampMs{};
+  void set_timestamp_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Energy =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      PowerRails_EnergyData>;
+
+  static constexpr FieldMetadata_Energy kEnergy{};
+  void set_energy(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Energy::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class PowerRails_RailDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  PowerRails_RailDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit PowerRails_RailDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit PowerRails_RailDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_index() const { return at<1>().valid(); }
+  uint32_t index() const { return at<1>().as_uint32(); }
+  bool has_rail_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars rail_name() const { return at<2>().as_string(); }
+  bool has_subsys_name() const { return at<3>().valid(); }
+  ::protozero::ConstChars subsys_name() const { return at<3>().as_string(); }
+  bool has_sampling_rate() const { return at<4>().valid(); }
+  uint32_t sampling_rate() const { return at<4>().as_uint32(); }
+};
+
+class PowerRails_RailDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = PowerRails_RailDescriptor_Decoder;
+  enum : int32_t {
+    kIndexFieldNumber = 1,
+    kRailNameFieldNumber = 2,
+    kSubsysNameFieldNumber = 3,
+    kSamplingRateFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.PowerRails.RailDescriptor"; }
+
+
+  using FieldMetadata_Index =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PowerRails_RailDescriptor>;
+
+  static constexpr FieldMetadata_Index kIndex{};
+  void set_index(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Index::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RailName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PowerRails_RailDescriptor>;
+
+  static constexpr FieldMetadata_RailName kRailName{};
+  void set_rail_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_RailName::kFieldId, data, size);
+  }
+  void set_rail_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_RailName::kFieldId, chars.data, chars.size);
+  }
+  void set_rail_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_RailName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SubsysName =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      PowerRails_RailDescriptor>;
+
+  static constexpr FieldMetadata_SubsysName kSubsysName{};
+  void set_subsys_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SubsysName::kFieldId, data, size);
+  }
+  void set_subsys_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SubsysName::kFieldId, chars.data, chars.size);
+  }
+  void set_subsys_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SubsysName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SamplingRate =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      PowerRails_RailDescriptor>;
+
+  static constexpr FieldMetadata_SamplingRate kSamplingRate{};
+  void set_sampling_rate(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SamplingRate::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ps/process_stats.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PS_PROCESS_STATS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PS_PROCESS_STATS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ProcessStats_FDInfo;
+class ProcessStats_Process;
+class ProcessStats_Thread;
+
+class ProcessStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_processes() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> processes() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_collection_end_timestamp() const { return at<2>().valid(); }
+  uint64_t collection_end_timestamp() const { return at<2>().as_uint64(); }
+};
+
+class ProcessStats : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStats_Decoder;
+  enum : int32_t {
+    kProcessesFieldNumber = 1,
+    kCollectionEndTimestampFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessStats"; }
+
+  using Thread = ::perfetto::protos::pbzero::ProcessStats_Thread;
+  using FDInfo = ::perfetto::protos::pbzero::ProcessStats_FDInfo;
+  using Process = ::perfetto::protos::pbzero::ProcessStats_Process;
+
+  using FieldMetadata_Processes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessStats_Process,
+      ProcessStats>;
+
+  static constexpr FieldMetadata_Processes kProcesses{};
+  template <typename T = ProcessStats_Process> T* add_processes() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_CollectionEndTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats>;
+
+  static constexpr FieldMetadata_CollectionEndTimestamp kCollectionEndTimestamp{};
+  void set_collection_end_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectionEndTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ProcessStats_Process_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/20, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessStats_Process_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessStats_Process_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessStats_Process_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_vm_size_kb() const { return at<2>().valid(); }
+  uint64_t vm_size_kb() const { return at<2>().as_uint64(); }
+  bool has_vm_rss_kb() const { return at<3>().valid(); }
+  uint64_t vm_rss_kb() const { return at<3>().as_uint64(); }
+  bool has_rss_anon_kb() const { return at<4>().valid(); }
+  uint64_t rss_anon_kb() const { return at<4>().as_uint64(); }
+  bool has_rss_file_kb() const { return at<5>().valid(); }
+  uint64_t rss_file_kb() const { return at<5>().as_uint64(); }
+  bool has_rss_shmem_kb() const { return at<6>().valid(); }
+  uint64_t rss_shmem_kb() const { return at<6>().as_uint64(); }
+  bool has_vm_swap_kb() const { return at<7>().valid(); }
+  uint64_t vm_swap_kb() const { return at<7>().as_uint64(); }
+  bool has_vm_locked_kb() const { return at<8>().valid(); }
+  uint64_t vm_locked_kb() const { return at<8>().as_uint64(); }
+  bool has_vm_hwm_kb() const { return at<9>().valid(); }
+  uint64_t vm_hwm_kb() const { return at<9>().as_uint64(); }
+  bool has_oom_score_adj() const { return at<10>().valid(); }
+  int64_t oom_score_adj() const { return at<10>().as_int64(); }
+  bool has_threads() const { return at<11>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> threads() const { return GetRepeated<::protozero::ConstBytes>(11); }
+  bool has_is_peak_rss_resettable() const { return at<12>().valid(); }
+  bool is_peak_rss_resettable() const { return at<12>().as_bool(); }
+  bool has_chrome_private_footprint_kb() const { return at<13>().valid(); }
+  uint32_t chrome_private_footprint_kb() const { return at<13>().as_uint32(); }
+  bool has_chrome_peak_resident_set_kb() const { return at<14>().valid(); }
+  uint32_t chrome_peak_resident_set_kb() const { return at<14>().as_uint32(); }
+  bool has_fds() const { return at<15>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> fds() const { return GetRepeated<::protozero::ConstBytes>(15); }
+  bool has_smr_rss_kb() const { return at<16>().valid(); }
+  uint64_t smr_rss_kb() const { return at<16>().as_uint64(); }
+  bool has_smr_pss_kb() const { return at<17>().valid(); }
+  uint64_t smr_pss_kb() const { return at<17>().as_uint64(); }
+  bool has_smr_pss_anon_kb() const { return at<18>().valid(); }
+  uint64_t smr_pss_anon_kb() const { return at<18>().as_uint64(); }
+  bool has_smr_pss_file_kb() const { return at<19>().valid(); }
+  uint64_t smr_pss_file_kb() const { return at<19>().as_uint64(); }
+  bool has_smr_pss_shmem_kb() const { return at<20>().valid(); }
+  uint64_t smr_pss_shmem_kb() const { return at<20>().as_uint64(); }
+};
+
+class ProcessStats_Process : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStats_Process_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kVmSizeKbFieldNumber = 2,
+    kVmRssKbFieldNumber = 3,
+    kRssAnonKbFieldNumber = 4,
+    kRssFileKbFieldNumber = 5,
+    kRssShmemKbFieldNumber = 6,
+    kVmSwapKbFieldNumber = 7,
+    kVmLockedKbFieldNumber = 8,
+    kVmHwmKbFieldNumber = 9,
+    kOomScoreAdjFieldNumber = 10,
+    kThreadsFieldNumber = 11,
+    kIsPeakRssResettableFieldNumber = 12,
+    kChromePrivateFootprintKbFieldNumber = 13,
+    kChromePeakResidentSetKbFieldNumber = 14,
+    kFdsFieldNumber = 15,
+    kSmrRssKbFieldNumber = 16,
+    kSmrPssKbFieldNumber = 17,
+    kSmrPssAnonKbFieldNumber = 18,
+    kSmrPssFileKbFieldNumber = 19,
+    kSmrPssShmemKbFieldNumber = 20,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessStats.Process"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VmSizeKb =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_VmSizeKb kVmSizeKb{};
+  void set_vm_size_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmSizeKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VmRssKb =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_VmRssKb kVmRssKb{};
+  void set_vm_rss_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmRssKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RssAnonKb =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_RssAnonKb kRssAnonKb{};
+  void set_rss_anon_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RssAnonKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RssFileKb =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_RssFileKb kRssFileKb{};
+  void set_rss_file_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RssFileKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RssShmemKb =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_RssShmemKb kRssShmemKb{};
+  void set_rss_shmem_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RssShmemKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VmSwapKb =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_VmSwapKb kVmSwapKb{};
+  void set_vm_swap_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmSwapKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VmLockedKb =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_VmLockedKb kVmLockedKb{};
+  void set_vm_locked_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmLockedKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_VmHwmKb =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_VmHwmKb kVmHwmKb{};
+  void set_vm_hwm_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_VmHwmKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OomScoreAdj =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_OomScoreAdj kOomScoreAdj{};
+  void set_oom_score_adj(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OomScoreAdj::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Threads =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessStats_Thread,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_Threads kThreads{};
+  template <typename T = ProcessStats_Thread> T* add_threads() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_IsPeakRssResettable =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_IsPeakRssResettable kIsPeakRssResettable{};
+  void set_is_peak_rss_resettable(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsPeakRssResettable::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChromePrivateFootprintKb =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_ChromePrivateFootprintKb kChromePrivateFootprintKb{};
+  void set_chrome_private_footprint_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChromePrivateFootprintKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ChromePeakResidentSetKb =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_ChromePeakResidentSetKb kChromePeakResidentSetKb{};
+  void set_chrome_peak_resident_set_kb(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChromePeakResidentSetKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Fds =
+    ::protozero::proto_utils::FieldMetadata<
+      15,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessStats_FDInfo,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_Fds kFds{};
+  template <typename T = ProcessStats_FDInfo> T* add_fds() {
+    return BeginNestedMessage<T>(15);
+  }
+
+
+  using FieldMetadata_SmrRssKb =
+    ::protozero::proto_utils::FieldMetadata<
+      16,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_SmrRssKb kSmrRssKb{};
+  void set_smr_rss_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SmrRssKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SmrPssKb =
+    ::protozero::proto_utils::FieldMetadata<
+      17,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_SmrPssKb kSmrPssKb{};
+  void set_smr_pss_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SmrPssKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SmrPssAnonKb =
+    ::protozero::proto_utils::FieldMetadata<
+      18,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_SmrPssAnonKb kSmrPssAnonKb{};
+  void set_smr_pss_anon_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SmrPssAnonKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SmrPssFileKb =
+    ::protozero::proto_utils::FieldMetadata<
+      19,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_SmrPssFileKb kSmrPssFileKb{};
+  void set_smr_pss_file_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SmrPssFileKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SmrPssShmemKb =
+    ::protozero::proto_utils::FieldMetadata<
+      20,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_Process>;
+
+  static constexpr FieldMetadata_SmrPssShmemKb kSmrPssShmemKb{};
+  void set_smr_pss_shmem_kb(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SmrPssShmemKb::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ProcessStats_FDInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProcessStats_FDInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessStats_FDInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessStats_FDInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_fd() const { return at<1>().valid(); }
+  uint64_t fd() const { return at<1>().as_uint64(); }
+  bool has_path() const { return at<2>().valid(); }
+  ::protozero::ConstChars path() const { return at<2>().as_string(); }
+};
+
+class ProcessStats_FDInfo : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStats_FDInfo_Decoder;
+  enum : int32_t {
+    kFdFieldNumber = 1,
+    kPathFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessStats.FDInfo"; }
+
+
+  using FieldMetadata_Fd =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessStats_FDInfo>;
+
+  static constexpr FieldMetadata_Fd kFd{};
+  void set_fd(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Fd::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Path =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessStats_FDInfo>;
+
+  static constexpr FieldMetadata_Path kPath{};
+  void set_path(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Path::kFieldId, data, size);
+  }
+  void set_path(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Path::kFieldId, chars.data, chars.size);
+  }
+  void set_path(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Path::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ProcessStats_Thread_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ProcessStats_Thread_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessStats_Thread_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessStats_Thread_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tid() const { return at<1>().valid(); }
+  int32_t tid() const { return at<1>().as_int32(); }
+};
+
+class ProcessStats_Thread : public ::protozero::Message {
+ public:
+  using Decoder = ProcessStats_Thread_Decoder;
+  enum : int32_t {
+    kTidFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessStats.Thread"; }
+
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessStats_Thread>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ps/process_tree.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PS_PROCESS_TREE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PS_PROCESS_TREE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ProcessTree_Process;
+class ProcessTree_Thread;
+
+class ProcessTree_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessTree_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessTree_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessTree_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_processes() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> processes() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_threads() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> threads() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_collection_end_timestamp() const { return at<3>().valid(); }
+  uint64_t collection_end_timestamp() const { return at<3>().as_uint64(); }
+};
+
+class ProcessTree : public ::protozero::Message {
+ public:
+  using Decoder = ProcessTree_Decoder;
+  enum : int32_t {
+    kProcessesFieldNumber = 1,
+    kThreadsFieldNumber = 2,
+    kCollectionEndTimestampFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessTree"; }
+
+  using Thread = ::perfetto::protos::pbzero::ProcessTree_Thread;
+  using Process = ::perfetto::protos::pbzero::ProcessTree_Process;
+
+  using FieldMetadata_Processes =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessTree_Process,
+      ProcessTree>;
+
+  static constexpr FieldMetadata_Processes kProcesses{};
+  template <typename T = ProcessTree_Process> T* add_processes() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Threads =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessTree_Thread,
+      ProcessTree>;
+
+  static constexpr FieldMetadata_Threads kThreads{};
+  template <typename T = ProcessTree_Thread> T* add_threads() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_CollectionEndTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ProcessTree>;
+
+  static constexpr FieldMetadata_CollectionEndTimestamp kCollectionEndTimestamp{};
+  void set_collection_end_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectionEndTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ProcessTree_Process_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessTree_Process_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessTree_Process_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessTree_Process_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_ppid() const { return at<2>().valid(); }
+  int32_t ppid() const { return at<2>().as_int32(); }
+  bool has_cmdline() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> cmdline() const { return GetRepeated<::protozero::ConstChars>(3); }
+  bool has_threads_deprecated() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> threads_deprecated() const { return GetRepeated<::protozero::ConstBytes>(4); }
+  bool has_uid() const { return at<5>().valid(); }
+  int32_t uid() const { return at<5>().as_int32(); }
+  bool has_nspid() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> nspid() const { return GetRepeated<int32_t>(6); }
+};
+
+class ProcessTree_Process : public ::protozero::Message {
+ public:
+  using Decoder = ProcessTree_Process_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kPpidFieldNumber = 2,
+    kCmdlineFieldNumber = 3,
+    kThreadsDeprecatedFieldNumber = 4,
+    kUidFieldNumber = 5,
+    kNspidFieldNumber = 6,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessTree.Process"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Ppid =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_Ppid kPpid{};
+  void set_ppid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Ppid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void add_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void add_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void add_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ThreadsDeprecated =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ProcessTree_Thread,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_ThreadsDeprecated kThreadsDeprecated{};
+  template <typename T = ProcessTree_Thread> T* add_threads_deprecated() {
+    return BeginNestedMessage<T>(4);
+  }
+
+
+  using FieldMetadata_Uid =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_Uid kUid{};
+  void set_uid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Uid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nspid =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Process>;
+
+  static constexpr FieldMetadata_Nspid kNspid{};
+  void add_nspid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nspid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ProcessTree_Thread_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ProcessTree_Thread_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ProcessTree_Thread_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ProcessTree_Thread_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_tid() const { return at<1>().valid(); }
+  int32_t tid() const { return at<1>().as_int32(); }
+  bool has_tgid() const { return at<3>().valid(); }
+  int32_t tgid() const { return at<3>().as_int32(); }
+  bool has_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars name() const { return at<2>().as_string(); }
+  bool has_nstid() const { return at<4>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> nstid() const { return GetRepeated<int32_t>(4); }
+};
+
+class ProcessTree_Thread : public ::protozero::Message {
+ public:
+  using Decoder = ProcessTree_Thread_Decoder;
+  enum : int32_t {
+    kTidFieldNumber = 1,
+    kTgidFieldNumber = 3,
+    kNameFieldNumber = 2,
+    kNstidFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ProcessTree.Thread"; }
+
+
+  using FieldMetadata_Tid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Thread>;
+
+  static constexpr FieldMetadata_Tid kTid{};
+  void set_tid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Tgid =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Thread>;
+
+  static constexpr FieldMetadata_Tgid kTgid{};
+  void set_tgid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Tgid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ProcessTree_Thread>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nstid =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      ProcessTree_Thread>;
+
+  static constexpr FieldMetadata_Nstid kNstid{};
+  void add_nstid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Nstid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/statsd/statsd_atom.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_STATSD_STATSD_ATOM_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_STATSD_STATSD_ATOM_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class Atom;
+
+class StatsdAtom_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  StatsdAtom_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit StatsdAtom_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit StatsdAtom_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_atom() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> atom() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_timestamp_nanos() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<int64_t> timestamp_nanos() const { return GetRepeated<int64_t>(2); }
+};
+
+class StatsdAtom : public ::protozero::Message {
+ public:
+  using Decoder = StatsdAtom_Decoder;
+  enum : int32_t {
+    kAtomFieldNumber = 1,
+    kTimestampNanosFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.StatsdAtom"; }
+
+
+  using FieldMetadata_Atom =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      Atom,
+      StatsdAtom>;
+
+  static constexpr FieldMetadata_Atom kAtom{};
+  template <typename T = Atom> T* add_atom() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_TimestampNanos =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      StatsdAtom>;
+
+  static constexpr FieldMetadata_TimestampNanos kTimestampNanos{};
+  void add_timestamp_nanos(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampNanos::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class Atom_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/0, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  Atom_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Atom_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Atom_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+};
+
+class Atom : public ::protozero::Message {
+ public:
+  using Decoder = Atom_Decoder;
+  static constexpr const char* GetName() { return ".perfetto.protos.Atom"; }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/sys_stats/sys_stats.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYS_STATS_SYS_STATS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYS_STATS_SYS_STATS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class SysStats_BuddyInfo;
+class SysStats_CpuTimes;
+class SysStats_DevfreqValue;
+class SysStats_DiskStat;
+class SysStats_InterruptCount;
+class SysStats_MeminfoValue;
+class SysStats_PsiSample;
+class SysStats_VmstatValue;
+enum MeminfoCounters : int32_t;
+namespace perfetto_pbzero_enum_SysStats_PsiSample {
+enum PsiResource : int32_t;
+}  // namespace perfetto_pbzero_enum_SysStats_PsiSample
+using SysStats_PsiSample_PsiResource = perfetto_pbzero_enum_SysStats_PsiSample::PsiResource;
+enum VmstatCounters : int32_t;
+
+namespace perfetto_pbzero_enum_SysStats_PsiSample {
+enum PsiResource : int32_t {
+  PSI_RESOURCE_UNSPECIFIED = 0,
+  PSI_RESOURCE_CPU_SOME = 1,
+  PSI_RESOURCE_CPU_FULL = 2,
+  PSI_RESOURCE_IO_SOME = 3,
+  PSI_RESOURCE_IO_FULL = 4,
+  PSI_RESOURCE_MEMORY_SOME = 5,
+  PSI_RESOURCE_MEMORY_FULL = 6,
+};
+} // namespace perfetto_pbzero_enum_SysStats_PsiSample
+using SysStats_PsiSample_PsiResource = perfetto_pbzero_enum_SysStats_PsiSample::PsiResource;
+
+
+constexpr SysStats_PsiSample_PsiResource SysStats_PsiSample_PsiResource_MIN = SysStats_PsiSample_PsiResource::PSI_RESOURCE_UNSPECIFIED;
+constexpr SysStats_PsiSample_PsiResource SysStats_PsiSample_PsiResource_MAX = SysStats_PsiSample_PsiResource::PSI_RESOURCE_MEMORY_FULL;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* SysStats_PsiSample_PsiResource_Name(::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_UNSPECIFIED:
+    return "PSI_RESOURCE_UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_CPU_SOME:
+    return "PSI_RESOURCE_CPU_SOME";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_CPU_FULL:
+    return "PSI_RESOURCE_CPU_FULL";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_IO_SOME:
+    return "PSI_RESOURCE_IO_SOME";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_IO_FULL:
+    return "PSI_RESOURCE_IO_FULL";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_MEMORY_SOME:
+    return "PSI_RESOURCE_MEMORY_SOME";
+
+  case ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource::PSI_RESOURCE_MEMORY_FULL:
+    return "PSI_RESOURCE_MEMORY_FULL";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class SysStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/14, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SysStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_meminfo() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> meminfo() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_vmstat() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> vmstat() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_cpu_stat() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> cpu_stat() const { return GetRepeated<::protozero::ConstBytes>(3); }
+  bool has_num_forks() const { return at<4>().valid(); }
+  uint64_t num_forks() const { return at<4>().as_uint64(); }
+  bool has_num_irq_total() const { return at<5>().valid(); }
+  uint64_t num_irq_total() const { return at<5>().as_uint64(); }
+  bool has_num_irq() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> num_irq() const { return GetRepeated<::protozero::ConstBytes>(6); }
+  bool has_num_softirq_total() const { return at<7>().valid(); }
+  uint64_t num_softirq_total() const { return at<7>().as_uint64(); }
+  bool has_num_softirq() const { return at<8>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> num_softirq() const { return GetRepeated<::protozero::ConstBytes>(8); }
+  bool has_collection_end_timestamp() const { return at<9>().valid(); }
+  uint64_t collection_end_timestamp() const { return at<9>().as_uint64(); }
+  bool has_devfreq() const { return at<10>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> devfreq() const { return GetRepeated<::protozero::ConstBytes>(10); }
+  bool has_cpufreq_khz() const { return at<11>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> cpufreq_khz() const { return GetRepeated<uint32_t>(11); }
+  bool has_buddy_info() const { return at<12>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buddy_info() const { return GetRepeated<::protozero::ConstBytes>(12); }
+  bool has_disk_stat() const { return at<13>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> disk_stat() const { return GetRepeated<::protozero::ConstBytes>(13); }
+  bool has_psi() const { return at<14>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> psi() const { return GetRepeated<::protozero::ConstBytes>(14); }
+};
+
+class SysStats : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_Decoder;
+  enum : int32_t {
+    kMeminfoFieldNumber = 1,
+    kVmstatFieldNumber = 2,
+    kCpuStatFieldNumber = 3,
+    kNumForksFieldNumber = 4,
+    kNumIrqTotalFieldNumber = 5,
+    kNumIrqFieldNumber = 6,
+    kNumSoftirqTotalFieldNumber = 7,
+    kNumSoftirqFieldNumber = 8,
+    kCollectionEndTimestampFieldNumber = 9,
+    kDevfreqFieldNumber = 10,
+    kCpufreqKhzFieldNumber = 11,
+    kBuddyInfoFieldNumber = 12,
+    kDiskStatFieldNumber = 13,
+    kPsiFieldNumber = 14,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats"; }
+
+  using MeminfoValue = ::perfetto::protos::pbzero::SysStats_MeminfoValue;
+  using VmstatValue = ::perfetto::protos::pbzero::SysStats_VmstatValue;
+  using CpuTimes = ::perfetto::protos::pbzero::SysStats_CpuTimes;
+  using InterruptCount = ::perfetto::protos::pbzero::SysStats_InterruptCount;
+  using DevfreqValue = ::perfetto::protos::pbzero::SysStats_DevfreqValue;
+  using BuddyInfo = ::perfetto::protos::pbzero::SysStats_BuddyInfo;
+  using DiskStat = ::perfetto::protos::pbzero::SysStats_DiskStat;
+  using PsiSample = ::perfetto::protos::pbzero::SysStats_PsiSample;
+
+  using FieldMetadata_Meminfo =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_MeminfoValue,
+      SysStats>;
+
+  static constexpr FieldMetadata_Meminfo kMeminfo{};
+  template <typename T = SysStats_MeminfoValue> T* add_meminfo() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_Vmstat =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_VmstatValue,
+      SysStats>;
+
+  static constexpr FieldMetadata_Vmstat kVmstat{};
+  template <typename T = SysStats_VmstatValue> T* add_vmstat() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_CpuStat =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_CpuTimes,
+      SysStats>;
+
+  static constexpr FieldMetadata_CpuStat kCpuStat{};
+  template <typename T = SysStats_CpuTimes> T* add_cpu_stat() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_NumForks =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats>;
+
+  static constexpr FieldMetadata_NumForks kNumForks{};
+  void set_num_forks(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumForks::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumIrqTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats>;
+
+  static constexpr FieldMetadata_NumIrqTotal kNumIrqTotal{};
+  void set_num_irq_total(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumIrqTotal::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumIrq =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_InterruptCount,
+      SysStats>;
+
+  static constexpr FieldMetadata_NumIrq kNumIrq{};
+  template <typename T = SysStats_InterruptCount> T* add_num_irq() {
+    return BeginNestedMessage<T>(6);
+  }
+
+
+  using FieldMetadata_NumSoftirqTotal =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats>;
+
+  static constexpr FieldMetadata_NumSoftirqTotal kNumSoftirqTotal{};
+  void set_num_softirq_total(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_NumSoftirqTotal::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NumSoftirq =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_InterruptCount,
+      SysStats>;
+
+  static constexpr FieldMetadata_NumSoftirq kNumSoftirq{};
+  template <typename T = SysStats_InterruptCount> T* add_num_softirq() {
+    return BeginNestedMessage<T>(8);
+  }
+
+
+  using FieldMetadata_CollectionEndTimestamp =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats>;
+
+  static constexpr FieldMetadata_CollectionEndTimestamp kCollectionEndTimestamp{};
+  void set_collection_end_timestamp(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CollectionEndTimestamp::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Devfreq =
+    ::protozero::proto_utils::FieldMetadata<
+      10,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_DevfreqValue,
+      SysStats>;
+
+  static constexpr FieldMetadata_Devfreq kDevfreq{};
+  template <typename T = SysStats_DevfreqValue> T* add_devfreq() {
+    return BeginNestedMessage<T>(10);
+  }
+
+
+  using FieldMetadata_CpufreqKhz =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStats>;
+
+  static constexpr FieldMetadata_CpufreqKhz kCpufreqKhz{};
+  void add_cpufreq_khz(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpufreqKhz::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_BuddyInfo =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_BuddyInfo,
+      SysStats>;
+
+  static constexpr FieldMetadata_BuddyInfo kBuddyInfo{};
+  template <typename T = SysStats_BuddyInfo> T* add_buddy_info() {
+    return BeginNestedMessage<T>(12);
+  }
+
+
+  using FieldMetadata_DiskStat =
+    ::protozero::proto_utils::FieldMetadata<
+      13,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_DiskStat,
+      SysStats>;
+
+  static constexpr FieldMetadata_DiskStat kDiskStat{};
+  template <typename T = SysStats_DiskStat> T* add_disk_stat() {
+    return BeginNestedMessage<T>(13);
+  }
+
+
+  using FieldMetadata_Psi =
+    ::protozero::proto_utils::FieldMetadata<
+      14,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SysStats_PsiSample,
+      SysStats>;
+
+  static constexpr FieldMetadata_Psi kPsi{};
+  template <typename T = SysStats_PsiSample> T* add_psi() {
+    return BeginNestedMessage<T>(14);
+  }
+
+};
+
+class SysStats_PsiSample_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_PsiSample_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_PsiSample_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_PsiSample_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_resource() const { return at<1>().valid(); }
+  int32_t resource() const { return at<1>().as_int32(); }
+  bool has_total_ns() const { return at<2>().valid(); }
+  uint64_t total_ns() const { return at<2>().as_uint64(); }
+};
+
+class SysStats_PsiSample : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_PsiSample_Decoder;
+  enum : int32_t {
+    kResourceFieldNumber = 1,
+    kTotalNsFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.PsiSample"; }
+
+
+  using PsiResource = ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource;
+  static inline const char* PsiResource_Name(PsiResource value) {
+    return ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource_Name(value);
+  }
+  static inline const PsiResource PSI_RESOURCE_UNSPECIFIED = PsiResource::PSI_RESOURCE_UNSPECIFIED;
+  static inline const PsiResource PSI_RESOURCE_CPU_SOME = PsiResource::PSI_RESOURCE_CPU_SOME;
+  static inline const PsiResource PSI_RESOURCE_CPU_FULL = PsiResource::PSI_RESOURCE_CPU_FULL;
+  static inline const PsiResource PSI_RESOURCE_IO_SOME = PsiResource::PSI_RESOURCE_IO_SOME;
+  static inline const PsiResource PSI_RESOURCE_IO_FULL = PsiResource::PSI_RESOURCE_IO_FULL;
+  static inline const PsiResource PSI_RESOURCE_MEMORY_SOME = PsiResource::PSI_RESOURCE_MEMORY_SOME;
+  static inline const PsiResource PSI_RESOURCE_MEMORY_FULL = PsiResource::PSI_RESOURCE_MEMORY_FULL;
+
+  using FieldMetadata_Resource =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource,
+      SysStats_PsiSample>;
+
+  static constexpr FieldMetadata_Resource kResource{};
+  void set_resource(::perfetto::protos::pbzero::SysStats_PsiSample_PsiResource value) {
+    static constexpr uint32_t field_id = FieldMetadata_Resource::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TotalNs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_PsiSample>;
+
+  static constexpr FieldMetadata_TotalNs kTotalNs{};
+  void set_total_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TotalNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SysStats_DiskStat_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_DiskStat_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_DiskStat_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_DiskStat_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_device_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars device_name() const { return at<1>().as_string(); }
+  bool has_read_sectors() const { return at<2>().valid(); }
+  uint64_t read_sectors() const { return at<2>().as_uint64(); }
+  bool has_read_time_ms() const { return at<3>().valid(); }
+  uint64_t read_time_ms() const { return at<3>().as_uint64(); }
+  bool has_write_sectors() const { return at<4>().valid(); }
+  uint64_t write_sectors() const { return at<4>().as_uint64(); }
+  bool has_write_time_ms() const { return at<5>().valid(); }
+  uint64_t write_time_ms() const { return at<5>().as_uint64(); }
+  bool has_discard_sectors() const { return at<6>().valid(); }
+  uint64_t discard_sectors() const { return at<6>().as_uint64(); }
+  bool has_discard_time_ms() const { return at<7>().valid(); }
+  uint64_t discard_time_ms() const { return at<7>().as_uint64(); }
+  bool has_flush_count() const { return at<8>().valid(); }
+  uint64_t flush_count() const { return at<8>().as_uint64(); }
+  bool has_flush_time_ms() const { return at<9>().valid(); }
+  uint64_t flush_time_ms() const { return at<9>().as_uint64(); }
+};
+
+class SysStats_DiskStat : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_DiskStat_Decoder;
+  enum : int32_t {
+    kDeviceNameFieldNumber = 1,
+    kReadSectorsFieldNumber = 2,
+    kReadTimeMsFieldNumber = 3,
+    kWriteSectorsFieldNumber = 4,
+    kWriteTimeMsFieldNumber = 5,
+    kDiscardSectorsFieldNumber = 6,
+    kDiscardTimeMsFieldNumber = 7,
+    kFlushCountFieldNumber = 8,
+    kFlushTimeMsFieldNumber = 9,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.DiskStat"; }
+
+
+  using FieldMetadata_DeviceName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_DeviceName kDeviceName{};
+  void set_device_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_DeviceName::kFieldId, data, size);
+  }
+  void set_device_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_DeviceName::kFieldId, chars.data, chars.size);
+  }
+  void set_device_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_DeviceName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReadSectors =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_ReadSectors kReadSectors{};
+  void set_read_sectors(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadSectors::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ReadTimeMs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_ReadTimeMs kReadTimeMs{};
+  void set_read_time_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ReadTimeMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WriteSectors =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_WriteSectors kWriteSectors{};
+  void set_write_sectors(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriteSectors::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_WriteTimeMs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_WriteTimeMs kWriteTimeMs{};
+  void set_write_time_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_WriteTimeMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DiscardSectors =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_DiscardSectors kDiscardSectors{};
+  void set_discard_sectors(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DiscardSectors::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DiscardTimeMs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_DiscardTimeMs kDiscardTimeMs{};
+  void set_discard_time_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_DiscardTimeMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FlushCount =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_FlushCount kFlushCount{};
+  void set_flush_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushCount::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_FlushTimeMs =
+    ::protozero::proto_utils::FieldMetadata<
+      9,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DiskStat>;
+
+  static constexpr FieldMetadata_FlushTimeMs kFlushTimeMs{};
+  void set_flush_time_ms(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_FlushTimeMs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SysStats_BuddyInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SysStats_BuddyInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_BuddyInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_BuddyInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_node() const { return at<1>().valid(); }
+  ::protozero::ConstChars node() const { return at<1>().as_string(); }
+  bool has_zone() const { return at<2>().valid(); }
+  ::protozero::ConstChars zone() const { return at<2>().as_string(); }
+  bool has_order_pages() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> order_pages() const { return GetRepeated<uint32_t>(3); }
+};
+
+class SysStats_BuddyInfo : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_BuddyInfo_Decoder;
+  enum : int32_t {
+    kNodeFieldNumber = 1,
+    kZoneFieldNumber = 2,
+    kOrderPagesFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.BuddyInfo"; }
+
+
+  using FieldMetadata_Node =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SysStats_BuddyInfo>;
+
+  static constexpr FieldMetadata_Node kNode{};
+  void set_node(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Node::kFieldId, data, size);
+  }
+  void set_node(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Node::kFieldId, chars.data, chars.size);
+  }
+  void set_node(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Node::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Zone =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SysStats_BuddyInfo>;
+
+  static constexpr FieldMetadata_Zone kZone{};
+  void set_zone(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Zone::kFieldId, data, size);
+  }
+  void set_zone(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Zone::kFieldId, chars.data, chars.size);
+  }
+  void set_zone(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Zone::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OrderPages =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStats_BuddyInfo>;
+
+  static constexpr FieldMetadata_OrderPages kOrderPages{};
+  void add_order_pages(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_OrderPages::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SysStats_DevfreqValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_DevfreqValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_DevfreqValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_DevfreqValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  ::protozero::ConstChars key() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  uint64_t value() const { return at<2>().as_uint64(); }
+};
+
+class SysStats_DevfreqValue : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_DevfreqValue_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.DevfreqValue"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SysStats_DevfreqValue>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Key::kFieldId, data, size);
+  }
+  void set_key(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Key::kFieldId, chars.data, chars.size);
+  }
+  void set_key(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_DevfreqValue>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SysStats_InterruptCount_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_InterruptCount_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_InterruptCount_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_InterruptCount_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_irq() const { return at<1>().valid(); }
+  int32_t irq() const { return at<1>().as_int32(); }
+  bool has_count() const { return at<2>().valid(); }
+  uint64_t count() const { return at<2>().as_uint64(); }
+};
+
+class SysStats_InterruptCount : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_InterruptCount_Decoder;
+  enum : int32_t {
+    kIrqFieldNumber = 1,
+    kCountFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.InterruptCount"; }
+
+
+  using FieldMetadata_Irq =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      SysStats_InterruptCount>;
+
+  static constexpr FieldMetadata_Irq kIrq{};
+  void set_irq(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Irq::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Count =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_InterruptCount>;
+
+  static constexpr FieldMetadata_Count kCount{};
+  void set_count(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Count::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SysStats_CpuTimes_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_CpuTimes_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_CpuTimes_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_CpuTimes_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpu_id() const { return at<1>().valid(); }
+  uint32_t cpu_id() const { return at<1>().as_uint32(); }
+  bool has_user_ns() const { return at<2>().valid(); }
+  uint64_t user_ns() const { return at<2>().as_uint64(); }
+  bool has_user_nice_ns() const { return at<3>().valid(); }
+  uint64_t user_nice_ns() const { return at<3>().as_uint64(); }
+  bool has_system_mode_ns() const { return at<4>().valid(); }
+  uint64_t system_mode_ns() const { return at<4>().as_uint64(); }
+  bool has_idle_ns() const { return at<5>().valid(); }
+  uint64_t idle_ns() const { return at<5>().as_uint64(); }
+  bool has_io_wait_ns() const { return at<6>().valid(); }
+  uint64_t io_wait_ns() const { return at<6>().as_uint64(); }
+  bool has_irq_ns() const { return at<7>().valid(); }
+  uint64_t irq_ns() const { return at<7>().as_uint64(); }
+  bool has_softirq_ns() const { return at<8>().valid(); }
+  uint64_t softirq_ns() const { return at<8>().as_uint64(); }
+};
+
+class SysStats_CpuTimes : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_CpuTimes_Decoder;
+  enum : int32_t {
+    kCpuIdFieldNumber = 1,
+    kUserNsFieldNumber = 2,
+    kUserNiceNsFieldNumber = 3,
+    kSystemModeNsFieldNumber = 4,
+    kIdleNsFieldNumber = 5,
+    kIoWaitNsFieldNumber = 6,
+    kIrqNsFieldNumber = 7,
+    kSoftirqNsFieldNumber = 8,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.CpuTimes"; }
+
+
+  using FieldMetadata_CpuId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_CpuId kCpuId{};
+  void set_cpu_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_CpuId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UserNs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_UserNs kUserNs{};
+  void set_user_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UserNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_UserNiceNs =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_UserNiceNs kUserNiceNs{};
+  void set_user_nice_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UserNiceNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SystemModeNs =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_SystemModeNs kSystemModeNs{};
+  void set_system_mode_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SystemModeNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IdleNs =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_IdleNs kIdleNs{};
+  void set_idle_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IdleNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IoWaitNs =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_IoWaitNs kIoWaitNs{};
+  void set_io_wait_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IoWaitNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IrqNs =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_IrqNs kIrqNs{};
+  void set_irq_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IrqNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SoftirqNs =
+    ::protozero::proto_utils::FieldMetadata<
+      8,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_CpuTimes>;
+
+  static constexpr FieldMetadata_SoftirqNs kSoftirqNs{};
+  void set_softirq_ns(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SoftirqNs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SysStats_VmstatValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_VmstatValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_VmstatValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_VmstatValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  int32_t key() const { return at<1>().as_int32(); }
+  bool has_value() const { return at<2>().valid(); }
+  uint64_t value() const { return at<2>().as_uint64(); }
+};
+
+class SysStats_VmstatValue : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_VmstatValue_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.VmstatValue"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::VmstatCounters,
+      SysStats_VmstatValue>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(::perfetto::protos::pbzero::VmstatCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_VmstatValue>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class SysStats_MeminfoValue_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SysStats_MeminfoValue_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SysStats_MeminfoValue_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SysStats_MeminfoValue_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  int32_t key() const { return at<1>().as_int32(); }
+  bool has_value() const { return at<2>().valid(); }
+  uint64_t value() const { return at<2>().as_uint64(); }
+};
+
+class SysStats_MeminfoValue : public ::protozero::Message {
+ public:
+  using Decoder = SysStats_MeminfoValue_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SysStats.MeminfoValue"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::MeminfoCounters,
+      SysStats_MeminfoValue>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(::perfetto::protos::pbzero::MeminfoCounters value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      SysStats_MeminfoValue>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/system_info/cpu_info.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_CPU_INFO_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_CPU_INFO_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class CpuInfo_Cpu;
+
+class CpuInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  CpuInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_cpus() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> cpus() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class CpuInfo : public ::protozero::Message {
+ public:
+  using Decoder = CpuInfo_Decoder;
+  enum : int32_t {
+    kCpusFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuInfo"; }
+
+  using Cpu = ::perfetto::protos::pbzero::CpuInfo_Cpu;
+
+  using FieldMetadata_Cpus =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      CpuInfo_Cpu,
+      CpuInfo>;
+
+  static constexpr FieldMetadata_Cpus kCpus{};
+  template <typename T = CpuInfo_Cpu> T* add_cpus() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class CpuInfo_Cpu_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  CpuInfo_Cpu_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit CpuInfo_Cpu_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit CpuInfo_Cpu_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_processor() const { return at<1>().valid(); }
+  ::protozero::ConstChars processor() const { return at<1>().as_string(); }
+  bool has_frequencies() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<uint32_t> frequencies() const { return GetRepeated<uint32_t>(2); }
+};
+
+class CpuInfo_Cpu : public ::protozero::Message {
+ public:
+  using Decoder = CpuInfo_Cpu_Decoder;
+  enum : int32_t {
+    kProcessorFieldNumber = 1,
+    kFrequenciesFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.CpuInfo.Cpu"; }
+
+
+  using FieldMetadata_Processor =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      CpuInfo_Cpu>;
+
+  static constexpr FieldMetadata_Processor kProcessor{};
+  void set_processor(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Processor::kFieldId, data, size);
+  }
+  void set_processor(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Processor::kFieldId, chars.data, chars.size);
+  }
+  void set_processor(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Processor::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Frequencies =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      CpuInfo_Cpu>;
+
+  static constexpr FieldMetadata_Frequencies kFrequencies{};
+  void add_frequencies(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Frequencies::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/translation/translation_table.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRANSLATION_TRANSLATION_TABLE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRANSLATION_TRANSLATION_TABLE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class ChromeHistorgramTranslationTable;
+class ChromeHistorgramTranslationTable_HashToNameEntry;
+class ChromePerformanceMarkTranslationTable;
+class ChromePerformanceMarkTranslationTable_MarkHashToNameEntry;
+class ChromePerformanceMarkTranslationTable_SiteHashToNameEntry;
+class ChromeUserEventTranslationTable;
+class ChromeUserEventTranslationTable_ActionHashToNameEntry;
+class SliceNameTranslationTable;
+class SliceNameTranslationTable_RawToDeobfuscatedNameEntry;
+
+class SliceNameTranslationTable_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  SliceNameTranslationTable_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SliceNameTranslationTable_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SliceNameTranslationTable_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_raw_to_deobfuscated_name() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> raw_to_deobfuscated_name() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class SliceNameTranslationTable : public ::protozero::Message {
+ public:
+  using Decoder = SliceNameTranslationTable_Decoder;
+  enum : int32_t {
+    kRawToDeobfuscatedNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SliceNameTranslationTable"; }
+
+  using RawToDeobfuscatedNameEntry = ::perfetto::protos::pbzero::SliceNameTranslationTable_RawToDeobfuscatedNameEntry;
+
+  using FieldMetadata_RawToDeobfuscatedName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SliceNameTranslationTable_RawToDeobfuscatedNameEntry,
+      SliceNameTranslationTable>;
+
+  static constexpr FieldMetadata_RawToDeobfuscatedName kRawToDeobfuscatedName{};
+  template <typename T = SliceNameTranslationTable_RawToDeobfuscatedNameEntry> T* add_raw_to_deobfuscated_name() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class SliceNameTranslationTable_RawToDeobfuscatedNameEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  SliceNameTranslationTable_RawToDeobfuscatedNameEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit SliceNameTranslationTable_RawToDeobfuscatedNameEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit SliceNameTranslationTable_RawToDeobfuscatedNameEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  ::protozero::ConstChars key() const { return at<1>().as_string(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class SliceNameTranslationTable_RawToDeobfuscatedNameEntry : public ::protozero::Message {
+ public:
+  using Decoder = SliceNameTranslationTable_RawToDeobfuscatedNameEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.SliceNameTranslationTable.RawToDeobfuscatedNameEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SliceNameTranslationTable_RawToDeobfuscatedNameEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Key::kFieldId, data, size);
+  }
+  void set_key(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Key::kFieldId, chars.data, chars.size);
+  }
+  void set_key(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      SliceNameTranslationTable_RawToDeobfuscatedNameEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromePerformanceMarkTranslationTable_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromePerformanceMarkTranslationTable_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromePerformanceMarkTranslationTable_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromePerformanceMarkTranslationTable_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_site_hash_to_name() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> site_hash_to_name() const { return GetRepeated<::protozero::ConstBytes>(1); }
+  bool has_mark_hash_to_name() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> mark_hash_to_name() const { return GetRepeated<::protozero::ConstBytes>(2); }
+};
+
+class ChromePerformanceMarkTranslationTable : public ::protozero::Message {
+ public:
+  using Decoder = ChromePerformanceMarkTranslationTable_Decoder;
+  enum : int32_t {
+    kSiteHashToNameFieldNumber = 1,
+    kMarkHashToNameFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromePerformanceMarkTranslationTable"; }
+
+  using SiteHashToNameEntry = ::perfetto::protos::pbzero::ChromePerformanceMarkTranslationTable_SiteHashToNameEntry;
+  using MarkHashToNameEntry = ::perfetto::protos::pbzero::ChromePerformanceMarkTranslationTable_MarkHashToNameEntry;
+
+  using FieldMetadata_SiteHashToName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromePerformanceMarkTranslationTable_SiteHashToNameEntry,
+      ChromePerformanceMarkTranslationTable>;
+
+  static constexpr FieldMetadata_SiteHashToName kSiteHashToName{};
+  template <typename T = ChromePerformanceMarkTranslationTable_SiteHashToNameEntry> T* add_site_hash_to_name() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_MarkHashToName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromePerformanceMarkTranslationTable_MarkHashToNameEntry,
+      ChromePerformanceMarkTranslationTable>;
+
+  static constexpr FieldMetadata_MarkHashToName kMarkHashToName{};
+  template <typename T = ChromePerformanceMarkTranslationTable_MarkHashToNameEntry> T* add_mark_hash_to_name() {
+    return BeginNestedMessage<T>(2);
+  }
+
+};
+
+class ChromePerformanceMarkTranslationTable_MarkHashToNameEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromePerformanceMarkTranslationTable_MarkHashToNameEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromePerformanceMarkTranslationTable_MarkHashToNameEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromePerformanceMarkTranslationTable_MarkHashToNameEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  uint32_t key() const { return at<1>().as_uint32(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class ChromePerformanceMarkTranslationTable_MarkHashToNameEntry : public ::protozero::Message {
+ public:
+  using Decoder = ChromePerformanceMarkTranslationTable_MarkHashToNameEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromePerformanceMarkTranslationTable.MarkHashToNameEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromePerformanceMarkTranslationTable_MarkHashToNameEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromePerformanceMarkTranslationTable_MarkHashToNameEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromePerformanceMarkTranslationTable_SiteHashToNameEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromePerformanceMarkTranslationTable_SiteHashToNameEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromePerformanceMarkTranslationTable_SiteHashToNameEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromePerformanceMarkTranslationTable_SiteHashToNameEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  uint32_t key() const { return at<1>().as_uint32(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class ChromePerformanceMarkTranslationTable_SiteHashToNameEntry : public ::protozero::Message {
+ public:
+  using Decoder = ChromePerformanceMarkTranslationTable_SiteHashToNameEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromePerformanceMarkTranslationTable.SiteHashToNameEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      ChromePerformanceMarkTranslationTable_SiteHashToNameEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromePerformanceMarkTranslationTable_SiteHashToNameEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeUserEventTranslationTable_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeUserEventTranslationTable_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeUserEventTranslationTable_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeUserEventTranslationTable_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_action_hash_to_name() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> action_hash_to_name() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class ChromeUserEventTranslationTable : public ::protozero::Message {
+ public:
+  using Decoder = ChromeUserEventTranslationTable_Decoder;
+  enum : int32_t {
+    kActionHashToNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeUserEventTranslationTable"; }
+
+  using ActionHashToNameEntry = ::perfetto::protos::pbzero::ChromeUserEventTranslationTable_ActionHashToNameEntry;
+
+  using FieldMetadata_ActionHashToName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeUserEventTranslationTable_ActionHashToNameEntry,
+      ChromeUserEventTranslationTable>;
+
+  static constexpr FieldMetadata_ActionHashToName kActionHashToName{};
+  template <typename T = ChromeUserEventTranslationTable_ActionHashToNameEntry> T* add_action_hash_to_name() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ChromeUserEventTranslationTable_ActionHashToNameEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeUserEventTranslationTable_ActionHashToNameEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeUserEventTranslationTable_ActionHashToNameEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeUserEventTranslationTable_ActionHashToNameEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  uint64_t key() const { return at<1>().as_uint64(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class ChromeUserEventTranslationTable_ActionHashToNameEntry : public ::protozero::Message {
+ public:
+  using Decoder = ChromeUserEventTranslationTable_ActionHashToNameEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeUserEventTranslationTable.ActionHashToNameEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeUserEventTranslationTable_ActionHashToNameEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeUserEventTranslationTable_ActionHashToNameEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class ChromeHistorgramTranslationTable_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  ChromeHistorgramTranslationTable_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeHistorgramTranslationTable_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeHistorgramTranslationTable_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_hash_to_name() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> hash_to_name() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class ChromeHistorgramTranslationTable : public ::protozero::Message {
+ public:
+  using Decoder = ChromeHistorgramTranslationTable_Decoder;
+  enum : int32_t {
+    kHashToNameFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeHistorgramTranslationTable"; }
+
+  using HashToNameEntry = ::perfetto::protos::pbzero::ChromeHistorgramTranslationTable_HashToNameEntry;
+
+  using FieldMetadata_HashToName =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeHistorgramTranslationTable_HashToNameEntry,
+      ChromeHistorgramTranslationTable>;
+
+  static constexpr FieldMetadata_HashToName kHashToName{};
+  template <typename T = ChromeHistorgramTranslationTable_HashToNameEntry> T* add_hash_to_name() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+class ChromeHistorgramTranslationTable_HashToNameEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ChromeHistorgramTranslationTable_HashToNameEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ChromeHistorgramTranslationTable_HashToNameEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ChromeHistorgramTranslationTable_HashToNameEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_key() const { return at<1>().valid(); }
+  uint64_t key() const { return at<1>().as_uint64(); }
+  bool has_value() const { return at<2>().valid(); }
+  ::protozero::ConstChars value() const { return at<2>().as_string(); }
+};
+
+class ChromeHistorgramTranslationTable_HashToNameEntry : public ::protozero::Message {
+ public:
+  using Decoder = ChromeHistorgramTranslationTable_HashToNameEntry_Decoder;
+  enum : int32_t {
+    kKeyFieldNumber = 1,
+    kValueFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ChromeHistorgramTranslationTable.HashToNameEntry"; }
+
+
+  using FieldMetadata_Key =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      ChromeHistorgramTranslationTable_HashToNameEntry>;
+
+  static constexpr FieldMetadata_Key kKey{};
+  void set_key(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Value =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      ChromeHistorgramTranslationTable_HashToNameEntry>;
+
+  static constexpr FieldMetadata_Value kValue{};
+  void set_value(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Value::kFieldId, data, size);
+  }
+  void set_value(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Value::kFieldId, chars.data, chars.size);
+  }
+  void set_value(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class TranslationTable_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TranslationTable_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TranslationTable_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TranslationTable_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_chrome_histogram() const { return at<1>().valid(); }
+  ::protozero::ConstBytes chrome_histogram() const { return at<1>().as_bytes(); }
+  bool has_chrome_user_event() const { return at<2>().valid(); }
+  ::protozero::ConstBytes chrome_user_event() const { return at<2>().as_bytes(); }
+  bool has_chrome_performance_mark() const { return at<3>().valid(); }
+  ::protozero::ConstBytes chrome_performance_mark() const { return at<3>().as_bytes(); }
+  bool has_slice_name() const { return at<4>().valid(); }
+  ::protozero::ConstBytes slice_name() const { return at<4>().as_bytes(); }
+};
+
+class TranslationTable : public ::protozero::Message {
+ public:
+  using Decoder = TranslationTable_Decoder;
+  enum : int32_t {
+    kChromeHistogramFieldNumber = 1,
+    kChromeUserEventFieldNumber = 2,
+    kChromePerformanceMarkFieldNumber = 3,
+    kSliceNameFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TranslationTable"; }
+
+
+  using FieldMetadata_ChromeHistogram =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeHistorgramTranslationTable,
+      TranslationTable>;
+
+  static constexpr FieldMetadata_ChromeHistogram kChromeHistogram{};
+  template <typename T = ChromeHistorgramTranslationTable> T* set_chrome_histogram() {
+    return BeginNestedMessage<T>(1);
+  }
+
+
+  using FieldMetadata_ChromeUserEvent =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromeUserEventTranslationTable,
+      TranslationTable>;
+
+  static constexpr FieldMetadata_ChromeUserEvent kChromeUserEvent{};
+  template <typename T = ChromeUserEventTranslationTable> T* set_chrome_user_event() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_ChromePerformanceMark =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      ChromePerformanceMarkTranslationTable,
+      TranslationTable>;
+
+  static constexpr FieldMetadata_ChromePerformanceMark kChromePerformanceMark{};
+  template <typename T = ChromePerformanceMarkTranslationTable> T* set_chrome_performance_mark() {
+    return BeginNestedMessage<T>(3);
+  }
+
+
+  using FieldMetadata_SliceName =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      SliceNameTranslationTable,
+      TranslationTable>;
+
+  static constexpr FieldMetadata_SliceName kSliceName{};
+  template <typename T = SliceNameTranslationTable> T* set_slice_name() {
+    return BeginNestedMessage<T>(4);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_DEFAULTS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_DEFAULTS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class PerfSampleDefaults;
+class TrackEventDefaults;
+
+class TracePacketDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/58, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TracePacketDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TracePacketDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TracePacketDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timestamp_clock_id() const { return at<58>().valid(); }
+  uint32_t timestamp_clock_id() const { return at<58>().as_uint32(); }
+  bool has_track_event_defaults() const { return at<11>().valid(); }
+  ::protozero::ConstBytes track_event_defaults() const { return at<11>().as_bytes(); }
+  bool has_perf_sample_defaults() const { return at<12>().valid(); }
+  ::protozero::ConstBytes perf_sample_defaults() const { return at<12>().as_bytes(); }
+};
+
+class TracePacketDefaults : public ::protozero::Message {
+ public:
+  using Decoder = TracePacketDefaults_Decoder;
+  enum : int32_t {
+    kTimestampClockIdFieldNumber = 58,
+    kTrackEventDefaultsFieldNumber = 11,
+    kPerfSampleDefaultsFieldNumber = 12,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TracePacketDefaults"; }
+
+
+  using FieldMetadata_TimestampClockId =
+    ::protozero::proto_utils::FieldMetadata<
+      58,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TracePacketDefaults>;
+
+  static constexpr FieldMetadata_TimestampClockId kTimestampClockId{};
+  void set_timestamp_clock_id(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimestampClockId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TrackEventDefaults =
+    ::protozero::proto_utils::FieldMetadata<
+      11,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TrackEventDefaults,
+      TracePacketDefaults>;
+
+  static constexpr FieldMetadata_TrackEventDefaults kTrackEventDefaults{};
+  template <typename T = TrackEventDefaults> T* set_track_event_defaults() {
+    return BeginNestedMessage<T>(11);
+  }
+
+
+  using FieldMetadata_PerfSampleDefaults =
+    ::protozero::proto_utils::FieldMetadata<
+      12,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      PerfSampleDefaults,
+      TracePacketDefaults>;
+
+  static constexpr FieldMetadata_PerfSampleDefaults kPerfSampleDefaults{};
+  template <typename T = PerfSampleDefaults> T* set_perf_sample_defaults() {
+    return BeginNestedMessage<T>(12);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/test_event.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TEST_EVENT_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TEST_EVENT_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DebugAnnotation;
+class TestEvent_TestPayload;
+
+class TestEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  TestEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_str() const { return at<1>().valid(); }
+  ::protozero::ConstChars str() const { return at<1>().as_string(); }
+  bool has_seq_value() const { return at<2>().valid(); }
+  uint32_t seq_value() const { return at<2>().as_uint32(); }
+  bool has_counter() const { return at<3>().valid(); }
+  uint64_t counter() const { return at<3>().as_uint64(); }
+  bool has_is_last() const { return at<4>().valid(); }
+  bool is_last() const { return at<4>().as_bool(); }
+  bool has_payload() const { return at<5>().valid(); }
+  ::protozero::ConstBytes payload() const { return at<5>().as_bytes(); }
+};
+
+class TestEvent : public ::protozero::Message {
+ public:
+  using Decoder = TestEvent_Decoder;
+  enum : int32_t {
+    kStrFieldNumber = 1,
+    kSeqValueFieldNumber = 2,
+    kCounterFieldNumber = 3,
+    kIsLastFieldNumber = 4,
+    kPayloadFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestEvent"; }
+
+  using TestPayload = ::perfetto::protos::pbzero::TestEvent_TestPayload;
+
+  using FieldMetadata_Str =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestEvent>;
+
+  static constexpr FieldMetadata_Str kStr{};
+  void set_str(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, size);
+  }
+  void set_str(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Str::kFieldId, chars.data, chars.size);
+  }
+  void set_str(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Str::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SeqValue =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestEvent>;
+
+  static constexpr FieldMetadata_SeqValue kSeqValue{};
+  void set_seq_value(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SeqValue::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Counter =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      TestEvent>;
+
+  static constexpr FieldMetadata_Counter kCounter{};
+  void set_counter(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Counter::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IsLast =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      TestEvent>;
+
+  static constexpr FieldMetadata_IsLast kIsLast{};
+  void set_is_last(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_IsLast::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Payload =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestEvent_TestPayload,
+      TestEvent>;
+
+  static constexpr FieldMetadata_Payload kPayload{};
+  template <typename T = TestEvent_TestPayload> T* set_payload() {
+    return BeginNestedMessage<T>(5);
+  }
+
+};
+
+class TestEvent_TestPayload_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TestEvent_TestPayload_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestEvent_TestPayload_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestEvent_TestPayload_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_str() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstChars> str() const { return GetRepeated<::protozero::ConstChars>(1); }
+  bool has_nested() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> nested() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_single_string() const { return at<4>().valid(); }
+  ::protozero::ConstChars single_string() const { return at<4>().as_string(); }
+  bool has_single_int() const { return at<5>().valid(); }
+  int32_t single_int() const { return at<5>().as_int32(); }
+  bool has_repeated_ints() const { return at<6>().valid(); }
+  ::protozero::RepeatedFieldIterator<int32_t> repeated_ints() const { return GetRepeated<int32_t>(6); }
+  bool has_remaining_nesting_depth() const { return at<3>().valid(); }
+  uint32_t remaining_nesting_depth() const { return at<3>().as_uint32(); }
+  bool has_debug_annotations() const { return at<7>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotations() const { return GetRepeated<::protozero::ConstBytes>(7); }
+};
+
+class TestEvent_TestPayload : public ::protozero::Message {
+ public:
+  using Decoder = TestEvent_TestPayload_Decoder;
+  enum : int32_t {
+    kStrFieldNumber = 1,
+    kNestedFieldNumber = 2,
+    kSingleStringFieldNumber = 4,
+    kSingleIntFieldNumber = 5,
+    kRepeatedIntsFieldNumber = 6,
+    kRemainingNestingDepthFieldNumber = 3,
+    kDebugAnnotationsFieldNumber = 7,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestEvent.TestPayload"; }
+
+
+  using FieldMetadata_Str =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_Str kStr{};
+  void add_str(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Str::kFieldId, data, size);
+  }
+  void add_str(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Str::kFieldId, chars.data, chars.size);
+  }
+  void add_str(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Str::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Nested =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestEvent_TestPayload,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_Nested kNested{};
+  template <typename T = TestEvent_TestPayload> T* add_nested() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_SingleString =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_SingleString kSingleString{};
+  void set_single_string(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_SingleString::kFieldId, data, size);
+  }
+  void set_single_string(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_SingleString::kFieldId, chars.data, chars.size);
+  }
+  void set_single_string(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_SingleString::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SingleInt =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_SingleInt kSingleInt{};
+  void set_single_int(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SingleInt::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RepeatedInts =
+    ::protozero::proto_utils::FieldMetadata<
+      6,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_RepeatedInts kRepeatedInts{};
+  void add_repeated_ints(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RepeatedInts::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_RemainingNestingDepth =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_RemainingNestingDepth kRemainingNestingDepth{};
+  void set_remaining_nesting_depth(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_RemainingNestingDepth::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DebugAnnotations =
+    ::protozero::proto_utils::FieldMetadata<
+      7,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      TestEvent_TestPayload>;
+
+  static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations{};
+  template <typename T = DebugAnnotation> T* add_debug_annotations() {
+    return BeginNestedMessage<T>(7);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/test_extensions.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TEST_EXTENSIONS_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TEST_EXTENSIONS_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class DebugAnnotation;
+
+class TestExtensionChild_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/99, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  TestExtensionChild_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit TestExtensionChild_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit TestExtensionChild_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_child_field_for_testing() const { return at<1>().valid(); }
+  ::protozero::ConstChars child_field_for_testing() const { return at<1>().as_string(); }
+  bool has_debug_annotations() const { return at<99>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> debug_annotations() const { return GetRepeated<::protozero::ConstBytes>(99); }
+};
+
+class TestExtensionChild : public ::protozero::Message {
+ public:
+  using Decoder = TestExtensionChild_Decoder;
+  enum : int32_t {
+    kChildFieldForTestingFieldNumber = 1,
+    kDebugAnnotationsFieldNumber = 99,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.TestExtensionChild"; }
+
+
+  using FieldMetadata_ChildFieldForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestExtensionChild>;
+
+  static constexpr FieldMetadata_ChildFieldForTesting kChildFieldForTesting{};
+  void set_child_field_for_testing(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ChildFieldForTesting::kFieldId, data, size);
+  }
+  void set_child_field_for_testing(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ChildFieldForTesting::kFieldId, chars.data, chars.size);
+  }
+  void set_child_field_for_testing(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ChildFieldForTesting::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_DebugAnnotations =
+    ::protozero::proto_utils::FieldMetadata<
+      99,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      DebugAnnotation,
+      TestExtensionChild>;
+
+  static constexpr FieldMetadata_DebugAnnotations kDebugAnnotations{};
+  template <typename T = DebugAnnotation> T* add_debug_annotations() {
+    return BeginNestedMessage<T>(99);
+  }
+
+};
+
+class TestExtension : public ::perfetto::protos::pbzero::TrackEvent {
+ public:
+
+  using FieldMetadata_StringExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9900,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestExtension>;
+
+  static constexpr FieldMetadata_StringExtensionForTesting kStringExtensionForTesting{};
+  void set_string_extension_for_testing(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringExtensionForTesting::kFieldId, data, size);
+  }
+  void set_string_extension_for_testing(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringExtensionForTesting::kFieldId, chars.data, chars.size);
+  }
+  void set_string_extension_for_testing(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringExtensionForTesting::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_StringExtensionForTesting2 =
+    ::protozero::proto_utils::FieldMetadata<
+      9905,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestExtension>;
+
+  static constexpr FieldMetadata_StringExtensionForTesting2 kStringExtensionForTesting2{};
+  void set_string_extension_for_testing2(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_StringExtensionForTesting2::kFieldId, data, size);
+  }
+  void set_string_extension_for_testing2(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_StringExtensionForTesting2::kFieldId, chars.data, chars.size);
+  }
+  void set_string_extension_for_testing2(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_StringExtensionForTesting2::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_IntExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9901,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      TestExtension>;
+
+  static constexpr FieldMetadata_IntExtensionForTesting kIntExtensionForTesting{};
+  void add_int_extension_for_testing(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_IntExtensionForTesting::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_OmittedExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9902,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      TestExtension>;
+
+  static constexpr FieldMetadata_OmittedExtensionForTesting kOmittedExtensionForTesting{};
+  void set_omitted_extension_for_testing(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_OmittedExtensionForTesting::kFieldId, data, size);
+  }
+  void set_omitted_extension_for_testing(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_OmittedExtensionForTesting::kFieldId, chars.data, chars.size);
+  }
+  void set_omitted_extension_for_testing(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_OmittedExtensionForTesting::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_NestedMessageExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9903,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TestExtensionChild,
+      TestExtension>;
+
+  static constexpr FieldMetadata_NestedMessageExtensionForTesting kNestedMessageExtensionForTesting{};
+  template <typename T = TestExtensionChild> T* set_nested_message_extension_for_testing() {
+    return BeginNestedMessage<T>(9903);
+  }
+
+
+  using FieldMetadata_UintExtensionForTesting =
+    ::protozero::proto_utils::FieldMetadata<
+      9904,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      TestExtension>;
+
+  static constexpr FieldMetadata_UintExtensionForTesting kUintExtensionForTesting{};
+  void set_uint_extension_for_testing(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_UintExtensionForTesting::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+};
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/trace.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class TracePacket;
+
+class Trace_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  Trace_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit Trace_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit Trace_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_packet() const { return at<1>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> packet() const { return GetRepeated<::protozero::ConstBytes>(1); }
+};
+
+class Trace : public ::protozero::Message {
+ public:
+  using Decoder = Trace_Decoder;
+  enum : int32_t {
+    kPacketFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.Trace"; }
+
+
+  using FieldMetadata_Packet =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      TracePacket,
+      Trace>;
+
+  static constexpr FieldMetadata_Packet kPacket{};
+  template <typename T = TracePacket> T* add_packet() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/extension_descriptor.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_EXTENSION_DESCRIPTOR_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_EXTENSION_DESCRIPTOR_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class FileDescriptorSet;
+
+class ExtensionDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  ExtensionDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit ExtensionDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit ExtensionDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_extension_set() const { return at<1>().valid(); }
+  ::protozero::ConstBytes extension_set() const { return at<1>().as_bytes(); }
+};
+
+class ExtensionDescriptor : public ::protozero::Message {
+ public:
+  using Decoder = ExtensionDescriptor_Decoder;
+  enum : int32_t {
+    kExtensionSetFieldNumber = 1,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.ExtensionDescriptor"; }
+
+
+  using FieldMetadata_ExtensionSet =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      FileDescriptorSet,
+      ExtensionDescriptor>;
+
+  static constexpr FieldMetadata_ExtensionSet kExtensionSet{};
+  template <typename T = FileDescriptorSet> T* set_extension_set() {
+    return BeginNestedMessage<T>(1);
+  }
+
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/memory_graph.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_MEMORY_GRAPH_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_MEMORY_GRAPH_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class MemoryTrackerSnapshot_ProcessSnapshot;
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge;
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode;
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry;
+namespace perfetto_pbzero_enum_MemoryTrackerSnapshot {
+enum LevelOfDetail : int32_t;
+}  // namespace perfetto_pbzero_enum_MemoryTrackerSnapshot
+using MemoryTrackerSnapshot_LevelOfDetail = perfetto_pbzero_enum_MemoryTrackerSnapshot::LevelOfDetail;
+namespace perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry {
+enum Units : int32_t;
+}  // namespace perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry
+using MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units = perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry::Units;
+
+namespace perfetto_pbzero_enum_MemoryTrackerSnapshot {
+enum LevelOfDetail : int32_t {
+  DETAIL_FULL = 0,
+  DETAIL_LIGHT = 1,
+  DETAIL_BACKGROUND = 2,
+};
+} // namespace perfetto_pbzero_enum_MemoryTrackerSnapshot
+using MemoryTrackerSnapshot_LevelOfDetail = perfetto_pbzero_enum_MemoryTrackerSnapshot::LevelOfDetail;
+
+
+constexpr MemoryTrackerSnapshot_LevelOfDetail MemoryTrackerSnapshot_LevelOfDetail_MIN = MemoryTrackerSnapshot_LevelOfDetail::DETAIL_FULL;
+constexpr MemoryTrackerSnapshot_LevelOfDetail MemoryTrackerSnapshot_LevelOfDetail_MAX = MemoryTrackerSnapshot_LevelOfDetail::DETAIL_BACKGROUND;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* MemoryTrackerSnapshot_LevelOfDetail_Name(::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail::DETAIL_FULL:
+    return "DETAIL_FULL";
+
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail::DETAIL_LIGHT:
+    return "DETAIL_LIGHT";
+
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail::DETAIL_BACKGROUND:
+    return "DETAIL_BACKGROUND";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+namespace perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry {
+enum Units : int32_t {
+  UNSPECIFIED = 0,
+  BYTES = 1,
+  COUNT = 2,
+};
+} // namespace perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry
+using MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units = perfetto_pbzero_enum_MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry::Units;
+
+
+constexpr MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_MIN = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units::UNSPECIFIED;
+constexpr MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_MAX = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units::COUNT;
+
+
+PERFETTO_PROTOZERO_CONSTEXPR14_OR_INLINE
+const char* MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_Name(::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units value) {
+  switch (value) {
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units::UNSPECIFIED:
+    return "UNSPECIFIED";
+
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units::BYTES:
+    return "BYTES";
+
+  case ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units::COUNT:
+    return "COUNT";
+  }
+  return "PBZERO_UNKNOWN_ENUM_VALUE";
+}
+
+class MemoryTrackerSnapshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  MemoryTrackerSnapshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MemoryTrackerSnapshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MemoryTrackerSnapshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_global_dump_id() const { return at<1>().valid(); }
+  uint64_t global_dump_id() const { return at<1>().as_uint64(); }
+  bool has_level_of_detail() const { return at<2>().valid(); }
+  int32_t level_of_detail() const { return at<2>().as_int32(); }
+  bool has_process_memory_dumps() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> process_memory_dumps() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class MemoryTrackerSnapshot : public ::protozero::Message {
+ public:
+  using Decoder = MemoryTrackerSnapshot_Decoder;
+  enum : int32_t {
+    kGlobalDumpIdFieldNumber = 1,
+    kLevelOfDetailFieldNumber = 2,
+    kProcessMemoryDumpsFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MemoryTrackerSnapshot"; }
+
+  using ProcessSnapshot = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot;
+
+  using LevelOfDetail = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail;
+  static inline const char* LevelOfDetail_Name(LevelOfDetail value) {
+    return ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail_Name(value);
+  }
+  static inline const LevelOfDetail DETAIL_FULL = LevelOfDetail::DETAIL_FULL;
+  static inline const LevelOfDetail DETAIL_LIGHT = LevelOfDetail::DETAIL_LIGHT;
+  static inline const LevelOfDetail DETAIL_BACKGROUND = LevelOfDetail::DETAIL_BACKGROUND;
+
+  using FieldMetadata_GlobalDumpId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot>;
+
+  static constexpr FieldMetadata_GlobalDumpId kGlobalDumpId{};
+  void set_global_dump_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_GlobalDumpId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_LevelOfDetail =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail,
+      MemoryTrackerSnapshot>;
+
+  static constexpr FieldMetadata_LevelOfDetail kLevelOfDetail{};
+  void set_level_of_detail(::perfetto::protos::pbzero::MemoryTrackerSnapshot_LevelOfDetail value) {
+    static constexpr uint32_t field_id = FieldMetadata_LevelOfDetail::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ProcessMemoryDumps =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MemoryTrackerSnapshot_ProcessSnapshot,
+      MemoryTrackerSnapshot>;
+
+  static constexpr FieldMetadata_ProcessMemoryDumps kProcessMemoryDumps{};
+  template <typename T = MemoryTrackerSnapshot_ProcessSnapshot> T* add_process_memory_dumps() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  MemoryTrackerSnapshot_ProcessSnapshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  int32_t pid() const { return at<1>().as_int32(); }
+  bool has_allocator_dumps() const { return at<2>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> allocator_dumps() const { return GetRepeated<::protozero::ConstBytes>(2); }
+  bool has_memory_edges() const { return at<3>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> memory_edges() const { return GetRepeated<::protozero::ConstBytes>(3); }
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot : public ::protozero::Message {
+ public:
+  using Decoder = MemoryTrackerSnapshot_ProcessSnapshot_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kAllocatorDumpsFieldNumber = 2,
+    kMemoryEdgesFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot"; }
+
+  using MemoryNode = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode;
+  using MemoryEdge = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge;
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt32,
+      int32_t,
+      MemoryTrackerSnapshot_ProcessSnapshot>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(int32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AllocatorDumps =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode,
+      MemoryTrackerSnapshot_ProcessSnapshot>;
+
+  static constexpr FieldMetadata_AllocatorDumps kAllocatorDumps{};
+  template <typename T = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode> T* add_allocator_dumps() {
+    return BeginNestedMessage<T>(2);
+  }
+
+
+  using FieldMetadata_MemoryEdges =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge,
+      MemoryTrackerSnapshot_ProcessSnapshot>;
+
+  static constexpr FieldMetadata_MemoryEdges kMemoryEdges{};
+  template <typename T = MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge> T* add_memory_edges() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_source_id() const { return at<1>().valid(); }
+  uint64_t source_id() const { return at<1>().as_uint64(); }
+  bool has_target_id() const { return at<2>().valid(); }
+  uint64_t target_id() const { return at<2>().as_uint64(); }
+  bool has_importance() const { return at<3>().valid(); }
+  uint32_t importance() const { return at<3>().as_uint32(); }
+  bool has_overridable() const { return at<4>().valid(); }
+  bool overridable() const { return at<4>().as_bool(); }
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge : public ::protozero::Message {
+ public:
+  using Decoder = MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge_Decoder;
+  enum : int32_t {
+    kSourceIdFieldNumber = 1,
+    kTargetIdFieldNumber = 2,
+    kImportanceFieldNumber = 3,
+    kOverridableFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryEdge"; }
+
+
+  using FieldMetadata_SourceId =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge>;
+
+  static constexpr FieldMetadata_SourceId kSourceId{};
+  void set_source_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SourceId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TargetId =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge>;
+
+  static constexpr FieldMetadata_TargetId kTargetId{};
+  void set_target_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TargetId::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Importance =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge>;
+
+  static constexpr FieldMetadata_Importance kImportance{};
+  void set_importance(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Importance::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Overridable =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryEdge>;
+
+  static constexpr FieldMetadata_Overridable kOverridable{};
+  void set_overridable(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Overridable::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
+ public:
+  MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_id() const { return at<1>().valid(); }
+  uint64_t id() const { return at<1>().as_uint64(); }
+  bool has_absolute_name() const { return at<2>().valid(); }
+  ::protozero::ConstChars absolute_name() const { return at<2>().as_string(); }
+  bool has_weak() const { return at<3>().valid(); }
+  bool weak() const { return at<3>().as_bool(); }
+  bool has_size_bytes() const { return at<4>().valid(); }
+  uint64_t size_bytes() const { return at<4>().as_uint64(); }
+  bool has_entries() const { return at<5>().valid(); }
+  ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> entries() const { return GetRepeated<::protozero::ConstBytes>(5); }
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode : public ::protozero::Message {
+ public:
+  using Decoder = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_Decoder;
+  enum : int32_t {
+    kIdFieldNumber = 1,
+    kAbsoluteNameFieldNumber = 2,
+    kWeakFieldNumber = 3,
+    kSizeBytesFieldNumber = 4,
+    kEntriesFieldNumber = 5,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryNode"; }
+
+  using MemoryNodeEntry = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry;
+
+  using FieldMetadata_Id =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode>;
+
+  static constexpr FieldMetadata_Id kId{};
+  void set_id(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Id::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_AbsoluteName =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode>;
+
+  static constexpr FieldMetadata_AbsoluteName kAbsoluteName{};
+  void set_absolute_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_AbsoluteName::kFieldId, data, size);
+  }
+  void set_absolute_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_AbsoluteName::kFieldId, chars.data, chars.size);
+  }
+  void set_absolute_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_AbsoluteName::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Weak =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kBool,
+      bool,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode>;
+
+  static constexpr FieldMetadata_Weak kWeak{};
+  void set_weak(bool value) {
+    static constexpr uint32_t field_id = FieldMetadata_Weak::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kBool>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_SizeBytes =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode>;
+
+  static constexpr FieldMetadata_SizeBytes kSizeBytes{};
+  void set_size_bytes(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_SizeBytes::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Entries =
+    ::protozero::proto_utils::FieldMetadata<
+      5,
+      ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode>;
+
+  static constexpr FieldMetadata_Entries kEntries{};
+  template <typename T = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry> T* add_entries() {
+    return BeginNestedMessage<T>(5);
+  }
+
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_name() const { return at<1>().valid(); }
+  ::protozero::ConstChars name() const { return at<1>().as_string(); }
+  bool has_units() const { return at<2>().valid(); }
+  int32_t units() const { return at<2>().as_int32(); }
+  bool has_value_uint64() const { return at<3>().valid(); }
+  uint64_t value_uint64() const { return at<3>().as_uint64(); }
+  bool has_value_string() const { return at<4>().valid(); }
+  ::protozero::ConstChars value_string() const { return at<4>().as_string(); }
+};
+
+class MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry : public ::protozero::Message {
+ public:
+  using Decoder = MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Decoder;
+  enum : int32_t {
+    kNameFieldNumber = 1,
+    kUnitsFieldNumber = 2,
+    kValueUint64FieldNumber = 3,
+    kValueStringFieldNumber = 4,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryNode.MemoryNodeEntry"; }
+
+
+  using Units = ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units;
+  static inline const char* Units_Name(Units value) {
+    return ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units_Name(value);
+  }
+  static inline const Units UNSPECIFIED = Units::UNSPECIFIED;
+  static inline const Units BYTES = Units::BYTES;
+  static inline const Units COUNT = Units::COUNT;
+
+  using FieldMetadata_Name =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry>;
+
+  static constexpr FieldMetadata_Name kName{};
+  void set_name(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Name::kFieldId, data, size);
+  }
+  void set_name(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Name::kFieldId, chars.data, chars.size);
+  }
+  void set_name(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Units =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kEnum,
+      ::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry>;
+
+  static constexpr FieldMetadata_Units kUnits{};
+  void set_units(::perfetto::protos::pbzero::MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry_Units value) {
+    static constexpr uint32_t field_id = FieldMetadata_Units::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kEnum>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ValueUint64 =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint64,
+      uint64_t,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry>;
+
+  static constexpr FieldMetadata_ValueUint64 kValueUint64{};
+  void set_value_uint64(uint64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_ValueUint64::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_ValueString =
+    ::protozero::proto_utils::FieldMetadata<
+      4,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      MemoryTrackerSnapshot_ProcessSnapshot_MemoryNode_MemoryNodeEntry>;
+
+  static constexpr FieldMetadata_ValueString kValueString{};
+  void set_value_string(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_ValueString::kFieldId, data, size);
+  }
+  void set_value_string(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_ValueString::kFieldId, chars.data, chars.size);
+  }
+  void set_value_string(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_ValueString::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/ui_state.pbzero.h
+// Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
+
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_UI_STATE_PROTO_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_UI_STATE_PROTO_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+
+class UiState_HighlightProcess;
+
+class UiState_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UiState_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UiState_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UiState_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_timeline_start_ts() const { return at<1>().valid(); }
+  int64_t timeline_start_ts() const { return at<1>().as_int64(); }
+  bool has_timeline_end_ts() const { return at<2>().valid(); }
+  int64_t timeline_end_ts() const { return at<2>().as_int64(); }
+  bool has_highlight_process() const { return at<3>().valid(); }
+  ::protozero::ConstBytes highlight_process() const { return at<3>().as_bytes(); }
+};
+
+class UiState : public ::protozero::Message {
+ public:
+  using Decoder = UiState_Decoder;
+  enum : int32_t {
+    kTimelineStartTsFieldNumber = 1,
+    kTimelineEndTsFieldNumber = 2,
+    kHighlightProcessFieldNumber = 3,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UiState"; }
+
+  using HighlightProcess = ::perfetto::protos::pbzero::UiState_HighlightProcess;
+
+  using FieldMetadata_TimelineStartTs =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      UiState>;
+
+  static constexpr FieldMetadata_TimelineStartTs kTimelineStartTs{};
+  void set_timeline_start_ts(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimelineStartTs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_TimelineEndTs =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kInt64,
+      int64_t,
+      UiState>;
+
+  static constexpr FieldMetadata_TimelineEndTs kTimelineEndTs{};
+  void set_timeline_end_ts(int64_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_TimelineEndTs::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kInt64>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_HighlightProcess =
+    ::protozero::proto_utils::FieldMetadata<
+      3,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kMessage,
+      UiState_HighlightProcess,
+      UiState>;
+
+  static constexpr FieldMetadata_HighlightProcess kHighlightProcess{};
+  template <typename T = UiState_HighlightProcess> T* set_highlight_process() {
+    return BeginNestedMessage<T>(3);
+  }
+
+};
+
+class UiState_HighlightProcess_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
+ public:
+  UiState_HighlightProcess_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
+  explicit UiState_HighlightProcess_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
+  explicit UiState_HighlightProcess_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
+  bool has_pid() const { return at<1>().valid(); }
+  uint32_t pid() const { return at<1>().as_uint32(); }
+  bool has_cmdline() const { return at<2>().valid(); }
+  ::protozero::ConstChars cmdline() const { return at<2>().as_string(); }
+};
+
+class UiState_HighlightProcess : public ::protozero::Message {
+ public:
+  using Decoder = UiState_HighlightProcess_Decoder;
+  enum : int32_t {
+    kPidFieldNumber = 1,
+    kCmdlineFieldNumber = 2,
+  };
+  static constexpr const char* GetName() { return ".perfetto.protos.UiState.HighlightProcess"; }
+
+
+  using FieldMetadata_Pid =
+    ::protozero::proto_utils::FieldMetadata<
+      1,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kUint32,
+      uint32_t,
+      UiState_HighlightProcess>;
+
+  static constexpr FieldMetadata_Pid kPid{};
+  void set_pid(uint32_t value) {
+    static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kUint32>
+        ::Append(*this, field_id, value);
+  }
+
+  using FieldMetadata_Cmdline =
+    ::protozero::proto_utils::FieldMetadata<
+      2,
+      ::protozero::proto_utils::RepetitionType::kNotRepeated,
+      ::protozero::proto_utils::ProtoSchemaType::kString,
+      std::string,
+      UiState_HighlightProcess>;
+
+  static constexpr FieldMetadata_Cmdline kCmdline{};
+  void set_cmdline(const char* data, size_t size) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
+  }
+  void set_cmdline(::protozero::ConstChars chars) {
+    AppendBytes(FieldMetadata_Cmdline::kFieldId, chars.data, chars.size);
+  }
+  void set_cmdline(std::string value) {
+    static constexpr uint32_t field_id = FieldMetadata_Cmdline::kFieldId;
+    // Call the appropriate protozero::Message::Append(field_id, ...)
+    // method based on the type of the field.
+    ::protozero::internal::FieldWriter<
+      ::protozero::proto_utils::ProtoSchemaType::kString>
+        ::Append(*this, field_id, value);
+  }
+};
+
+} // Namespace.
+} // Namespace.
+} // Namespace.
+#endif  // Include guard.
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_active_processes.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_ACTIVE_PROCESSES_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_ACTIVE_PROCESSES_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeActiveProcesses;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeActiveProcesses : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPidFieldNumber = 1,
+  };
+
+  ChromeActiveProcesses();
+  ~ChromeActiveProcesses() override;
+  ChromeActiveProcesses(ChromeActiveProcesses&&) noexcept;
+  ChromeActiveProcesses& operator=(ChromeActiveProcesses&&);
+  ChromeActiveProcesses(const ChromeActiveProcesses&);
+  ChromeActiveProcesses& operator=(const ChromeActiveProcesses&);
+  bool operator==(const ChromeActiveProcesses&) const;
+  bool operator!=(const ChromeActiveProcesses& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<int32_t>& pid() const { return pid_; }
+  std::vector<int32_t>* mutable_pid() { return &pid_; }
+  int pid_size() const { return static_cast<int>(pid_.size()); }
+  void clear_pid() { pid_.clear(); }
+  void add_pid(int32_t value) { pid_.emplace_back(value); }
+  int32_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
+
+ private:
+  std::vector<int32_t> pid_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_ACTIVE_PROCESSES_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_application_state_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeApplicationStateInfo;
+enum ChromeApplicationStateInfo_ChromeApplicationState : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeApplicationStateInfo_ChromeApplicationState : int {
+  ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN = 0,
+  ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = 1,
+  ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = 2,
+  ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = 3,
+  ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = 4,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeApplicationStateInfo : public ::protozero::CppMessageObj {
+ public:
+  using ChromeApplicationState = ChromeApplicationStateInfo_ChromeApplicationState;
+  static constexpr auto APPLICATION_STATE_UNKNOWN = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN;
+  static constexpr auto APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+  static constexpr auto APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
+  static constexpr auto APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_STOPPED_ACTIVITIES;
+  static constexpr auto APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
+  static constexpr auto ChromeApplicationState_MIN = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN;
+  static constexpr auto ChromeApplicationState_MAX = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
+  enum FieldNumbers {
+    kApplicationStateFieldNumber = 1,
+  };
+
+  ChromeApplicationStateInfo();
+  ~ChromeApplicationStateInfo() override;
+  ChromeApplicationStateInfo(ChromeApplicationStateInfo&&) noexcept;
+  ChromeApplicationStateInfo& operator=(ChromeApplicationStateInfo&&);
+  ChromeApplicationStateInfo(const ChromeApplicationStateInfo&);
+  ChromeApplicationStateInfo& operator=(const ChromeApplicationStateInfo&);
+  bool operator==(const ChromeApplicationStateInfo&) const;
+  bool operator!=(const ChromeApplicationStateInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_application_state() const { return _has_field_[1]; }
+  ChromeApplicationStateInfo_ChromeApplicationState application_state() const { return application_state_; }
+  void set_application_state(ChromeApplicationStateInfo_ChromeApplicationState value) { application_state_ = value; _has_field_.set(1); }
+
+ private:
+  ChromeApplicationStateInfo_ChromeApplicationState application_state_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class CompositorTimingHistory;
+class BeginFrameSourceState;
+class BeginFrameArgs;
+class SourceLocation;
+class BeginFrameObserverState;
+class BeginImplFrameArgs;
+class BeginImplFrameArgs_TimestampsInUs;
+class ChromeCompositorStateMachine;
+class ChromeCompositorStateMachine_MinorState;
+class ChromeCompositorStateMachine_MajorState;
+class ChromeCompositorSchedulerState;
+enum ChromeCompositorSchedulerAction : int;
+enum BeginFrameArgs_BeginFrameArgsType : int;
+enum BeginImplFrameArgs_State : int;
+enum ChromeCompositorStateMachine_MinorState_TreePriority : int;
+enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int;
+enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int;
+enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int;
+enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int;
+enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int;
+enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeCompositorSchedulerAction : int {
+  CC_SCHEDULER_ACTION_UNSPECIFIED = 0,
+  CC_SCHEDULER_ACTION_NONE = 1,
+  CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME = 2,
+  CC_SCHEDULER_ACTION_COMMIT = 3,
+  CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE = 4,
+  CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE = 5,
+  CC_SCHEDULER_ACTION_DRAW_FORCED = 6,
+  CC_SCHEDULER_ACTION_DRAW_ABORT = 7,
+  CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION = 8,
+  CC_SCHEDULER_ACTION_PREPARE_TILES = 9,
+  CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK = 10,
+  CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION = 11,
+  CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL = 12,
+  CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON = 13,
+};
+enum BeginFrameArgs_BeginFrameArgsType : int {
+  BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = 0,
+  BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID = 1,
+  BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL = 2,
+  BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED = 3,
+};
+enum BeginImplFrameArgs_State : int {
+  BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED = 0,
+  BeginImplFrameArgs_State_BEGIN_FRAME_USING = 1,
+};
+enum ChromeCompositorStateMachine_MinorState_TreePriority : int {
+  ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = 1,
+  ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = 2,
+  ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = 3,
+};
+enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int {
+  ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER = 1,
+  ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = 2,
+};
+enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int {
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE = 1,
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = 2,
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE = 3,
+};
+enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int {
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE = 1,
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT = 2,
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT = 3,
+};
+enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int {
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE = 1,
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE = 2,
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING = 3,
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = 4,
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = 5,
+};
+enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int {
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED = 0,
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE = 1,
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT = 2,
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION = 3,
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW = 4,
+};
+enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int {
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED = 0,
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE = 1,
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE = 2,
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR = 3,
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE = 4,
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED = 5,
+};
+
+class PERFETTO_EXPORT_COMPONENT CompositorTimingHistory : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kBeginMainFrameQueueCriticalEstimateDeltaUsFieldNumber = 1,
+    kBeginMainFrameQueueNotCriticalEstimateDeltaUsFieldNumber = 2,
+    kBeginMainFrameStartToReadyToCommitEstimateDeltaUsFieldNumber = 3,
+    kCommitToReadyToActivateEstimateDeltaUsFieldNumber = 4,
+    kPrepareTilesEstimateDeltaUsFieldNumber = 5,
+    kActivateEstimateDeltaUsFieldNumber = 6,
+    kDrawEstimateDeltaUsFieldNumber = 7,
+  };
+
+  CompositorTimingHistory();
+  ~CompositorTimingHistory() override;
+  CompositorTimingHistory(CompositorTimingHistory&&) noexcept;
+  CompositorTimingHistory& operator=(CompositorTimingHistory&&);
+  CompositorTimingHistory(const CompositorTimingHistory&);
+  CompositorTimingHistory& operator=(const CompositorTimingHistory&);
+  bool operator==(const CompositorTimingHistory&) const;
+  bool operator!=(const CompositorTimingHistory& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_begin_main_frame_queue_critical_estimate_delta_us() const { return _has_field_[1]; }
+  int64_t begin_main_frame_queue_critical_estimate_delta_us() const { return begin_main_frame_queue_critical_estimate_delta_us_; }
+  void set_begin_main_frame_queue_critical_estimate_delta_us(int64_t value) { begin_main_frame_queue_critical_estimate_delta_us_ = value; _has_field_.set(1); }
+
+  bool has_begin_main_frame_queue_not_critical_estimate_delta_us() const { return _has_field_[2]; }
+  int64_t begin_main_frame_queue_not_critical_estimate_delta_us() const { return begin_main_frame_queue_not_critical_estimate_delta_us_; }
+  void set_begin_main_frame_queue_not_critical_estimate_delta_us(int64_t value) { begin_main_frame_queue_not_critical_estimate_delta_us_ = value; _has_field_.set(2); }
+
+  bool has_begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const { return _has_field_[3]; }
+  int64_t begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const { return begin_main_frame_start_to_ready_to_commit_estimate_delta_us_; }
+  void set_begin_main_frame_start_to_ready_to_commit_estimate_delta_us(int64_t value) { begin_main_frame_start_to_ready_to_commit_estimate_delta_us_ = value; _has_field_.set(3); }
+
+  bool has_commit_to_ready_to_activate_estimate_delta_us() const { return _has_field_[4]; }
+  int64_t commit_to_ready_to_activate_estimate_delta_us() const { return commit_to_ready_to_activate_estimate_delta_us_; }
+  void set_commit_to_ready_to_activate_estimate_delta_us(int64_t value) { commit_to_ready_to_activate_estimate_delta_us_ = value; _has_field_.set(4); }
+
+  bool has_prepare_tiles_estimate_delta_us() const { return _has_field_[5]; }
+  int64_t prepare_tiles_estimate_delta_us() const { return prepare_tiles_estimate_delta_us_; }
+  void set_prepare_tiles_estimate_delta_us(int64_t value) { prepare_tiles_estimate_delta_us_ = value; _has_field_.set(5); }
+
+  bool has_activate_estimate_delta_us() const { return _has_field_[6]; }
+  int64_t activate_estimate_delta_us() const { return activate_estimate_delta_us_; }
+  void set_activate_estimate_delta_us(int64_t value) { activate_estimate_delta_us_ = value; _has_field_.set(6); }
+
+  bool has_draw_estimate_delta_us() const { return _has_field_[7]; }
+  int64_t draw_estimate_delta_us() const { return draw_estimate_delta_us_; }
+  void set_draw_estimate_delta_us(int64_t value) { draw_estimate_delta_us_ = value; _has_field_.set(7); }
+
+ private:
+  int64_t begin_main_frame_queue_critical_estimate_delta_us_{};
+  int64_t begin_main_frame_queue_not_critical_estimate_delta_us_{};
+  int64_t begin_main_frame_start_to_ready_to_commit_estimate_delta_us_{};
+  int64_t commit_to_ready_to_activate_estimate_delta_us_{};
+  int64_t prepare_tiles_estimate_delta_us_{};
+  int64_t activate_estimate_delta_us_{};
+  int64_t draw_estimate_delta_us_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT BeginFrameSourceState : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSourceIdFieldNumber = 1,
+    kPausedFieldNumber = 2,
+    kNumObserversFieldNumber = 3,
+    kLastBeginFrameArgsFieldNumber = 4,
+  };
+
+  BeginFrameSourceState();
+  ~BeginFrameSourceState() override;
+  BeginFrameSourceState(BeginFrameSourceState&&) noexcept;
+  BeginFrameSourceState& operator=(BeginFrameSourceState&&);
+  BeginFrameSourceState(const BeginFrameSourceState&);
+  BeginFrameSourceState& operator=(const BeginFrameSourceState&);
+  bool operator==(const BeginFrameSourceState&) const;
+  bool operator!=(const BeginFrameSourceState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_source_id() const { return _has_field_[1]; }
+  uint32_t source_id() const { return source_id_; }
+  void set_source_id(uint32_t value) { source_id_ = value; _has_field_.set(1); }
+
+  bool has_paused() const { return _has_field_[2]; }
+  bool paused() const { return paused_; }
+  void set_paused(bool value) { paused_ = value; _has_field_.set(2); }
+
+  bool has_num_observers() const { return _has_field_[3]; }
+  uint32_t num_observers() const { return num_observers_; }
+  void set_num_observers(uint32_t value) { num_observers_ = value; _has_field_.set(3); }
+
+  bool has_last_begin_frame_args() const { return _has_field_[4]; }
+  const BeginFrameArgs& last_begin_frame_args() const { return *last_begin_frame_args_; }
+  BeginFrameArgs* mutable_last_begin_frame_args() { _has_field_.set(4); return last_begin_frame_args_.get(); }
+
+ private:
+  uint32_t source_id_{};
+  bool paused_{};
+  uint32_t num_observers_{};
+  ::protozero::CopyablePtr<BeginFrameArgs> last_begin_frame_args_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT BeginFrameArgs : public ::protozero::CppMessageObj {
+ public:
+  using BeginFrameArgsType = BeginFrameArgs_BeginFrameArgsType;
+  static constexpr auto BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
+  static constexpr auto BEGIN_FRAME_ARGS_TYPE_INVALID = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID;
+  static constexpr auto BEGIN_FRAME_ARGS_TYPE_NORMAL = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL;
+  static constexpr auto BEGIN_FRAME_ARGS_TYPE_MISSED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
+  static constexpr auto BeginFrameArgsType_MIN = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
+  static constexpr auto BeginFrameArgsType_MAX = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
+  enum FieldNumbers {
+    kTypeFieldNumber = 1,
+    kSourceIdFieldNumber = 2,
+    kSequenceNumberFieldNumber = 3,
+    kFrameTimeUsFieldNumber = 4,
+    kDeadlineUsFieldNumber = 5,
+    kIntervalDeltaUsFieldNumber = 6,
+    kOnCriticalPathFieldNumber = 7,
+    kAnimateOnlyFieldNumber = 8,
+    kSourceLocationIidFieldNumber = 9,
+    kSourceLocationFieldNumber = 10,
+    kFramesThrottledSinceLastFieldNumber = 12,
+  };
+
+  BeginFrameArgs();
+  ~BeginFrameArgs() override;
+  BeginFrameArgs(BeginFrameArgs&&) noexcept;
+  BeginFrameArgs& operator=(BeginFrameArgs&&);
+  BeginFrameArgs(const BeginFrameArgs&);
+  BeginFrameArgs& operator=(const BeginFrameArgs&);
+  bool operator==(const BeginFrameArgs&) const;
+  bool operator!=(const BeginFrameArgs& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_type() const { return _has_field_[1]; }
+  BeginFrameArgs_BeginFrameArgsType type() const { return type_; }
+  void set_type(BeginFrameArgs_BeginFrameArgsType value) { type_ = value; _has_field_.set(1); }
+
+  bool has_source_id() const { return _has_field_[2]; }
+  uint64_t source_id() const { return source_id_; }
+  void set_source_id(uint64_t value) { source_id_ = value; _has_field_.set(2); }
+
+  bool has_sequence_number() const { return _has_field_[3]; }
+  uint64_t sequence_number() const { return sequence_number_; }
+  void set_sequence_number(uint64_t value) { sequence_number_ = value; _has_field_.set(3); }
+
+  bool has_frame_time_us() const { return _has_field_[4]; }
+  int64_t frame_time_us() const { return frame_time_us_; }
+  void set_frame_time_us(int64_t value) { frame_time_us_ = value; _has_field_.set(4); }
+
+  bool has_deadline_us() const { return _has_field_[5]; }
+  int64_t deadline_us() const { return deadline_us_; }
+  void set_deadline_us(int64_t value) { deadline_us_ = value; _has_field_.set(5); }
+
+  bool has_interval_delta_us() const { return _has_field_[6]; }
+  int64_t interval_delta_us() const { return interval_delta_us_; }
+  void set_interval_delta_us(int64_t value) { interval_delta_us_ = value; _has_field_.set(6); }
+
+  bool has_on_critical_path() const { return _has_field_[7]; }
+  bool on_critical_path() const { return on_critical_path_; }
+  void set_on_critical_path(bool value) { on_critical_path_ = value; _has_field_.set(7); }
+
+  bool has_animate_only() const { return _has_field_[8]; }
+  bool animate_only() const { return animate_only_; }
+  void set_animate_only(bool value) { animate_only_ = value; _has_field_.set(8); }
+
+  bool has_source_location_iid() const { return _has_field_[9]; }
+  uint64_t source_location_iid() const { return source_location_iid_; }
+  void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(9); }
+
+  bool has_source_location() const { return _has_field_[10]; }
+  const SourceLocation& source_location() const { return *source_location_; }
+  SourceLocation* mutable_source_location() { _has_field_.set(10); return source_location_.get(); }
+
+  bool has_frames_throttled_since_last() const { return _has_field_[12]; }
+  int64_t frames_throttled_since_last() const { return frames_throttled_since_last_; }
+  void set_frames_throttled_since_last(int64_t value) { frames_throttled_since_last_ = value; _has_field_.set(12); }
+
+ private:
+  BeginFrameArgs_BeginFrameArgsType type_{};
+  uint64_t source_id_{};
+  uint64_t sequence_number_{};
+  int64_t frame_time_us_{};
+  int64_t deadline_us_{};
+  int64_t interval_delta_us_{};
+  bool on_critical_path_{};
+  bool animate_only_{};
+  uint64_t source_location_iid_{};
+  ::protozero::CopyablePtr<SourceLocation> source_location_;
+  int64_t frames_throttled_since_last_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<13> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT BeginFrameObserverState : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDroppedBeginFrameArgsFieldNumber = 1,
+    kLastBeginFrameArgsFieldNumber = 2,
+  };
+
+  BeginFrameObserverState();
+  ~BeginFrameObserverState() override;
+  BeginFrameObserverState(BeginFrameObserverState&&) noexcept;
+  BeginFrameObserverState& operator=(BeginFrameObserverState&&);
+  BeginFrameObserverState(const BeginFrameObserverState&);
+  BeginFrameObserverState& operator=(const BeginFrameObserverState&);
+  bool operator==(const BeginFrameObserverState&) const;
+  bool operator!=(const BeginFrameObserverState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_dropped_begin_frame_args() const { return _has_field_[1]; }
+  int64_t dropped_begin_frame_args() const { return dropped_begin_frame_args_; }
+  void set_dropped_begin_frame_args(int64_t value) { dropped_begin_frame_args_ = value; _has_field_.set(1); }
+
+  bool has_last_begin_frame_args() const { return _has_field_[2]; }
+  const BeginFrameArgs& last_begin_frame_args() const { return *last_begin_frame_args_; }
+  BeginFrameArgs* mutable_last_begin_frame_args() { _has_field_.set(2); return last_begin_frame_args_.get(); }
+
+ private:
+  int64_t dropped_begin_frame_args_{};
+  ::protozero::CopyablePtr<BeginFrameArgs> last_begin_frame_args_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT BeginImplFrameArgs : public ::protozero::CppMessageObj {
+ public:
+  using TimestampsInUs = BeginImplFrameArgs_TimestampsInUs;
+  using State = BeginImplFrameArgs_State;
+  static constexpr auto BEGIN_FRAME_FINISHED = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
+  static constexpr auto BEGIN_FRAME_USING = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
+  static constexpr auto State_MIN = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
+  static constexpr auto State_MAX = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
+  enum FieldNumbers {
+    kUpdatedAtUsFieldNumber = 1,
+    kFinishedAtUsFieldNumber = 2,
+    kStateFieldNumber = 3,
+    kCurrentArgsFieldNumber = 4,
+    kLastArgsFieldNumber = 5,
+    kTimestampsInUsFieldNumber = 6,
+  };
+
+  BeginImplFrameArgs();
+  ~BeginImplFrameArgs() override;
+  BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept;
+  BeginImplFrameArgs& operator=(BeginImplFrameArgs&&);
+  BeginImplFrameArgs(const BeginImplFrameArgs&);
+  BeginImplFrameArgs& operator=(const BeginImplFrameArgs&);
+  bool operator==(const BeginImplFrameArgs&) const;
+  bool operator!=(const BeginImplFrameArgs& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_updated_at_us() const { return _has_field_[1]; }
+  int64_t updated_at_us() const { return updated_at_us_; }
+  void set_updated_at_us(int64_t value) { updated_at_us_ = value; _has_field_.set(1); }
+
+  bool has_finished_at_us() const { return _has_field_[2]; }
+  int64_t finished_at_us() const { return finished_at_us_; }
+  void set_finished_at_us(int64_t value) { finished_at_us_ = value; _has_field_.set(2); }
+
+  bool has_state() const { return _has_field_[3]; }
+  BeginImplFrameArgs_State state() const { return state_; }
+  void set_state(BeginImplFrameArgs_State value) { state_ = value; _has_field_.set(3); }
+
+  bool has_current_args() const { return _has_field_[4]; }
+  const BeginFrameArgs& current_args() const { return *current_args_; }
+  BeginFrameArgs* mutable_current_args() { _has_field_.set(4); return current_args_.get(); }
+
+  bool has_last_args() const { return _has_field_[5]; }
+  const BeginFrameArgs& last_args() const { return *last_args_; }
+  BeginFrameArgs* mutable_last_args() { _has_field_.set(5); return last_args_.get(); }
+
+  bool has_timestamps_in_us() const { return _has_field_[6]; }
+  const BeginImplFrameArgs_TimestampsInUs& timestamps_in_us() const { return *timestamps_in_us_; }
+  BeginImplFrameArgs_TimestampsInUs* mutable_timestamps_in_us() { _has_field_.set(6); return timestamps_in_us_.get(); }
+
+ private:
+  int64_t updated_at_us_{};
+  int64_t finished_at_us_{};
+  BeginImplFrameArgs_State state_{};
+  ::protozero::CopyablePtr<BeginFrameArgs> current_args_;
+  ::protozero::CopyablePtr<BeginFrameArgs> last_args_;
+  ::protozero::CopyablePtr<BeginImplFrameArgs_TimestampsInUs> timestamps_in_us_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<7> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT BeginImplFrameArgs_TimestampsInUs : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIntervalDeltaFieldNumber = 1,
+    kNowToDeadlineDeltaFieldNumber = 2,
+    kFrameTimeToNowDeltaFieldNumber = 3,
+    kFrameTimeToDeadlineDeltaFieldNumber = 4,
+    kNowFieldNumber = 5,
+    kFrameTimeFieldNumber = 6,
+    kDeadlineFieldNumber = 7,
+  };
+
+  BeginImplFrameArgs_TimestampsInUs();
+  ~BeginImplFrameArgs_TimestampsInUs() override;
+  BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept;
+  BeginImplFrameArgs_TimestampsInUs& operator=(BeginImplFrameArgs_TimestampsInUs&&);
+  BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&);
+  BeginImplFrameArgs_TimestampsInUs& operator=(const BeginImplFrameArgs_TimestampsInUs&);
+  bool operator==(const BeginImplFrameArgs_TimestampsInUs&) const;
+  bool operator!=(const BeginImplFrameArgs_TimestampsInUs& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_interval_delta() const { return _has_field_[1]; }
+  int64_t interval_delta() const { return interval_delta_; }
+  void set_interval_delta(int64_t value) { interval_delta_ = value; _has_field_.set(1); }
+
+  bool has_now_to_deadline_delta() const { return _has_field_[2]; }
+  int64_t now_to_deadline_delta() const { return now_to_deadline_delta_; }
+  void set_now_to_deadline_delta(int64_t value) { now_to_deadline_delta_ = value; _has_field_.set(2); }
+
+  bool has_frame_time_to_now_delta() const { return _has_field_[3]; }
+  int64_t frame_time_to_now_delta() const { return frame_time_to_now_delta_; }
+  void set_frame_time_to_now_delta(int64_t value) { frame_time_to_now_delta_ = value; _has_field_.set(3); }
+
+  bool has_frame_time_to_deadline_delta() const { return _has_field_[4]; }
+  int64_t frame_time_to_deadline_delta() const { return frame_time_to_deadline_delta_; }
+  void set_frame_time_to_deadline_delta(int64_t value) { frame_time_to_deadline_delta_ = value; _has_field_.set(4); }
+
+  bool has_now() const { return _has_field_[5]; }
+  int64_t now() const { return now_; }
+  void set_now(int64_t value) { now_ = value; _has_field_.set(5); }
+
+  bool has_frame_time() const { return _has_field_[6]; }
+  int64_t frame_time() const { return frame_time_; }
+  void set_frame_time(int64_t value) { frame_time_ = value; _has_field_.set(6); }
+
+  bool has_deadline() const { return _has_field_[7]; }
+  int64_t deadline() const { return deadline_; }
+  void set_deadline(int64_t value) { deadline_ = value; _has_field_.set(7); }
+
+ private:
+  int64_t interval_delta_{};
+  int64_t now_to_deadline_delta_{};
+  int64_t frame_time_to_now_delta_{};
+  int64_t frame_time_to_deadline_delta_{};
+  int64_t now_{};
+  int64_t frame_time_{};
+  int64_t deadline_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeCompositorStateMachine : public ::protozero::CppMessageObj {
+ public:
+  using MajorState = ChromeCompositorStateMachine_MajorState;
+  using MinorState = ChromeCompositorStateMachine_MinorState;
+  enum FieldNumbers {
+    kMajorStateFieldNumber = 1,
+    kMinorStateFieldNumber = 2,
+  };
+
+  ChromeCompositorStateMachine();
+  ~ChromeCompositorStateMachine() override;
+  ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept;
+  ChromeCompositorStateMachine& operator=(ChromeCompositorStateMachine&&);
+  ChromeCompositorStateMachine(const ChromeCompositorStateMachine&);
+  ChromeCompositorStateMachine& operator=(const ChromeCompositorStateMachine&);
+  bool operator==(const ChromeCompositorStateMachine&) const;
+  bool operator!=(const ChromeCompositorStateMachine& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_major_state() const { return _has_field_[1]; }
+  const ChromeCompositorStateMachine_MajorState& major_state() const { return *major_state_; }
+  ChromeCompositorStateMachine_MajorState* mutable_major_state() { _has_field_.set(1); return major_state_.get(); }
+
+  bool has_minor_state() const { return _has_field_[2]; }
+  const ChromeCompositorStateMachine_MinorState& minor_state() const { return *minor_state_; }
+  ChromeCompositorStateMachine_MinorState* mutable_minor_state() { _has_field_.set(2); return minor_state_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<ChromeCompositorStateMachine_MajorState> major_state_;
+  ::protozero::CopyablePtr<ChromeCompositorStateMachine_MinorState> minor_state_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeCompositorStateMachine_MinorState : public ::protozero::CppMessageObj {
+ public:
+  using TreePriority = ChromeCompositorStateMachine_MinorState_TreePriority;
+  static constexpr auto TREE_PRIORITY_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
+  static constexpr auto TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES;
+  static constexpr auto TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY;
+  static constexpr auto TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+  static constexpr auto TreePriority_MIN = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
+  static constexpr auto TreePriority_MAX = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+  using ScrollHandlerState = ChromeCompositorStateMachine_MinorState_ScrollHandlerState;
+  static constexpr auto SCROLL_HANDLER_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
+  static constexpr auto SCROLL_AFFECTS_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER;
+  static constexpr auto SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
+  static constexpr auto ScrollHandlerState_MIN = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
+  static constexpr auto ScrollHandlerState_MAX = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
+  enum FieldNumbers {
+    kCommitCountFieldNumber = 1,
+    kCurrentFrameNumberFieldNumber = 2,
+    kLastFrameNumberSubmitPerformedFieldNumber = 3,
+    kLastFrameNumberDrawPerformedFieldNumber = 4,
+    kLastFrameNumberBeginMainFrameSentFieldNumber = 5,
+    kDidDrawFieldNumber = 6,
+    kDidSendBeginMainFrameForCurrentFrameFieldNumber = 7,
+    kDidNotifyBeginMainFrameNotExpectedUntilFieldNumber = 8,
+    kDidNotifyBeginMainFrameNotExpectedSoonFieldNumber = 9,
+    kWantsBeginMainFrameNotExpectedFieldNumber = 10,
+    kDidCommitDuringFrameFieldNumber = 11,
+    kDidInvalidateLayerTreeFrameSinkFieldNumber = 12,
+    kDidPerformImplSideInvalidaionFieldNumber = 13,
+    kDidPrepareTilesFieldNumber = 14,
+    kConsecutiveCheckerboardAnimationsFieldNumber = 15,
+    kPendingSubmitFramesFieldNumber = 16,
+    kSubmitFramesWithCurrentLayerTreeFrameSinkFieldNumber = 17,
+    kNeedsRedrawFieldNumber = 18,
+    kNeedsPrepareTilesFieldNumber = 19,
+    kNeedsBeginMainFrameFieldNumber = 20,
+    kNeedsOneBeginImplFrameFieldNumber = 21,
+    kVisibleFieldNumber = 22,
+    kBeginFrameSourcePausedFieldNumber = 23,
+    kCanDrawFieldNumber = 24,
+    kResourcelessDrawFieldNumber = 25,
+    kHasPendingTreeFieldNumber = 26,
+    kPendingTreeIsReadyForActivationFieldNumber = 27,
+    kActiveTreeNeedsFirstDrawFieldNumber = 28,
+    kActiveTreeIsReadyToDrawFieldNumber = 29,
+    kDidCreateAndInitializeFirstLayerTreeFrameSinkFieldNumber = 30,
+    kTreePriorityFieldNumber = 31,
+    kScrollHandlerStateFieldNumber = 32,
+    kCriticalBeginMainFrameToActivateIsFastFieldNumber = 33,
+    kMainThreadMissedLastDeadlineFieldNumber = 34,
+    kVideoNeedsBeginFramesFieldNumber = 36,
+    kDeferBeginMainFrameFieldNumber = 37,
+    kLastCommitHadNoUpdatesFieldNumber = 38,
+    kDidDrawInLastFrameFieldNumber = 39,
+    kDidSubmitInLastFrameFieldNumber = 40,
+    kNeedsImplSideInvalidationFieldNumber = 41,
+    kCurrentPendingTreeIsImplSideFieldNumber = 42,
+    kPreviousPendingTreeWasImplSideFieldNumber = 43,
+    kProcessingAnimationWorkletsForActiveTreeFieldNumber = 44,
+    kProcessingAnimationWorkletsForPendingTreeFieldNumber = 45,
+    kProcessingPaintWorkletsForPendingTreeFieldNumber = 46,
+  };
+
+  ChromeCompositorStateMachine_MinorState();
+  ~ChromeCompositorStateMachine_MinorState() override;
+  ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept;
+  ChromeCompositorStateMachine_MinorState& operator=(ChromeCompositorStateMachine_MinorState&&);
+  ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&);
+  ChromeCompositorStateMachine_MinorState& operator=(const ChromeCompositorStateMachine_MinorState&);
+  bool operator==(const ChromeCompositorStateMachine_MinorState&) const;
+  bool operator!=(const ChromeCompositorStateMachine_MinorState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_commit_count() const { return _has_field_[1]; }
+  int32_t commit_count() const { return commit_count_; }
+  void set_commit_count(int32_t value) { commit_count_ = value; _has_field_.set(1); }
+
+  bool has_current_frame_number() const { return _has_field_[2]; }
+  int32_t current_frame_number() const { return current_frame_number_; }
+  void set_current_frame_number(int32_t value) { current_frame_number_ = value; _has_field_.set(2); }
+
+  bool has_last_frame_number_submit_performed() const { return _has_field_[3]; }
+  int32_t last_frame_number_submit_performed() const { return last_frame_number_submit_performed_; }
+  void set_last_frame_number_submit_performed(int32_t value) { last_frame_number_submit_performed_ = value; _has_field_.set(3); }
+
+  bool has_last_frame_number_draw_performed() const { return _has_field_[4]; }
+  int32_t last_frame_number_draw_performed() const { return last_frame_number_draw_performed_; }
+  void set_last_frame_number_draw_performed(int32_t value) { last_frame_number_draw_performed_ = value; _has_field_.set(4); }
+
+  bool has_last_frame_number_begin_main_frame_sent() const { return _has_field_[5]; }
+  int32_t last_frame_number_begin_main_frame_sent() const { return last_frame_number_begin_main_frame_sent_; }
+  void set_last_frame_number_begin_main_frame_sent(int32_t value) { last_frame_number_begin_main_frame_sent_ = value; _has_field_.set(5); }
+
+  bool has_did_draw() const { return _has_field_[6]; }
+  bool did_draw() const { return did_draw_; }
+  void set_did_draw(bool value) { did_draw_ = value; _has_field_.set(6); }
+
+  bool has_did_send_begin_main_frame_for_current_frame() const { return _has_field_[7]; }
+  bool did_send_begin_main_frame_for_current_frame() const { return did_send_begin_main_frame_for_current_frame_; }
+  void set_did_send_begin_main_frame_for_current_frame(bool value) { did_send_begin_main_frame_for_current_frame_ = value; _has_field_.set(7); }
+
+  bool has_did_notify_begin_main_frame_not_expected_until() const { return _has_field_[8]; }
+  bool did_notify_begin_main_frame_not_expected_until() const { return did_notify_begin_main_frame_not_expected_until_; }
+  void set_did_notify_begin_main_frame_not_expected_until(bool value) { did_notify_begin_main_frame_not_expected_until_ = value; _has_field_.set(8); }
+
+  bool has_did_notify_begin_main_frame_not_expected_soon() const { return _has_field_[9]; }
+  bool did_notify_begin_main_frame_not_expected_soon() const { return did_notify_begin_main_frame_not_expected_soon_; }
+  void set_did_notify_begin_main_frame_not_expected_soon(bool value) { did_notify_begin_main_frame_not_expected_soon_ = value; _has_field_.set(9); }
+
+  bool has_wants_begin_main_frame_not_expected() const { return _has_field_[10]; }
+  bool wants_begin_main_frame_not_expected() const { return wants_begin_main_frame_not_expected_; }
+  void set_wants_begin_main_frame_not_expected(bool value) { wants_begin_main_frame_not_expected_ = value; _has_field_.set(10); }
+
+  bool has_did_commit_during_frame() const { return _has_field_[11]; }
+  bool did_commit_during_frame() const { return did_commit_during_frame_; }
+  void set_did_commit_during_frame(bool value) { did_commit_during_frame_ = value; _has_field_.set(11); }
+
+  bool has_did_invalidate_layer_tree_frame_sink() const { return _has_field_[12]; }
+  bool did_invalidate_layer_tree_frame_sink() const { return did_invalidate_layer_tree_frame_sink_; }
+  void set_did_invalidate_layer_tree_frame_sink(bool value) { did_invalidate_layer_tree_frame_sink_ = value; _has_field_.set(12); }
+
+  bool has_did_perform_impl_side_invalidaion() const { return _has_field_[13]; }
+  bool did_perform_impl_side_invalidaion() const { return did_perform_impl_side_invalidaion_; }
+  void set_did_perform_impl_side_invalidaion(bool value) { did_perform_impl_side_invalidaion_ = value; _has_field_.set(13); }
+
+  bool has_did_prepare_tiles() const { return _has_field_[14]; }
+  bool did_prepare_tiles() const { return did_prepare_tiles_; }
+  void set_did_prepare_tiles(bool value) { did_prepare_tiles_ = value; _has_field_.set(14); }
+
+  bool has_consecutive_checkerboard_animations() const { return _has_field_[15]; }
+  int32_t consecutive_checkerboard_animations() const { return consecutive_checkerboard_animations_; }
+  void set_consecutive_checkerboard_animations(int32_t value) { consecutive_checkerboard_animations_ = value; _has_field_.set(15); }
+
+  bool has_pending_submit_frames() const { return _has_field_[16]; }
+  int32_t pending_submit_frames() const { return pending_submit_frames_; }
+  void set_pending_submit_frames(int32_t value) { pending_submit_frames_ = value; _has_field_.set(16); }
+
+  bool has_submit_frames_with_current_layer_tree_frame_sink() const { return _has_field_[17]; }
+  int32_t submit_frames_with_current_layer_tree_frame_sink() const { return submit_frames_with_current_layer_tree_frame_sink_; }
+  void set_submit_frames_with_current_layer_tree_frame_sink(int32_t value) { submit_frames_with_current_layer_tree_frame_sink_ = value; _has_field_.set(17); }
+
+  bool has_needs_redraw() const { return _has_field_[18]; }
+  bool needs_redraw() const { return needs_redraw_; }
+  void set_needs_redraw(bool value) { needs_redraw_ = value; _has_field_.set(18); }
+
+  bool has_needs_prepare_tiles() const { return _has_field_[19]; }
+  bool needs_prepare_tiles() const { return needs_prepare_tiles_; }
+  void set_needs_prepare_tiles(bool value) { needs_prepare_tiles_ = value; _has_field_.set(19); }
+
+  bool has_needs_begin_main_frame() const { return _has_field_[20]; }
+  bool needs_begin_main_frame() const { return needs_begin_main_frame_; }
+  void set_needs_begin_main_frame(bool value) { needs_begin_main_frame_ = value; _has_field_.set(20); }
+
+  bool has_needs_one_begin_impl_frame() const { return _has_field_[21]; }
+  bool needs_one_begin_impl_frame() const { return needs_one_begin_impl_frame_; }
+  void set_needs_one_begin_impl_frame(bool value) { needs_one_begin_impl_frame_ = value; _has_field_.set(21); }
+
+  bool has_visible() const { return _has_field_[22]; }
+  bool visible() const { return visible_; }
+  void set_visible(bool value) { visible_ = value; _has_field_.set(22); }
+
+  bool has_begin_frame_source_paused() const { return _has_field_[23]; }
+  bool begin_frame_source_paused() const { return begin_frame_source_paused_; }
+  void set_begin_frame_source_paused(bool value) { begin_frame_source_paused_ = value; _has_field_.set(23); }
+
+  bool has_can_draw() const { return _has_field_[24]; }
+  bool can_draw() const { return can_draw_; }
+  void set_can_draw(bool value) { can_draw_ = value; _has_field_.set(24); }
+
+  bool has_resourceless_draw() const { return _has_field_[25]; }
+  bool resourceless_draw() const { return resourceless_draw_; }
+  void set_resourceless_draw(bool value) { resourceless_draw_ = value; _has_field_.set(25); }
+
+  bool has_has_pending_tree() const { return _has_field_[26]; }
+  bool has_pending_tree() const { return has_pending_tree_; }
+  void set_has_pending_tree(bool value) { has_pending_tree_ = value; _has_field_.set(26); }
+
+  bool has_pending_tree_is_ready_for_activation() const { return _has_field_[27]; }
+  bool pending_tree_is_ready_for_activation() const { return pending_tree_is_ready_for_activation_; }
+  void set_pending_tree_is_ready_for_activation(bool value) { pending_tree_is_ready_for_activation_ = value; _has_field_.set(27); }
+
+  bool has_active_tree_needs_first_draw() const { return _has_field_[28]; }
+  bool active_tree_needs_first_draw() const { return active_tree_needs_first_draw_; }
+  void set_active_tree_needs_first_draw(bool value) { active_tree_needs_first_draw_ = value; _has_field_.set(28); }
+
+  bool has_active_tree_is_ready_to_draw() const { return _has_field_[29]; }
+  bool active_tree_is_ready_to_draw() const { return active_tree_is_ready_to_draw_; }
+  void set_active_tree_is_ready_to_draw(bool value) { active_tree_is_ready_to_draw_ = value; _has_field_.set(29); }
+
+  bool has_did_create_and_initialize_first_layer_tree_frame_sink() const { return _has_field_[30]; }
+  bool did_create_and_initialize_first_layer_tree_frame_sink() const { return did_create_and_initialize_first_layer_tree_frame_sink_; }
+  void set_did_create_and_initialize_first_layer_tree_frame_sink(bool value) { did_create_and_initialize_first_layer_tree_frame_sink_ = value; _has_field_.set(30); }
+
+  bool has_tree_priority() const { return _has_field_[31]; }
+  ChromeCompositorStateMachine_MinorState_TreePriority tree_priority() const { return tree_priority_; }
+  void set_tree_priority(ChromeCompositorStateMachine_MinorState_TreePriority value) { tree_priority_ = value; _has_field_.set(31); }
+
+  bool has_scroll_handler_state() const { return _has_field_[32]; }
+  ChromeCompositorStateMachine_MinorState_ScrollHandlerState scroll_handler_state() const { return scroll_handler_state_; }
+  void set_scroll_handler_state(ChromeCompositorStateMachine_MinorState_ScrollHandlerState value) { scroll_handler_state_ = value; _has_field_.set(32); }
+
+  bool has_critical_begin_main_frame_to_activate_is_fast() const { return _has_field_[33]; }
+  bool critical_begin_main_frame_to_activate_is_fast() const { return critical_begin_main_frame_to_activate_is_fast_; }
+  void set_critical_begin_main_frame_to_activate_is_fast(bool value) { critical_begin_main_frame_to_activate_is_fast_ = value; _has_field_.set(33); }
+
+  bool has_main_thread_missed_last_deadline() const { return _has_field_[34]; }
+  bool main_thread_missed_last_deadline() const { return main_thread_missed_last_deadline_; }
+  void set_main_thread_missed_last_deadline(bool value) { main_thread_missed_last_deadline_ = value; _has_field_.set(34); }
+
+  bool has_video_needs_begin_frames() const { return _has_field_[36]; }
+  bool video_needs_begin_frames() const { return video_needs_begin_frames_; }
+  void set_video_needs_begin_frames(bool value) { video_needs_begin_frames_ = value; _has_field_.set(36); }
+
+  bool has_defer_begin_main_frame() const { return _has_field_[37]; }
+  bool defer_begin_main_frame() const { return defer_begin_main_frame_; }
+  void set_defer_begin_main_frame(bool value) { defer_begin_main_frame_ = value; _has_field_.set(37); }
+
+  bool has_last_commit_had_no_updates() const { return _has_field_[38]; }
+  bool last_commit_had_no_updates() const { return last_commit_had_no_updates_; }
+  void set_last_commit_had_no_updates(bool value) { last_commit_had_no_updates_ = value; _has_field_.set(38); }
+
+  bool has_did_draw_in_last_frame() const { return _has_field_[39]; }
+  bool did_draw_in_last_frame() const { return did_draw_in_last_frame_; }
+  void set_did_draw_in_last_frame(bool value) { did_draw_in_last_frame_ = value; _has_field_.set(39); }
+
+  bool has_did_submit_in_last_frame() const { return _has_field_[40]; }
+  bool did_submit_in_last_frame() const { return did_submit_in_last_frame_; }
+  void set_did_submit_in_last_frame(bool value) { did_submit_in_last_frame_ = value; _has_field_.set(40); }
+
+  bool has_needs_impl_side_invalidation() const { return _has_field_[41]; }
+  bool needs_impl_side_invalidation() const { return needs_impl_side_invalidation_; }
+  void set_needs_impl_side_invalidation(bool value) { needs_impl_side_invalidation_ = value; _has_field_.set(41); }
+
+  bool has_current_pending_tree_is_impl_side() const { return _has_field_[42]; }
+  bool current_pending_tree_is_impl_side() const { return current_pending_tree_is_impl_side_; }
+  void set_current_pending_tree_is_impl_side(bool value) { current_pending_tree_is_impl_side_ = value; _has_field_.set(42); }
+
+  bool has_previous_pending_tree_was_impl_side() const { return _has_field_[43]; }
+  bool previous_pending_tree_was_impl_side() const { return previous_pending_tree_was_impl_side_; }
+  void set_previous_pending_tree_was_impl_side(bool value) { previous_pending_tree_was_impl_side_ = value; _has_field_.set(43); }
+
+  bool has_processing_animation_worklets_for_active_tree() const { return _has_field_[44]; }
+  bool processing_animation_worklets_for_active_tree() const { return processing_animation_worklets_for_active_tree_; }
+  void set_processing_animation_worklets_for_active_tree(bool value) { processing_animation_worklets_for_active_tree_ = value; _has_field_.set(44); }
+
+  bool has_processing_animation_worklets_for_pending_tree() const { return _has_field_[45]; }
+  bool processing_animation_worklets_for_pending_tree() const { return processing_animation_worklets_for_pending_tree_; }
+  void set_processing_animation_worklets_for_pending_tree(bool value) { processing_animation_worklets_for_pending_tree_ = value; _has_field_.set(45); }
+
+  bool has_processing_paint_worklets_for_pending_tree() const { return _has_field_[46]; }
+  bool processing_paint_worklets_for_pending_tree() const { return processing_paint_worklets_for_pending_tree_; }
+  void set_processing_paint_worklets_for_pending_tree(bool value) { processing_paint_worklets_for_pending_tree_ = value; _has_field_.set(46); }
+
+ private:
+  int32_t commit_count_{};
+  int32_t current_frame_number_{};
+  int32_t last_frame_number_submit_performed_{};
+  int32_t last_frame_number_draw_performed_{};
+  int32_t last_frame_number_begin_main_frame_sent_{};
+  bool did_draw_{};
+  bool did_send_begin_main_frame_for_current_frame_{};
+  bool did_notify_begin_main_frame_not_expected_until_{};
+  bool did_notify_begin_main_frame_not_expected_soon_{};
+  bool wants_begin_main_frame_not_expected_{};
+  bool did_commit_during_frame_{};
+  bool did_invalidate_layer_tree_frame_sink_{};
+  bool did_perform_impl_side_invalidaion_{};
+  bool did_prepare_tiles_{};
+  int32_t consecutive_checkerboard_animations_{};
+  int32_t pending_submit_frames_{};
+  int32_t submit_frames_with_current_layer_tree_frame_sink_{};
+  bool needs_redraw_{};
+  bool needs_prepare_tiles_{};
+  bool needs_begin_main_frame_{};
+  bool needs_one_begin_impl_frame_{};
+  bool visible_{};
+  bool begin_frame_source_paused_{};
+  bool can_draw_{};
+  bool resourceless_draw_{};
+  bool has_pending_tree_{};
+  bool pending_tree_is_ready_for_activation_{};
+  bool active_tree_needs_first_draw_{};
+  bool active_tree_is_ready_to_draw_{};
+  bool did_create_and_initialize_first_layer_tree_frame_sink_{};
+  ChromeCompositorStateMachine_MinorState_TreePriority tree_priority_{};
+  ChromeCompositorStateMachine_MinorState_ScrollHandlerState scroll_handler_state_{};
+  bool critical_begin_main_frame_to_activate_is_fast_{};
+  bool main_thread_missed_last_deadline_{};
+  bool video_needs_begin_frames_{};
+  bool defer_begin_main_frame_{};
+  bool last_commit_had_no_updates_{};
+  bool did_draw_in_last_frame_{};
+  bool did_submit_in_last_frame_{};
+  bool needs_impl_side_invalidation_{};
+  bool current_pending_tree_is_impl_side_{};
+  bool previous_pending_tree_was_impl_side_{};
+  bool processing_animation_worklets_for_active_tree_{};
+  bool processing_animation_worklets_for_pending_tree_{};
+  bool processing_paint_worklets_for_pending_tree_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<47> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeCompositorStateMachine_MajorState : public ::protozero::CppMessageObj {
+ public:
+  using BeginImplFrameState = ChromeCompositorStateMachine_MajorState_BeginImplFrameState;
+  static constexpr auto BEGIN_IMPL_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
+  static constexpr auto BEGIN_IMPL_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE;
+  static constexpr auto BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME;
+  static constexpr auto BEGIN_IMPL_FRAME_INSIDE_DEADLINE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
+  static constexpr auto BeginImplFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
+  static constexpr auto BeginImplFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
+  using BeginMainFrameState = ChromeCompositorStateMachine_MajorState_BeginMainFrameState;
+  static constexpr auto BEGIN_MAIN_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
+  static constexpr auto BEGIN_MAIN_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE;
+  static constexpr auto BEGIN_MAIN_FRAME_SENT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT;
+  static constexpr auto BEGIN_MAIN_FRAME_READY_TO_COMMIT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
+  static constexpr auto BeginMainFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
+  static constexpr auto BeginMainFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
+  using LayerTreeFrameSinkState = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState;
+  static constexpr auto LAYER_TREE_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
+  static constexpr auto LAYER_TREE_FRAME_NONE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE;
+  static constexpr auto LAYER_TREE_FRAME_ACTIVE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE;
+  static constexpr auto LAYER_TREE_FRAME_CREATING = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING;
+  static constexpr auto LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT;
+  static constexpr auto LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
+  static constexpr auto LayerTreeFrameSinkState_MIN = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
+  static constexpr auto LayerTreeFrameSinkState_MAX = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
+  using ForcedRedrawOnTimeoutState = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState;
+  static constexpr auto FORCED_REDRAW_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
+  static constexpr auto FORCED_REDRAW_IDLE = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE;
+  static constexpr auto FORCED_REDRAW_WAITING_FOR_COMMIT = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT;
+  static constexpr auto FORCED_REDRAW_WAITING_FOR_ACTIVATION = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION;
+  static constexpr auto FORCED_REDRAW_WAITING_FOR_DRAW = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
+  static constexpr auto ForcedRedrawOnTimeoutState_MIN = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
+  static constexpr auto ForcedRedrawOnTimeoutState_MAX = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
+  enum FieldNumbers {
+    kNextActionFieldNumber = 1,
+    kBeginImplFrameStateFieldNumber = 2,
+    kBeginMainFrameStateFieldNumber = 3,
+    kLayerTreeFrameSinkStateFieldNumber = 4,
+    kForcedRedrawStateFieldNumber = 5,
+  };
+
+  ChromeCompositorStateMachine_MajorState();
+  ~ChromeCompositorStateMachine_MajorState() override;
+  ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept;
+  ChromeCompositorStateMachine_MajorState& operator=(ChromeCompositorStateMachine_MajorState&&);
+  ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&);
+  ChromeCompositorStateMachine_MajorState& operator=(const ChromeCompositorStateMachine_MajorState&);
+  bool operator==(const ChromeCompositorStateMachine_MajorState&) const;
+  bool operator!=(const ChromeCompositorStateMachine_MajorState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_next_action() const { return _has_field_[1]; }
+  ChromeCompositorSchedulerAction next_action() const { return next_action_; }
+  void set_next_action(ChromeCompositorSchedulerAction value) { next_action_ = value; _has_field_.set(1); }
+
+  bool has_begin_impl_frame_state() const { return _has_field_[2]; }
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState begin_impl_frame_state() const { return begin_impl_frame_state_; }
+  void set_begin_impl_frame_state(ChromeCompositorStateMachine_MajorState_BeginImplFrameState value) { begin_impl_frame_state_ = value; _has_field_.set(2); }
+
+  bool has_begin_main_frame_state() const { return _has_field_[3]; }
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState begin_main_frame_state() const { return begin_main_frame_state_; }
+  void set_begin_main_frame_state(ChromeCompositorStateMachine_MajorState_BeginMainFrameState value) { begin_main_frame_state_ = value; _has_field_.set(3); }
+
+  bool has_layer_tree_frame_sink_state() const { return _has_field_[4]; }
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState layer_tree_frame_sink_state() const { return layer_tree_frame_sink_state_; }
+  void set_layer_tree_frame_sink_state(ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState value) { layer_tree_frame_sink_state_ = value; _has_field_.set(4); }
+
+  bool has_forced_redraw_state() const { return _has_field_[5]; }
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState forced_redraw_state() const { return forced_redraw_state_; }
+  void set_forced_redraw_state(ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value) { forced_redraw_state_ = value; _has_field_.set(5); }
+
+ private:
+  ChromeCompositorSchedulerAction next_action_{};
+  ChromeCompositorStateMachine_MajorState_BeginImplFrameState begin_impl_frame_state_{};
+  ChromeCompositorStateMachine_MajorState_BeginMainFrameState begin_main_frame_state_{};
+  ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState layer_tree_frame_sink_state_{};
+  ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState forced_redraw_state_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeCompositorSchedulerState : public ::protozero::CppMessageObj {
+ public:
+  using BeginImplFrameDeadlineMode = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode;
+  static constexpr auto DEADLINE_MODE_UNSPECIFIED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
+  static constexpr auto DEADLINE_MODE_NONE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE;
+  static constexpr auto DEADLINE_MODE_IMMEDIATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE;
+  static constexpr auto DEADLINE_MODE_REGULAR = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR;
+  static constexpr auto DEADLINE_MODE_LATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE;
+  static constexpr auto DEADLINE_MODE_BLOCKED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
+  static constexpr auto BeginImplFrameDeadlineMode_MIN = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
+  static constexpr auto BeginImplFrameDeadlineMode_MAX = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
+  enum FieldNumbers {
+    kStateMachineFieldNumber = 1,
+    kObservingBeginFrameSourceFieldNumber = 2,
+    kBeginImplFrameDeadlineTaskFieldNumber = 3,
+    kPendingBeginFrameTaskFieldNumber = 4,
+    kSkippedLastFrameMissedExceededDeadlineFieldNumber = 5,
+    kInsideActionFieldNumber = 7,
+    kDeadlineModeFieldNumber = 8,
+    kDeadlineUsFieldNumber = 9,
+    kDeadlineScheduledAtUsFieldNumber = 10,
+    kNowUsFieldNumber = 11,
+    kNowToDeadlineDeltaUsFieldNumber = 12,
+    kNowToDeadlineScheduledAtDeltaUsFieldNumber = 13,
+    kBeginImplFrameArgsFieldNumber = 14,
+    kBeginFrameObserverStateFieldNumber = 15,
+    kBeginFrameSourceStateFieldNumber = 16,
+    kCompositorTimingHistoryFieldNumber = 17,
+  };
+
+  ChromeCompositorSchedulerState();
+  ~ChromeCompositorSchedulerState() override;
+  ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept;
+  ChromeCompositorSchedulerState& operator=(ChromeCompositorSchedulerState&&);
+  ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&);
+  ChromeCompositorSchedulerState& operator=(const ChromeCompositorSchedulerState&);
+  bool operator==(const ChromeCompositorSchedulerState&) const;
+  bool operator!=(const ChromeCompositorSchedulerState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_state_machine() const { return _has_field_[1]; }
+  const ChromeCompositorStateMachine& state_machine() const { return *state_machine_; }
+  ChromeCompositorStateMachine* mutable_state_machine() { _has_field_.set(1); return state_machine_.get(); }
+
+  bool has_observing_begin_frame_source() const { return _has_field_[2]; }
+  bool observing_begin_frame_source() const { return observing_begin_frame_source_; }
+  void set_observing_begin_frame_source(bool value) { observing_begin_frame_source_ = value; _has_field_.set(2); }
+
+  bool has_begin_impl_frame_deadline_task() const { return _has_field_[3]; }
+  bool begin_impl_frame_deadline_task() const { return begin_impl_frame_deadline_task_; }
+  void set_begin_impl_frame_deadline_task(bool value) { begin_impl_frame_deadline_task_ = value; _has_field_.set(3); }
+
+  bool has_pending_begin_frame_task() const { return _has_field_[4]; }
+  bool pending_begin_frame_task() const { return pending_begin_frame_task_; }
+  void set_pending_begin_frame_task(bool value) { pending_begin_frame_task_ = value; _has_field_.set(4); }
+
+  bool has_skipped_last_frame_missed_exceeded_deadline() const { return _has_field_[5]; }
+  bool skipped_last_frame_missed_exceeded_deadline() const { return skipped_last_frame_missed_exceeded_deadline_; }
+  void set_skipped_last_frame_missed_exceeded_deadline(bool value) { skipped_last_frame_missed_exceeded_deadline_ = value; _has_field_.set(5); }
+
+  bool has_inside_action() const { return _has_field_[7]; }
+  ChromeCompositorSchedulerAction inside_action() const { return inside_action_; }
+  void set_inside_action(ChromeCompositorSchedulerAction value) { inside_action_ = value; _has_field_.set(7); }
+
+  bool has_deadline_mode() const { return _has_field_[8]; }
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode deadline_mode() const { return deadline_mode_; }
+  void set_deadline_mode(ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value) { deadline_mode_ = value; _has_field_.set(8); }
+
+  bool has_deadline_us() const { return _has_field_[9]; }
+  int64_t deadline_us() const { return deadline_us_; }
+  void set_deadline_us(int64_t value) { deadline_us_ = value; _has_field_.set(9); }
+
+  bool has_deadline_scheduled_at_us() const { return _has_field_[10]; }
+  int64_t deadline_scheduled_at_us() const { return deadline_scheduled_at_us_; }
+  void set_deadline_scheduled_at_us(int64_t value) { deadline_scheduled_at_us_ = value; _has_field_.set(10); }
+
+  bool has_now_us() const { return _has_field_[11]; }
+  int64_t now_us() const { return now_us_; }
+  void set_now_us(int64_t value) { now_us_ = value; _has_field_.set(11); }
+
+  bool has_now_to_deadline_delta_us() const { return _has_field_[12]; }
+  int64_t now_to_deadline_delta_us() const { return now_to_deadline_delta_us_; }
+  void set_now_to_deadline_delta_us(int64_t value) { now_to_deadline_delta_us_ = value; _has_field_.set(12); }
+
+  bool has_now_to_deadline_scheduled_at_delta_us() const { return _has_field_[13]; }
+  int64_t now_to_deadline_scheduled_at_delta_us() const { return now_to_deadline_scheduled_at_delta_us_; }
+  void set_now_to_deadline_scheduled_at_delta_us(int64_t value) { now_to_deadline_scheduled_at_delta_us_ = value; _has_field_.set(13); }
+
+  bool has_begin_impl_frame_args() const { return _has_field_[14]; }
+  const BeginImplFrameArgs& begin_impl_frame_args() const { return *begin_impl_frame_args_; }
+  BeginImplFrameArgs* mutable_begin_impl_frame_args() { _has_field_.set(14); return begin_impl_frame_args_.get(); }
+
+  bool has_begin_frame_observer_state() const { return _has_field_[15]; }
+  const BeginFrameObserverState& begin_frame_observer_state() const { return *begin_frame_observer_state_; }
+  BeginFrameObserverState* mutable_begin_frame_observer_state() { _has_field_.set(15); return begin_frame_observer_state_.get(); }
+
+  bool has_begin_frame_source_state() const { return _has_field_[16]; }
+  const BeginFrameSourceState& begin_frame_source_state() const { return *begin_frame_source_state_; }
+  BeginFrameSourceState* mutable_begin_frame_source_state() { _has_field_.set(16); return begin_frame_source_state_.get(); }
+
+  bool has_compositor_timing_history() const { return _has_field_[17]; }
+  const CompositorTimingHistory& compositor_timing_history() const { return *compositor_timing_history_; }
+  CompositorTimingHistory* mutable_compositor_timing_history() { _has_field_.set(17); return compositor_timing_history_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<ChromeCompositorStateMachine> state_machine_;
+  bool observing_begin_frame_source_{};
+  bool begin_impl_frame_deadline_task_{};
+  bool pending_begin_frame_task_{};
+  bool skipped_last_frame_missed_exceeded_deadline_{};
+  ChromeCompositorSchedulerAction inside_action_{};
+  ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode deadline_mode_{};
+  int64_t deadline_us_{};
+  int64_t deadline_scheduled_at_us_{};
+  int64_t now_us_{};
+  int64_t now_to_deadline_delta_us_{};
+  int64_t now_to_deadline_scheduled_at_delta_us_{};
+  ::protozero::CopyablePtr<BeginImplFrameArgs> begin_impl_frame_args_;
+  ::protozero::CopyablePtr<BeginFrameObserverState> begin_frame_observer_state_;
+  ::protozero::CopyablePtr<BeginFrameSourceState> begin_frame_source_state_;
+  ::protozero::CopyablePtr<CompositorTimingHistory> compositor_timing_history_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<18> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeContentSettingsEventInfo;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeContentSettingsEventInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNumberOfExceptionsFieldNumber = 1,
+  };
+
+  ChromeContentSettingsEventInfo();
+  ~ChromeContentSettingsEventInfo() override;
+  ChromeContentSettingsEventInfo(ChromeContentSettingsEventInfo&&) noexcept;
+  ChromeContentSettingsEventInfo& operator=(ChromeContentSettingsEventInfo&&);
+  ChromeContentSettingsEventInfo(const ChromeContentSettingsEventInfo&);
+  ChromeContentSettingsEventInfo& operator=(const ChromeContentSettingsEventInfo&);
+  bool operator==(const ChromeContentSettingsEventInfo&) const;
+  bool operator!=(const ChromeContentSettingsEventInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_number_of_exceptions() const { return _has_field_[1]; }
+  uint32_t number_of_exceptions() const { return number_of_exceptions_; }
+  void set_number_of_exceptions(uint32_t value) { number_of_exceptions_ = value; _has_field_.set(1); }
+
+ private:
+  uint32_t number_of_exceptions_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeFrameReporter;
+enum ChromeFrameReporter_State : int;
+enum ChromeFrameReporter_FrameDropReason : int;
+enum ChromeFrameReporter_ScrollState : int;
+enum ChromeFrameReporter_FrameType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeFrameReporter_State : int {
+  ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED = 0,
+  ChromeFrameReporter_State_STATE_PRESENTED_ALL = 1,
+  ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL = 2,
+  ChromeFrameReporter_State_STATE_DROPPED = 3,
+};
+enum ChromeFrameReporter_FrameDropReason : int {
+  ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED = 0,
+  ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR = 1,
+  ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD = 2,
+  ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR = 3,
+};
+enum ChromeFrameReporter_ScrollState : int {
+  ChromeFrameReporter_ScrollState_SCROLL_NONE = 0,
+  ChromeFrameReporter_ScrollState_SCROLL_MAIN_THREAD = 1,
+  ChromeFrameReporter_ScrollState_SCROLL_COMPOSITOR_THREAD = 2,
+  ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN = 3,
+};
+enum ChromeFrameReporter_FrameType : int {
+  ChromeFrameReporter_FrameType_FORKED = 0,
+  ChromeFrameReporter_FrameType_BACKFILL = 1,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeFrameReporter : public ::protozero::CppMessageObj {
+ public:
+  using State = ChromeFrameReporter_State;
+  static constexpr auto STATE_NO_UPDATE_DESIRED = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
+  static constexpr auto STATE_PRESENTED_ALL = ChromeFrameReporter_State_STATE_PRESENTED_ALL;
+  static constexpr auto STATE_PRESENTED_PARTIAL = ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL;
+  static constexpr auto STATE_DROPPED = ChromeFrameReporter_State_STATE_DROPPED;
+  static constexpr auto State_MIN = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
+  static constexpr auto State_MAX = ChromeFrameReporter_State_STATE_DROPPED;
+  using FrameDropReason = ChromeFrameReporter_FrameDropReason;
+  static constexpr auto REASON_UNSPECIFIED = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
+  static constexpr auto REASON_DISPLAY_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR;
+  static constexpr auto REASON_MAIN_THREAD = ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD;
+  static constexpr auto REASON_CLIENT_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
+  static constexpr auto FrameDropReason_MIN = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
+  static constexpr auto FrameDropReason_MAX = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
+  using ScrollState = ChromeFrameReporter_ScrollState;
+  static constexpr auto SCROLL_NONE = ChromeFrameReporter_ScrollState_SCROLL_NONE;
+  static constexpr auto SCROLL_MAIN_THREAD = ChromeFrameReporter_ScrollState_SCROLL_MAIN_THREAD;
+  static constexpr auto SCROLL_COMPOSITOR_THREAD = ChromeFrameReporter_ScrollState_SCROLL_COMPOSITOR_THREAD;
+  static constexpr auto SCROLL_UNKNOWN = ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN;
+  static constexpr auto ScrollState_MIN = ChromeFrameReporter_ScrollState_SCROLL_NONE;
+  static constexpr auto ScrollState_MAX = ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN;
+  using FrameType = ChromeFrameReporter_FrameType;
+  static constexpr auto FORKED = ChromeFrameReporter_FrameType_FORKED;
+  static constexpr auto BACKFILL = ChromeFrameReporter_FrameType_BACKFILL;
+  static constexpr auto FrameType_MIN = ChromeFrameReporter_FrameType_FORKED;
+  static constexpr auto FrameType_MAX = ChromeFrameReporter_FrameType_BACKFILL;
+  enum FieldNumbers {
+    kStateFieldNumber = 1,
+    kReasonFieldNumber = 2,
+    kFrameSourceFieldNumber = 3,
+    kFrameSequenceFieldNumber = 4,
+    kAffectsSmoothnessFieldNumber = 5,
+    kScrollStateFieldNumber = 6,
+    kHasMainAnimationFieldNumber = 7,
+    kHasCompositorAnimationFieldNumber = 8,
+    kHasSmoothInputMainFieldNumber = 9,
+    kHasMissingContentFieldNumber = 10,
+    kLayerTreeHostIdFieldNumber = 11,
+    kHasHighLatencyFieldNumber = 12,
+    kFrameTypeFieldNumber = 13,
+    kHighLatencyContributionStageFieldNumber = 14,
+  };
+
+  ChromeFrameReporter();
+  ~ChromeFrameReporter() override;
+  ChromeFrameReporter(ChromeFrameReporter&&) noexcept;
+  ChromeFrameReporter& operator=(ChromeFrameReporter&&);
+  ChromeFrameReporter(const ChromeFrameReporter&);
+  ChromeFrameReporter& operator=(const ChromeFrameReporter&);
+  bool operator==(const ChromeFrameReporter&) const;
+  bool operator!=(const ChromeFrameReporter& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_state() const { return _has_field_[1]; }
+  ChromeFrameReporter_State state() const { return state_; }
+  void set_state(ChromeFrameReporter_State value) { state_ = value; _has_field_.set(1); }
+
+  bool has_reason() const { return _has_field_[2]; }
+  ChromeFrameReporter_FrameDropReason reason() const { return reason_; }
+  void set_reason(ChromeFrameReporter_FrameDropReason value) { reason_ = value; _has_field_.set(2); }
+
+  bool has_frame_source() const { return _has_field_[3]; }
+  uint64_t frame_source() const { return frame_source_; }
+  void set_frame_source(uint64_t value) { frame_source_ = value; _has_field_.set(3); }
+
+  bool has_frame_sequence() const { return _has_field_[4]; }
+  uint64_t frame_sequence() const { return frame_sequence_; }
+  void set_frame_sequence(uint64_t value) { frame_sequence_ = value; _has_field_.set(4); }
+
+  bool has_affects_smoothness() const { return _has_field_[5]; }
+  bool affects_smoothness() const { return affects_smoothness_; }
+  void set_affects_smoothness(bool value) { affects_smoothness_ = value; _has_field_.set(5); }
+
+  bool has_scroll_state() const { return _has_field_[6]; }
+  ChromeFrameReporter_ScrollState scroll_state() const { return scroll_state_; }
+  void set_scroll_state(ChromeFrameReporter_ScrollState value) { scroll_state_ = value; _has_field_.set(6); }
+
+  bool has_has_main_animation() const { return _has_field_[7]; }
+  bool has_main_animation() const { return has_main_animation_; }
+  void set_has_main_animation(bool value) { has_main_animation_ = value; _has_field_.set(7); }
+
+  bool has_has_compositor_animation() const { return _has_field_[8]; }
+  bool has_compositor_animation() const { return has_compositor_animation_; }
+  void set_has_compositor_animation(bool value) { has_compositor_animation_ = value; _has_field_.set(8); }
+
+  bool has_has_smooth_input_main() const { return _has_field_[9]; }
+  bool has_smooth_input_main() const { return has_smooth_input_main_; }
+  void set_has_smooth_input_main(bool value) { has_smooth_input_main_ = value; _has_field_.set(9); }
+
+  bool has_has_missing_content() const { return _has_field_[10]; }
+  bool has_missing_content() const { return has_missing_content_; }
+  void set_has_missing_content(bool value) { has_missing_content_ = value; _has_field_.set(10); }
+
+  bool has_layer_tree_host_id() const { return _has_field_[11]; }
+  uint64_t layer_tree_host_id() const { return layer_tree_host_id_; }
+  void set_layer_tree_host_id(uint64_t value) { layer_tree_host_id_ = value; _has_field_.set(11); }
+
+  bool has_has_high_latency() const { return _has_field_[12]; }
+  bool has_high_latency() const { return has_high_latency_; }
+  void set_has_high_latency(bool value) { has_high_latency_ = value; _has_field_.set(12); }
+
+  bool has_frame_type() const { return _has_field_[13]; }
+  ChromeFrameReporter_FrameType frame_type() const { return frame_type_; }
+  void set_frame_type(ChromeFrameReporter_FrameType value) { frame_type_ = value; _has_field_.set(13); }
+
+  const std::vector<std::string>& high_latency_contribution_stage() const { return high_latency_contribution_stage_; }
+  std::vector<std::string>* mutable_high_latency_contribution_stage() { return &high_latency_contribution_stage_; }
+  int high_latency_contribution_stage_size() const { return static_cast<int>(high_latency_contribution_stage_.size()); }
+  void clear_high_latency_contribution_stage() { high_latency_contribution_stage_.clear(); }
+  void add_high_latency_contribution_stage(std::string value) { high_latency_contribution_stage_.emplace_back(value); }
+  std::string* add_high_latency_contribution_stage() { high_latency_contribution_stage_.emplace_back(); return &high_latency_contribution_stage_.back(); }
+
+ private:
+  ChromeFrameReporter_State state_{};
+  ChromeFrameReporter_FrameDropReason reason_{};
+  uint64_t frame_source_{};
+  uint64_t frame_sequence_{};
+  bool affects_smoothness_{};
+  ChromeFrameReporter_ScrollState scroll_state_{};
+  bool has_main_animation_{};
+  bool has_compositor_animation_{};
+  bool has_smooth_input_main_{};
+  bool has_missing_content_{};
+  uint64_t layer_tree_host_id_{};
+  bool has_high_latency_{};
+  ChromeFrameReporter_FrameType frame_type_{};
+  std::vector<std::string> high_latency_contribution_stage_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<15> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeHistogramSample;
+class HistogramName;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeHistogramSample : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameHashFieldNumber = 1,
+    kNameFieldNumber = 2,
+    kSampleFieldNumber = 3,
+    kNameIidFieldNumber = 4,
+  };
+
+  ChromeHistogramSample();
+  ~ChromeHistogramSample() override;
+  ChromeHistogramSample(ChromeHistogramSample&&) noexcept;
+  ChromeHistogramSample& operator=(ChromeHistogramSample&&);
+  ChromeHistogramSample(const ChromeHistogramSample&);
+  ChromeHistogramSample& operator=(const ChromeHistogramSample&);
+  bool operator==(const ChromeHistogramSample&) const;
+  bool operator!=(const ChromeHistogramSample& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name_hash() const { return _has_field_[1]; }
+  uint64_t name_hash() const { return name_hash_; }
+  void set_name_hash(uint64_t value) { name_hash_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+  bool has_sample() const { return _has_field_[3]; }
+  int64_t sample() const { return sample_; }
+  void set_sample(int64_t value) { sample_ = value; _has_field_.set(3); }
+
+  bool has_name_iid() const { return _has_field_[4]; }
+  uint64_t name_iid() const { return name_iid_; }
+  void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(4); }
+
+ private:
+  uint64_t name_hash_{};
+  std::string name_{};
+  int64_t sample_{};
+  uint64_t name_iid_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT HistogramName : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  HistogramName();
+  ~HistogramName() override;
+  HistogramName(HistogramName&&) noexcept;
+  HistogramName& operator=(HistogramName&&);
+  HistogramName(const HistogramName&);
+  HistogramName& operator=(const HistogramName&);
+  bool operator==(const HistogramName&) const;
+  bool operator!=(const HistogramName& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeKeyedService;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeKeyedService : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNameFieldNumber = 1,
+  };
+
+  ChromeKeyedService();
+  ~ChromeKeyedService() override;
+  ChromeKeyedService(ChromeKeyedService&&) noexcept;
+  ChromeKeyedService& operator=(ChromeKeyedService&&);
+  ChromeKeyedService(const ChromeKeyedService&);
+  ChromeKeyedService& operator=(const ChromeKeyedService&);
+  bool operator==(const ChromeKeyedService&) const;
+  bool operator!=(const ChromeKeyedService& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name() const { return _has_field_[1]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
+
+ private:
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeLatencyInfo;
+class ChromeLatencyInfo_ComponentInfo;
+enum ChromeLatencyInfo_Step : int;
+enum ChromeLatencyInfo_LatencyComponentType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeLatencyInfo_Step : int {
+  ChromeLatencyInfo_Step_STEP_UNSPECIFIED = 0,
+  ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI = 3,
+  ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL = 5,
+  ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = 8,
+  ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN = 4,
+  ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE = 2,
+  ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = 1,
+  ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = 9,
+  ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL = 10,
+  ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS = 6,
+  ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP = 7,
+  ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS = 11,
+};
+enum ChromeLatencyInfo_LatencyComponentType : int {
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED = 0,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = 1,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = 2,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = 3,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = 4,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI = 5,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = 6,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = 7,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = 8,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = 9,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = 10,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = 11,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = 12,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = 13,
+  ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = 14,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeLatencyInfo : public ::protozero::CppMessageObj {
+ public:
+  using ComponentInfo = ChromeLatencyInfo_ComponentInfo;
+  using Step = ChromeLatencyInfo_Step;
+  static constexpr auto STEP_UNSPECIFIED = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
+  static constexpr auto STEP_SEND_INPUT_EVENT_UI = ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI;
+  static constexpr auto STEP_HANDLE_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL;
+  static constexpr auto STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL;
+  static constexpr auto STEP_HANDLE_INPUT_EVENT_MAIN = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN;
+  static constexpr auto STEP_MAIN_THREAD_SCROLL_UPDATE = ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE;
+  static constexpr auto STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT;
+  static constexpr auto STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL;
+  static constexpr auto STEP_HANDLED_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL;
+  static constexpr auto STEP_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS;
+  static constexpr auto STEP_DRAW_AND_SWAP = ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP;
+  static constexpr auto STEP_FINISHED_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS;
+  static constexpr auto Step_MIN = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
+  static constexpr auto Step_MAX = ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS;
+  using LatencyComponentType = ChromeLatencyInfo_LatencyComponentType;
+  static constexpr auto COMPONENT_UNSPECIFIED = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_UI = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP;
+  static constexpr auto COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME;
+  static constexpr auto COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER;
+  static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
+  static constexpr auto LatencyComponentType_MIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
+  static constexpr auto LatencyComponentType_MAX = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
+  enum FieldNumbers {
+    kTraceIdFieldNumber = 1,
+    kStepFieldNumber = 2,
+    kFrameTreeNodeIdFieldNumber = 3,
+    kComponentInfoFieldNumber = 4,
+    kIsCoalescedFieldNumber = 5,
+    kGestureScrollIdFieldNumber = 6,
+    kTouchIdFieldNumber = 7,
+  };
+
+  ChromeLatencyInfo();
+  ~ChromeLatencyInfo() override;
+  ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept;
+  ChromeLatencyInfo& operator=(ChromeLatencyInfo&&);
+  ChromeLatencyInfo(const ChromeLatencyInfo&);
+  ChromeLatencyInfo& operator=(const ChromeLatencyInfo&);
+  bool operator==(const ChromeLatencyInfo&) const;
+  bool operator!=(const ChromeLatencyInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_id() const { return _has_field_[1]; }
+  int64_t trace_id() const { return trace_id_; }
+  void set_trace_id(int64_t value) { trace_id_ = value; _has_field_.set(1); }
+
+  bool has_step() const { return _has_field_[2]; }
+  ChromeLatencyInfo_Step step() const { return step_; }
+  void set_step(ChromeLatencyInfo_Step value) { step_ = value; _has_field_.set(2); }
+
+  bool has_frame_tree_node_id() const { return _has_field_[3]; }
+  int32_t frame_tree_node_id() const { return frame_tree_node_id_; }
+  void set_frame_tree_node_id(int32_t value) { frame_tree_node_id_ = value; _has_field_.set(3); }
+
+  const std::vector<ChromeLatencyInfo_ComponentInfo>& component_info() const { return component_info_; }
+  std::vector<ChromeLatencyInfo_ComponentInfo>* mutable_component_info() { return &component_info_; }
+  int component_info_size() const;
+  void clear_component_info();
+  ChromeLatencyInfo_ComponentInfo* add_component_info();
+
+  bool has_is_coalesced() const { return _has_field_[5]; }
+  bool is_coalesced() const { return is_coalesced_; }
+  void set_is_coalesced(bool value) { is_coalesced_ = value; _has_field_.set(5); }
+
+  bool has_gesture_scroll_id() const { return _has_field_[6]; }
+  int64_t gesture_scroll_id() const { return gesture_scroll_id_; }
+  void set_gesture_scroll_id(int64_t value) { gesture_scroll_id_ = value; _has_field_.set(6); }
+
+  bool has_touch_id() const { return _has_field_[7]; }
+  int64_t touch_id() const { return touch_id_; }
+  void set_touch_id(int64_t value) { touch_id_ = value; _has_field_.set(7); }
+
+ private:
+  int64_t trace_id_{};
+  ChromeLatencyInfo_Step step_{};
+  int32_t frame_tree_node_id_{};
+  std::vector<ChromeLatencyInfo_ComponentInfo> component_info_;
+  bool is_coalesced_{};
+  int64_t gesture_scroll_id_{};
+  int64_t touch_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChromeLatencyInfo_ComponentInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kComponentTypeFieldNumber = 1,
+    kTimeUsFieldNumber = 2,
+  };
+
+  ChromeLatencyInfo_ComponentInfo();
+  ~ChromeLatencyInfo_ComponentInfo() override;
+  ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept;
+  ChromeLatencyInfo_ComponentInfo& operator=(ChromeLatencyInfo_ComponentInfo&&);
+  ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&);
+  ChromeLatencyInfo_ComponentInfo& operator=(const ChromeLatencyInfo_ComponentInfo&);
+  bool operator==(const ChromeLatencyInfo_ComponentInfo&) const;
+  bool operator!=(const ChromeLatencyInfo_ComponentInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_component_type() const { return _has_field_[1]; }
+  ChromeLatencyInfo_LatencyComponentType component_type() const { return component_type_; }
+  void set_component_type(ChromeLatencyInfo_LatencyComponentType value) { component_type_ = value; _has_field_.set(1); }
+
+  bool has_time_us() const { return _has_field_[2]; }
+  uint64_t time_us() const { return time_us_; }
+  void set_time_us(uint64_t value) { time_us_ = value; _has_field_.set(2); }
+
+ private:
+  ChromeLatencyInfo_LatencyComponentType component_type_{};
+  uint64_t time_us_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeLegacyIpc;
+enum ChromeLegacyIpc_MessageClass : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeLegacyIpc_MessageClass : int {
+  ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED = 0,
+  ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION = 1,
+  ChromeLegacyIpc_MessageClass_CLASS_FRAME = 2,
+  ChromeLegacyIpc_MessageClass_CLASS_PAGE = 3,
+  ChromeLegacyIpc_MessageClass_CLASS_VIEW = 4,
+  ChromeLegacyIpc_MessageClass_CLASS_WIDGET = 5,
+  ChromeLegacyIpc_MessageClass_CLASS_INPUT = 6,
+  ChromeLegacyIpc_MessageClass_CLASS_TEST = 7,
+  ChromeLegacyIpc_MessageClass_CLASS_WORKER = 8,
+  ChromeLegacyIpc_MessageClass_CLASS_NACL = 9,
+  ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL = 10,
+  ChromeLegacyIpc_MessageClass_CLASS_MEDIA = 11,
+  ChromeLegacyIpc_MessageClass_CLASS_PPAPI = 12,
+  ChromeLegacyIpc_MessageClass_CLASS_CHROME = 13,
+  ChromeLegacyIpc_MessageClass_CLASS_DRAG = 14,
+  ChromeLegacyIpc_MessageClass_CLASS_PRINT = 15,
+  ChromeLegacyIpc_MessageClass_CLASS_EXTENSION = 16,
+  ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT = 17,
+  ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST = 18,
+  ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY = 19,
+  ChromeLegacyIpc_MessageClass_CLASS_PRERENDER = 20,
+  ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING = 21,
+  ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN = 22,
+  ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW = 23,
+  ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST = 24,
+  ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA = 25,
+  ChromeLegacyIpc_MessageClass_CLASS_CAST = 26,
+  ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE = 27,
+  ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING = 28,
+  ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU = 29,
+  ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST = 30,
+  ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS = 31,
+  ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW = 32,
+  ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW = 33,
+  ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE = 34,
+  ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER = 35,
+  ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER = 36,
+  ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME = 37,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeLegacyIpc : public ::protozero::CppMessageObj {
+ public:
+  using MessageClass = ChromeLegacyIpc_MessageClass;
+  static constexpr auto CLASS_UNSPECIFIED = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
+  static constexpr auto CLASS_AUTOMATION = ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION;
+  static constexpr auto CLASS_FRAME = ChromeLegacyIpc_MessageClass_CLASS_FRAME;
+  static constexpr auto CLASS_PAGE = ChromeLegacyIpc_MessageClass_CLASS_PAGE;
+  static constexpr auto CLASS_VIEW = ChromeLegacyIpc_MessageClass_CLASS_VIEW;
+  static constexpr auto CLASS_WIDGET = ChromeLegacyIpc_MessageClass_CLASS_WIDGET;
+  static constexpr auto CLASS_INPUT = ChromeLegacyIpc_MessageClass_CLASS_INPUT;
+  static constexpr auto CLASS_TEST = ChromeLegacyIpc_MessageClass_CLASS_TEST;
+  static constexpr auto CLASS_WORKER = ChromeLegacyIpc_MessageClass_CLASS_WORKER;
+  static constexpr auto CLASS_NACL = ChromeLegacyIpc_MessageClass_CLASS_NACL;
+  static constexpr auto CLASS_GPU_CHANNEL = ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL;
+  static constexpr auto CLASS_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_MEDIA;
+  static constexpr auto CLASS_PPAPI = ChromeLegacyIpc_MessageClass_CLASS_PPAPI;
+  static constexpr auto CLASS_CHROME = ChromeLegacyIpc_MessageClass_CLASS_CHROME;
+  static constexpr auto CLASS_DRAG = ChromeLegacyIpc_MessageClass_CLASS_DRAG;
+  static constexpr auto CLASS_PRINT = ChromeLegacyIpc_MessageClass_CLASS_PRINT;
+  static constexpr auto CLASS_EXTENSION = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION;
+  static constexpr auto CLASS_TEXT_INPUT_CLIENT = ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT;
+  static constexpr auto CLASS_BLINK_TEST = ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST;
+  static constexpr auto CLASS_ACCESSIBILITY = ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY;
+  static constexpr auto CLASS_PRERENDER = ChromeLegacyIpc_MessageClass_CLASS_PRERENDER;
+  static constexpr auto CLASS_CHROMOTING = ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING;
+  static constexpr auto CLASS_BROWSER_PLUGIN = ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN;
+  static constexpr auto CLASS_ANDROID_WEB_VIEW = ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW;
+  static constexpr auto CLASS_NACL_HOST = ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST;
+  static constexpr auto CLASS_ENCRYPTED_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA;
+  static constexpr auto CLASS_CAST = ChromeLegacyIpc_MessageClass_CLASS_CAST;
+  static constexpr auto CLASS_GIN_JAVA_BRIDGE = ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE;
+  static constexpr auto CLASS_CHROME_UTILITY_PRINTING = ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING;
+  static constexpr auto CLASS_OZONE_GPU = ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU;
+  static constexpr auto CLASS_WEB_TEST = ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST;
+  static constexpr auto CLASS_NETWORK_HINTS = ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS;
+  static constexpr auto CLASS_EXTENSIONS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW;
+  static constexpr auto CLASS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW;
+  static constexpr auto CLASS_MEDIA_PLAYER_DELEGATE = ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE;
+  static constexpr auto CLASS_EXTENSION_WORKER = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER;
+  static constexpr auto CLASS_SUBRESOURCE_FILTER = ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER;
+  static constexpr auto CLASS_UNFREEZABLE_FRAME = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
+  static constexpr auto MessageClass_MIN = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
+  static constexpr auto MessageClass_MAX = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
+  enum FieldNumbers {
+    kMessageClassFieldNumber = 1,
+    kMessageLineFieldNumber = 2,
+  };
+
+  ChromeLegacyIpc();
+  ~ChromeLegacyIpc() override;
+  ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept;
+  ChromeLegacyIpc& operator=(ChromeLegacyIpc&&);
+  ChromeLegacyIpc(const ChromeLegacyIpc&);
+  ChromeLegacyIpc& operator=(const ChromeLegacyIpc&);
+  bool operator==(const ChromeLegacyIpc&) const;
+  bool operator!=(const ChromeLegacyIpc& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_message_class() const { return _has_field_[1]; }
+  ChromeLegacyIpc_MessageClass message_class() const { return message_class_; }
+  void set_message_class(ChromeLegacyIpc_MessageClass value) { message_class_ = value; _has_field_.set(1); }
+
+  bool has_message_line() const { return _has_field_[2]; }
+  uint32_t message_line() const { return message_line_; }
+  void set_message_line(uint32_t value) { message_line_ = value; _has_field_.set(2); }
+
+ private:
+  ChromeLegacyIpc_MessageClass message_class_{};
+  uint32_t message_line_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_message_pump.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeMessagePump;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeMessagePump : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSentMessagesInQueueFieldNumber = 1,
+    kIoHandlerLocationIidFieldNumber = 2,
+  };
+
+  ChromeMessagePump();
+  ~ChromeMessagePump() override;
+  ChromeMessagePump(ChromeMessagePump&&) noexcept;
+  ChromeMessagePump& operator=(ChromeMessagePump&&);
+  ChromeMessagePump(const ChromeMessagePump&);
+  ChromeMessagePump& operator=(const ChromeMessagePump&);
+  bool operator==(const ChromeMessagePump&) const;
+  bool operator!=(const ChromeMessagePump& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_sent_messages_in_queue() const { return _has_field_[1]; }
+  bool sent_messages_in_queue() const { return sent_messages_in_queue_; }
+  void set_sent_messages_in_queue(bool value) { sent_messages_in_queue_ = value; _has_field_.set(1); }
+
+  bool has_io_handler_location_iid() const { return _has_field_[2]; }
+  uint64_t io_handler_location_iid() const { return io_handler_location_iid_; }
+  void set_io_handler_location_iid(uint64_t value) { io_handler_location_iid_ = value; _has_field_.set(2); }
+
+ private:
+  bool sent_messages_in_queue_{};
+  uint64_t io_handler_location_iid_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeMojoEventInfo;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeMojoEventInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kWatcherNotifyInterfaceTagFieldNumber = 1,
+    kIpcHashFieldNumber = 2,
+    kMojoInterfaceTagFieldNumber = 3,
+    kMojoInterfaceMethodIidFieldNumber = 4,
+    kIsReplyFieldNumber = 5,
+    kPayloadSizeFieldNumber = 6,
+    kDataNumBytesFieldNumber = 7,
+  };
+
+  ChromeMojoEventInfo();
+  ~ChromeMojoEventInfo() override;
+  ChromeMojoEventInfo(ChromeMojoEventInfo&&) noexcept;
+  ChromeMojoEventInfo& operator=(ChromeMojoEventInfo&&);
+  ChromeMojoEventInfo(const ChromeMojoEventInfo&);
+  ChromeMojoEventInfo& operator=(const ChromeMojoEventInfo&);
+  bool operator==(const ChromeMojoEventInfo&) const;
+  bool operator!=(const ChromeMojoEventInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_watcher_notify_interface_tag() const { return _has_field_[1]; }
+  const std::string& watcher_notify_interface_tag() const { return watcher_notify_interface_tag_; }
+  void set_watcher_notify_interface_tag(const std::string& value) { watcher_notify_interface_tag_ = value; _has_field_.set(1); }
+
+  bool has_ipc_hash() const { return _has_field_[2]; }
+  uint32_t ipc_hash() const { return ipc_hash_; }
+  void set_ipc_hash(uint32_t value) { ipc_hash_ = value; _has_field_.set(2); }
+
+  bool has_mojo_interface_tag() const { return _has_field_[3]; }
+  const std::string& mojo_interface_tag() const { return mojo_interface_tag_; }
+  void set_mojo_interface_tag(const std::string& value) { mojo_interface_tag_ = value; _has_field_.set(3); }
+
+  bool has_mojo_interface_method_iid() const { return _has_field_[4]; }
+  uint64_t mojo_interface_method_iid() const { return mojo_interface_method_iid_; }
+  void set_mojo_interface_method_iid(uint64_t value) { mojo_interface_method_iid_ = value; _has_field_.set(4); }
+
+  bool has_is_reply() const { return _has_field_[5]; }
+  bool is_reply() const { return is_reply_; }
+  void set_is_reply(bool value) { is_reply_ = value; _has_field_.set(5); }
+
+  bool has_payload_size() const { return _has_field_[6]; }
+  uint64_t payload_size() const { return payload_size_; }
+  void set_payload_size(uint64_t value) { payload_size_ = value; _has_field_.set(6); }
+
+  bool has_data_num_bytes() const { return _has_field_[7]; }
+  uint64_t data_num_bytes() const { return data_num_bytes_; }
+  void set_data_num_bytes(uint64_t value) { data_num_bytes_ = value; _has_field_.set(7); }
+
+ private:
+  std::string watcher_notify_interface_tag_{};
+  uint32_t ipc_hash_{};
+  std::string mojo_interface_tag_{};
+  uint64_t mojo_interface_method_iid_{};
+  bool is_reply_{};
+  uint64_t payload_size_{};
+  uint64_t data_num_bytes_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeProcessDescriptor;
+enum ChromeProcessDescriptor_ProcessType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeProcessDescriptor_ProcessType : int {
+  ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED = 0,
+  ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER = 1,
+  ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER = 2,
+  ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY = 3,
+  ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE = 4,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER = 5,
+  ChromeProcessDescriptor_ProcessType_PROCESS_GPU = 6,
+  ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN = 7,
+  ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER = 8,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_NETWORK = 9,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TRACING = 10,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_STORAGE = 11,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_AUDIO = 12,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_DATA_DECODER = 13,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UTIL_WIN = 14,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROXY_RESOLVER = 15,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CDM = 16,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_VIDEO_CAPTURE = 17,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UNZIPPER = 18,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MIRRORING = 19,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEPATCHER = 20,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TTS = 21,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTING = 22,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QUARANTINE = 23,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_LOCALSEARCH = 24,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = 25,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEUTIL = 26,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTCOMPOSITOR = 27,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PAINTPREVIEW = 28,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SPEECHRECOGNITION = 29,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_XRDEVICE = 30,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_READICON = 31,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_LANGUAGEDETECTION = 32,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHARING = 33,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIAPARSER = 34,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QRCODEGENERATOR = 35,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROFILEIMPORT = 36,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_IME = 37,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_RECORDING = 38,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION = 39,
+  ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER_EXTENSION = 40,
+  ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIA_FOUNDATION = 41,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeProcessDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using ProcessType = ChromeProcessDescriptor_ProcessType;
+  static constexpr auto PROCESS_UNSPECIFIED = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
+  static constexpr auto PROCESS_BROWSER = ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER;
+  static constexpr auto PROCESS_RENDERER = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER;
+  static constexpr auto PROCESS_UTILITY = ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY;
+  static constexpr auto PROCESS_ZYGOTE = ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE;
+  static constexpr auto PROCESS_SANDBOX_HELPER = ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER;
+  static constexpr auto PROCESS_GPU = ChromeProcessDescriptor_ProcessType_PROCESS_GPU;
+  static constexpr auto PROCESS_PPAPI_PLUGIN = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN;
+  static constexpr auto PROCESS_PPAPI_BROKER = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER;
+  static constexpr auto PROCESS_SERVICE_NETWORK = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_NETWORK;
+  static constexpr auto PROCESS_SERVICE_TRACING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TRACING;
+  static constexpr auto PROCESS_SERVICE_STORAGE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_STORAGE;
+  static constexpr auto PROCESS_SERVICE_AUDIO = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_AUDIO;
+  static constexpr auto PROCESS_SERVICE_DATA_DECODER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_DATA_DECODER;
+  static constexpr auto PROCESS_SERVICE_UTIL_WIN = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UTIL_WIN;
+  static constexpr auto PROCESS_SERVICE_PROXY_RESOLVER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROXY_RESOLVER;
+  static constexpr auto PROCESS_SERVICE_CDM = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CDM;
+  static constexpr auto PROCESS_SERVICE_VIDEO_CAPTURE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_VIDEO_CAPTURE;
+  static constexpr auto PROCESS_SERVICE_UNZIPPER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UNZIPPER;
+  static constexpr auto PROCESS_SERVICE_MIRRORING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MIRRORING;
+  static constexpr auto PROCESS_SERVICE_FILEPATCHER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEPATCHER;
+  static constexpr auto PROCESS_SERVICE_TTS = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TTS;
+  static constexpr auto PROCESS_SERVICE_PRINTING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTING;
+  static constexpr auto PROCESS_SERVICE_QUARANTINE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QUARANTINE;
+  static constexpr auto PROCESS_SERVICE_CROS_LOCALSEARCH = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_LOCALSEARCH;
+  static constexpr auto PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER;
+  static constexpr auto PROCESS_SERVICE_FILEUTIL = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEUTIL;
+  static constexpr auto PROCESS_SERVICE_PRINTCOMPOSITOR = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTCOMPOSITOR;
+  static constexpr auto PROCESS_SERVICE_PAINTPREVIEW = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PAINTPREVIEW;
+  static constexpr auto PROCESS_SERVICE_SPEECHRECOGNITION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SPEECHRECOGNITION;
+  static constexpr auto PROCESS_SERVICE_XRDEVICE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_XRDEVICE;
+  static constexpr auto PROCESS_SERVICE_READICON = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_READICON;
+  static constexpr auto PROCESS_SERVICE_LANGUAGEDETECTION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_LANGUAGEDETECTION;
+  static constexpr auto PROCESS_SERVICE_SHARING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHARING;
+  static constexpr auto PROCESS_SERVICE_MEDIAPARSER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIAPARSER;
+  static constexpr auto PROCESS_SERVICE_QRCODEGENERATOR = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QRCODEGENERATOR;
+  static constexpr auto PROCESS_SERVICE_PROFILEIMPORT = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROFILEIMPORT;
+  static constexpr auto PROCESS_SERVICE_IME = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_IME;
+  static constexpr auto PROCESS_SERVICE_RECORDING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_RECORDING;
+  static constexpr auto PROCESS_SERVICE_SHAPEDETECTION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION;
+  static constexpr auto PROCESS_RENDERER_EXTENSION = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER_EXTENSION;
+  static constexpr auto PROCESS_SERVICE_MEDIA_FOUNDATION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIA_FOUNDATION;
+  static constexpr auto ProcessType_MIN = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
+  static constexpr auto ProcessType_MAX = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIA_FOUNDATION;
+  enum FieldNumbers {
+    kProcessTypeFieldNumber = 1,
+    kProcessPriorityFieldNumber = 2,
+    kLegacySortIndexFieldNumber = 3,
+    kHostAppPackageNameFieldNumber = 4,
+    kCrashTraceIdFieldNumber = 5,
+  };
+
+  ChromeProcessDescriptor();
+  ~ChromeProcessDescriptor() override;
+  ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept;
+  ChromeProcessDescriptor& operator=(ChromeProcessDescriptor&&);
+  ChromeProcessDescriptor(const ChromeProcessDescriptor&);
+  ChromeProcessDescriptor& operator=(const ChromeProcessDescriptor&);
+  bool operator==(const ChromeProcessDescriptor&) const;
+  bool operator!=(const ChromeProcessDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_process_type() const { return _has_field_[1]; }
+  ChromeProcessDescriptor_ProcessType process_type() const { return process_type_; }
+  void set_process_type(ChromeProcessDescriptor_ProcessType value) { process_type_ = value; _has_field_.set(1); }
+
+  bool has_process_priority() const { return _has_field_[2]; }
+  int32_t process_priority() const { return process_priority_; }
+  void set_process_priority(int32_t value) { process_priority_ = value; _has_field_.set(2); }
+
+  bool has_legacy_sort_index() const { return _has_field_[3]; }
+  int32_t legacy_sort_index() const { return legacy_sort_index_; }
+  void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
+
+  bool has_host_app_package_name() const { return _has_field_[4]; }
+  const std::string& host_app_package_name() const { return host_app_package_name_; }
+  void set_host_app_package_name(const std::string& value) { host_app_package_name_ = value; _has_field_.set(4); }
+
+  bool has_crash_trace_id() const { return _has_field_[5]; }
+  uint64_t crash_trace_id() const { return crash_trace_id_; }
+  void set_crash_trace_id(uint64_t value) { crash_trace_id_ = value; _has_field_.set(5); }
+
+ private:
+  ChromeProcessDescriptor_ProcessType process_type_{};
+  int32_t process_priority_{};
+  int32_t legacy_sort_index_{};
+  std::string host_app_package_name_{};
+  uint64_t crash_trace_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<6> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeRendererSchedulerState;
+enum ChromeRAILMode : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeRAILMode : int {
+  RAIL_MODE_NONE = 0,
+  RAIL_MODE_RESPONSE = 1,
+  RAIL_MODE_ANIMATION = 2,
+  RAIL_MODE_IDLE = 3,
+  RAIL_MODE_LOAD = 4,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeRendererSchedulerState : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kRailModeFieldNumber = 1,
+    kIsBackgroundedFieldNumber = 2,
+    kIsHiddenFieldNumber = 3,
+  };
+
+  ChromeRendererSchedulerState();
+  ~ChromeRendererSchedulerState() override;
+  ChromeRendererSchedulerState(ChromeRendererSchedulerState&&) noexcept;
+  ChromeRendererSchedulerState& operator=(ChromeRendererSchedulerState&&);
+  ChromeRendererSchedulerState(const ChromeRendererSchedulerState&);
+  ChromeRendererSchedulerState& operator=(const ChromeRendererSchedulerState&);
+  bool operator==(const ChromeRendererSchedulerState&) const;
+  bool operator!=(const ChromeRendererSchedulerState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_rail_mode() const { return _has_field_[1]; }
+  ChromeRAILMode rail_mode() const { return rail_mode_; }
+  void set_rail_mode(ChromeRAILMode value) { rail_mode_ = value; _has_field_.set(1); }
+
+  bool has_is_backgrounded() const { return _has_field_[2]; }
+  bool is_backgrounded() const { return is_backgrounded_; }
+  void set_is_backgrounded(bool value) { is_backgrounded_ = value; _has_field_.set(2); }
+
+  bool has_is_hidden() const { return _has_field_[3]; }
+  bool is_hidden() const { return is_hidden_; }
+  void set_is_hidden(bool value) { is_hidden_ = value; _has_field_.set(3); }
+
+ private:
+  ChromeRAILMode rail_mode_{};
+  bool is_backgrounded_{};
+  bool is_hidden_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeThreadDescriptor;
+enum ChromeThreadDescriptor_ThreadType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ChromeThreadDescriptor_ThreadType : int {
+  ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED = 0,
+  ChromeThreadDescriptor_ThreadType_THREAD_MAIN = 1,
+  ChromeThreadDescriptor_ThreadType_THREAD_IO = 2,
+  ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER = 3,
+  ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER = 4,
+  ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING = 5,
+  ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING = 6,
+  ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE = 7,
+  ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR = 8,
+  ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR = 9,
+  ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER = 10,
+  ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER = 11,
+  ChromeThreadDescriptor_ThreadType_THREAD_NETWORK_SERVICE = 12,
+  ChromeThreadDescriptor_ThreadType_THREAD_CHILD_IO = 13,
+  ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_IO = 14,
+  ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_MAIN = 15,
+  ChromeThreadDescriptor_ThreadType_THREAD_RENDERER_MAIN = 16,
+  ChromeThreadDescriptor_ThreadType_THREAD_UTILITY_MAIN = 17,
+  ChromeThreadDescriptor_ThreadType_THREAD_GPU_MAIN = 18,
+  ChromeThreadDescriptor_ThreadType_THREAD_CACHE_BLOCKFILE = 19,
+  ChromeThreadDescriptor_ThreadType_THREAD_MEDIA = 20,
+  ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_OUTPUTDEVICE = 21,
+  ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_INPUTDEVICE = 22,
+  ChromeThreadDescriptor_ThreadType_THREAD_GPU_MEMORY = 23,
+  ChromeThreadDescriptor_ThreadType_THREAD_GPU_VSYNC = 24,
+  ChromeThreadDescriptor_ThreadType_THREAD_DXA_VIDEODECODER = 25,
+  ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_WATCHDOG = 26,
+  ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_NETWORK = 27,
+  ChromeThreadDescriptor_ThreadType_THREAD_WINDOW_OWNER = 28,
+  ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_SIGNALING = 29,
+  ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_WORKER = 30,
+  ChromeThreadDescriptor_ThreadType_THREAD_PPAPI_MAIN = 31,
+  ChromeThreadDescriptor_ThreadType_THREAD_GPU_WATCHDOG = 32,
+  ChromeThreadDescriptor_ThreadType_THREAD_SWAPPER = 33,
+  ChromeThreadDescriptor_ThreadType_THREAD_GAMEPAD_POLLING = 34,
+  ChromeThreadDescriptor_ThreadType_THREAD_WEBCRYPTO = 35,
+  ChromeThreadDescriptor_ThreadType_THREAD_DATABASE = 36,
+  ChromeThreadDescriptor_ThreadType_THREAD_PROXYRESOLVER = 37,
+  ChromeThreadDescriptor_ThreadType_THREAD_DEVTOOLSADB = 38,
+  ChromeThreadDescriptor_ThreadType_THREAD_NETWORKCONFIGWATCHER = 39,
+  ChromeThreadDescriptor_ThreadType_THREAD_WASAPI_RENDER = 40,
+  ChromeThreadDescriptor_ThreadType_THREAD_LOADER_LOCK_SAMPLER = 41,
+  ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA = 50,
+  ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER = 51,
+};
+
+class PERFETTO_EXPORT_COMPONENT ChromeThreadDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using ThreadType = ChromeThreadDescriptor_ThreadType;
+  static constexpr auto THREAD_UNSPECIFIED = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
+  static constexpr auto THREAD_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_MAIN;
+  static constexpr auto THREAD_IO = ChromeThreadDescriptor_ThreadType_THREAD_IO;
+  static constexpr auto THREAD_POOL_BG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER;
+  static constexpr auto THREAD_POOL_FG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER;
+  static constexpr auto THREAD_POOL_FG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING;
+  static constexpr auto THREAD_POOL_BG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING;
+  static constexpr auto THREAD_POOL_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE;
+  static constexpr auto THREAD_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR;
+  static constexpr auto THREAD_VIZ_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR;
+  static constexpr auto THREAD_COMPOSITOR_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER;
+  static constexpr auto THREAD_SERVICE_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER;
+  static constexpr auto THREAD_NETWORK_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_NETWORK_SERVICE;
+  static constexpr auto THREAD_CHILD_IO = ChromeThreadDescriptor_ThreadType_THREAD_CHILD_IO;
+  static constexpr auto THREAD_BROWSER_IO = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_IO;
+  static constexpr auto THREAD_BROWSER_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_MAIN;
+  static constexpr auto THREAD_RENDERER_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_RENDERER_MAIN;
+  static constexpr auto THREAD_UTILITY_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_UTILITY_MAIN;
+  static constexpr auto THREAD_GPU_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_GPU_MAIN;
+  static constexpr auto THREAD_CACHE_BLOCKFILE = ChromeThreadDescriptor_ThreadType_THREAD_CACHE_BLOCKFILE;
+  static constexpr auto THREAD_MEDIA = ChromeThreadDescriptor_ThreadType_THREAD_MEDIA;
+  static constexpr auto THREAD_AUDIO_OUTPUTDEVICE = ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_OUTPUTDEVICE;
+  static constexpr auto THREAD_AUDIO_INPUTDEVICE = ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_INPUTDEVICE;
+  static constexpr auto THREAD_GPU_MEMORY = ChromeThreadDescriptor_ThreadType_THREAD_GPU_MEMORY;
+  static constexpr auto THREAD_GPU_VSYNC = ChromeThreadDescriptor_ThreadType_THREAD_GPU_VSYNC;
+  static constexpr auto THREAD_DXA_VIDEODECODER = ChromeThreadDescriptor_ThreadType_THREAD_DXA_VIDEODECODER;
+  static constexpr auto THREAD_BROWSER_WATCHDOG = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_WATCHDOG;
+  static constexpr auto THREAD_WEBRTC_NETWORK = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_NETWORK;
+  static constexpr auto THREAD_WINDOW_OWNER = ChromeThreadDescriptor_ThreadType_THREAD_WINDOW_OWNER;
+  static constexpr auto THREAD_WEBRTC_SIGNALING = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_SIGNALING;
+  static constexpr auto THREAD_WEBRTC_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_WORKER;
+  static constexpr auto THREAD_PPAPI_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_PPAPI_MAIN;
+  static constexpr auto THREAD_GPU_WATCHDOG = ChromeThreadDescriptor_ThreadType_THREAD_GPU_WATCHDOG;
+  static constexpr auto THREAD_SWAPPER = ChromeThreadDescriptor_ThreadType_THREAD_SWAPPER;
+  static constexpr auto THREAD_GAMEPAD_POLLING = ChromeThreadDescriptor_ThreadType_THREAD_GAMEPAD_POLLING;
+  static constexpr auto THREAD_WEBCRYPTO = ChromeThreadDescriptor_ThreadType_THREAD_WEBCRYPTO;
+  static constexpr auto THREAD_DATABASE = ChromeThreadDescriptor_ThreadType_THREAD_DATABASE;
+  static constexpr auto THREAD_PROXYRESOLVER = ChromeThreadDescriptor_ThreadType_THREAD_PROXYRESOLVER;
+  static constexpr auto THREAD_DEVTOOLSADB = ChromeThreadDescriptor_ThreadType_THREAD_DEVTOOLSADB;
+  static constexpr auto THREAD_NETWORKCONFIGWATCHER = ChromeThreadDescriptor_ThreadType_THREAD_NETWORKCONFIGWATCHER;
+  static constexpr auto THREAD_WASAPI_RENDER = ChromeThreadDescriptor_ThreadType_THREAD_WASAPI_RENDER;
+  static constexpr auto THREAD_LOADER_LOCK_SAMPLER = ChromeThreadDescriptor_ThreadType_THREAD_LOADER_LOCK_SAMPLER;
+  static constexpr auto THREAD_MEMORY_INFRA = ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA;
+  static constexpr auto THREAD_SAMPLING_PROFILER = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
+  static constexpr auto ThreadType_MIN = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
+  static constexpr auto ThreadType_MAX = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
+  enum FieldNumbers {
+    kThreadTypeFieldNumber = 1,
+    kLegacySortIndexFieldNumber = 2,
+  };
+
+  ChromeThreadDescriptor();
+  ~ChromeThreadDescriptor() override;
+  ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept;
+  ChromeThreadDescriptor& operator=(ChromeThreadDescriptor&&);
+  ChromeThreadDescriptor(const ChromeThreadDescriptor&);
+  ChromeThreadDescriptor& operator=(const ChromeThreadDescriptor&);
+  bool operator==(const ChromeThreadDescriptor&) const;
+  bool operator!=(const ChromeThreadDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_thread_type() const { return _has_field_[1]; }
+  ChromeThreadDescriptor_ThreadType thread_type() const { return thread_type_; }
+  void set_thread_type(ChromeThreadDescriptor_ThreadType value) { thread_type_ = value; _has_field_.set(1); }
+
+  bool has_legacy_sort_index() const { return _has_field_[2]; }
+  int32_t legacy_sort_index() const { return legacy_sort_index_; }
+  void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(2); }
+
+ private:
+  ChromeThreadDescriptor_ThreadType thread_type_{};
+  int32_t legacy_sort_index_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeUserEvent;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeUserEvent : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kActionFieldNumber = 1,
+    kActionHashFieldNumber = 2,
+  };
+
+  ChromeUserEvent();
+  ~ChromeUserEvent() override;
+  ChromeUserEvent(ChromeUserEvent&&) noexcept;
+  ChromeUserEvent& operator=(ChromeUserEvent&&);
+  ChromeUserEvent(const ChromeUserEvent&);
+  ChromeUserEvent& operator=(const ChromeUserEvent&);
+  bool operator==(const ChromeUserEvent&) const;
+  bool operator!=(const ChromeUserEvent& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_action() const { return _has_field_[1]; }
+  const std::string& action() const { return action_; }
+  void set_action(const std::string& value) { action_ = value; _has_field_.set(1); }
+
+  bool has_action_hash() const { return _has_field_[2]; }
+  uint64_t action_hash() const { return action_hash_; }
+  void set_action_hash(uint64_t value) { action_hash_ = value; _has_field_.set(2); }
+
+ private:
+  std::string action_{};
+  uint64_t action_hash_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ChromeWindowHandleEventInfo;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT ChromeWindowHandleEventInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDpiFieldNumber = 1,
+    kMessageIdFieldNumber = 2,
+    kHwndPtrFieldNumber = 3,
+  };
+
+  ChromeWindowHandleEventInfo();
+  ~ChromeWindowHandleEventInfo() override;
+  ChromeWindowHandleEventInfo(ChromeWindowHandleEventInfo&&) noexcept;
+  ChromeWindowHandleEventInfo& operator=(ChromeWindowHandleEventInfo&&);
+  ChromeWindowHandleEventInfo(const ChromeWindowHandleEventInfo&);
+  ChromeWindowHandleEventInfo& operator=(const ChromeWindowHandleEventInfo&);
+  bool operator==(const ChromeWindowHandleEventInfo&) const;
+  bool operator!=(const ChromeWindowHandleEventInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_dpi() const { return _has_field_[1]; }
+  uint32_t dpi() const { return dpi_; }
+  void set_dpi(uint32_t value) { dpi_ = value; _has_field_.set(1); }
+
+  bool has_message_id() const { return _has_field_[2]; }
+  uint32_t message_id() const { return message_id_; }
+  void set_message_id(uint32_t value) { message_id_ = value; _has_field_.set(2); }
+
+  bool has_hwnd_ptr() const { return _has_field_[3]; }
+  uint64_t hwnd_ptr() const { return hwnd_ptr_; }
+  void set_hwnd_ptr(uint64_t value) { hwnd_ptr_ = value; _has_field_.set(3); }
+
+ private:
+  uint32_t dpi_{};
+  uint32_t message_id_{};
+  uint64_t hwnd_ptr_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/debug_annotation.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class DebugAnnotationValueTypeName;
+class DebugAnnotationName;
+class DebugAnnotation;
+class DebugAnnotation_NestedValue;
+enum DebugAnnotation_NestedValue_NestedType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum DebugAnnotation_NestedValue_NestedType : int {
+  DebugAnnotation_NestedValue_NestedType_UNSPECIFIED = 0,
+  DebugAnnotation_NestedValue_NestedType_DICT = 1,
+  DebugAnnotation_NestedValue_NestedType_ARRAY = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT DebugAnnotationValueTypeName : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  DebugAnnotationValueTypeName();
+  ~DebugAnnotationValueTypeName() override;
+  DebugAnnotationValueTypeName(DebugAnnotationValueTypeName&&) noexcept;
+  DebugAnnotationValueTypeName& operator=(DebugAnnotationValueTypeName&&);
+  DebugAnnotationValueTypeName(const DebugAnnotationValueTypeName&);
+  DebugAnnotationValueTypeName& operator=(const DebugAnnotationValueTypeName&);
+  bool operator==(const DebugAnnotationValueTypeName&) const;
+  bool operator!=(const DebugAnnotationValueTypeName& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DebugAnnotationName : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  DebugAnnotationName();
+  ~DebugAnnotationName() override;
+  DebugAnnotationName(DebugAnnotationName&&) noexcept;
+  DebugAnnotationName& operator=(DebugAnnotationName&&);
+  DebugAnnotationName(const DebugAnnotationName&);
+  DebugAnnotationName& operator=(const DebugAnnotationName&);
+  bool operator==(const DebugAnnotationName&) const;
+  bool operator!=(const DebugAnnotationName& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DebugAnnotation : public ::protozero::CppMessageObj {
+ public:
+  using NestedValue = DebugAnnotation_NestedValue;
+  enum FieldNumbers {
+    kNameIidFieldNumber = 1,
+    kNameFieldNumber = 10,
+    kBoolValueFieldNumber = 2,
+    kUintValueFieldNumber = 3,
+    kIntValueFieldNumber = 4,
+    kDoubleValueFieldNumber = 5,
+    kPointerValueFieldNumber = 7,
+    kNestedValueFieldNumber = 8,
+    kLegacyJsonValueFieldNumber = 9,
+    kStringValueFieldNumber = 6,
+    kStringValueIidFieldNumber = 17,
+    kProtoTypeNameFieldNumber = 16,
+    kProtoTypeNameIidFieldNumber = 13,
+    kProtoValueFieldNumber = 14,
+    kDictEntriesFieldNumber = 11,
+    kArrayValuesFieldNumber = 12,
+  };
+
+  DebugAnnotation();
+  ~DebugAnnotation() override;
+  DebugAnnotation(DebugAnnotation&&) noexcept;
+  DebugAnnotation& operator=(DebugAnnotation&&);
+  DebugAnnotation(const DebugAnnotation&);
+  DebugAnnotation& operator=(const DebugAnnotation&);
+  bool operator==(const DebugAnnotation&) const;
+  bool operator!=(const DebugAnnotation& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name_iid() const { return _has_field_[1]; }
+  uint64_t name_iid() const { return name_iid_; }
+  void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[10]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(10); }
+
+  bool has_bool_value() const { return _has_field_[2]; }
+  bool bool_value() const { return bool_value_; }
+  void set_bool_value(bool value) { bool_value_ = value; _has_field_.set(2); }
+
+  bool has_uint_value() const { return _has_field_[3]; }
+  uint64_t uint_value() const { return uint_value_; }
+  void set_uint_value(uint64_t value) { uint_value_ = value; _has_field_.set(3); }
+
+  bool has_int_value() const { return _has_field_[4]; }
+  int64_t int_value() const { return int_value_; }
+  void set_int_value(int64_t value) { int_value_ = value; _has_field_.set(4); }
+
+  bool has_double_value() const { return _has_field_[5]; }
+  double double_value() const { return double_value_; }
+  void set_double_value(double value) { double_value_ = value; _has_field_.set(5); }
+
+  bool has_pointer_value() const { return _has_field_[7]; }
+  uint64_t pointer_value() const { return pointer_value_; }
+  void set_pointer_value(uint64_t value) { pointer_value_ = value; _has_field_.set(7); }
+
+  bool has_nested_value() const { return _has_field_[8]; }
+  const DebugAnnotation_NestedValue& nested_value() const { return *nested_value_; }
+  DebugAnnotation_NestedValue* mutable_nested_value() { _has_field_.set(8); return nested_value_.get(); }
+
+  bool has_legacy_json_value() const { return _has_field_[9]; }
+  const std::string& legacy_json_value() const { return legacy_json_value_; }
+  void set_legacy_json_value(const std::string& value) { legacy_json_value_ = value; _has_field_.set(9); }
+
+  bool has_string_value() const { return _has_field_[6]; }
+  const std::string& string_value() const { return string_value_; }
+  void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(6); }
+
+  bool has_string_value_iid() const { return _has_field_[17]; }
+  uint64_t string_value_iid() const { return string_value_iid_; }
+  void set_string_value_iid(uint64_t value) { string_value_iid_ = value; _has_field_.set(17); }
+
+  bool has_proto_type_name() const { return _has_field_[16]; }
+  const std::string& proto_type_name() const { return proto_type_name_; }
+  void set_proto_type_name(const std::string& value) { proto_type_name_ = value; _has_field_.set(16); }
+
+  bool has_proto_type_name_iid() const { return _has_field_[13]; }
+  uint64_t proto_type_name_iid() const { return proto_type_name_iid_; }
+  void set_proto_type_name_iid(uint64_t value) { proto_type_name_iid_ = value; _has_field_.set(13); }
+
+  bool has_proto_value() const { return _has_field_[14]; }
+  const std::string& proto_value() const { return proto_value_; }
+  void set_proto_value(const std::string& value) { proto_value_ = value; _has_field_.set(14); }
+  void set_proto_value(const void* p, size_t s) { proto_value_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(14); }
+
+  const std::vector<DebugAnnotation>& dict_entries() const { return dict_entries_; }
+  std::vector<DebugAnnotation>* mutable_dict_entries() { return &dict_entries_; }
+  int dict_entries_size() const;
+  void clear_dict_entries();
+  DebugAnnotation* add_dict_entries();
+
+  const std::vector<DebugAnnotation>& array_values() const { return array_values_; }
+  std::vector<DebugAnnotation>* mutable_array_values() { return &array_values_; }
+  int array_values_size() const;
+  void clear_array_values();
+  DebugAnnotation* add_array_values();
+
+ private:
+  uint64_t name_iid_{};
+  std::string name_{};
+  bool bool_value_{};
+  uint64_t uint_value_{};
+  int64_t int_value_{};
+  double double_value_{};
+  uint64_t pointer_value_{};
+  ::protozero::CopyablePtr<DebugAnnotation_NestedValue> nested_value_;
+  std::string legacy_json_value_{};
+  std::string string_value_{};
+  uint64_t string_value_iid_{};
+  std::string proto_type_name_{};
+  uint64_t proto_type_name_iid_{};
+  std::string proto_value_{};
+  std::vector<DebugAnnotation> dict_entries_;
+  std::vector<DebugAnnotation> array_values_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<18> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DebugAnnotation_NestedValue : public ::protozero::CppMessageObj {
+ public:
+  using NestedType = DebugAnnotation_NestedValue_NestedType;
+  static constexpr auto UNSPECIFIED = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
+  static constexpr auto DICT = DebugAnnotation_NestedValue_NestedType_DICT;
+  static constexpr auto ARRAY = DebugAnnotation_NestedValue_NestedType_ARRAY;
+  static constexpr auto NestedType_MIN = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
+  static constexpr auto NestedType_MAX = DebugAnnotation_NestedValue_NestedType_ARRAY;
+  enum FieldNumbers {
+    kNestedTypeFieldNumber = 1,
+    kDictKeysFieldNumber = 2,
+    kDictValuesFieldNumber = 3,
+    kArrayValuesFieldNumber = 4,
+    kIntValueFieldNumber = 5,
+    kDoubleValueFieldNumber = 6,
+    kBoolValueFieldNumber = 7,
+    kStringValueFieldNumber = 8,
+  };
+
+  DebugAnnotation_NestedValue();
+  ~DebugAnnotation_NestedValue() override;
+  DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept;
+  DebugAnnotation_NestedValue& operator=(DebugAnnotation_NestedValue&&);
+  DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&);
+  DebugAnnotation_NestedValue& operator=(const DebugAnnotation_NestedValue&);
+  bool operator==(const DebugAnnotation_NestedValue&) const;
+  bool operator!=(const DebugAnnotation_NestedValue& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_nested_type() const { return _has_field_[1]; }
+  DebugAnnotation_NestedValue_NestedType nested_type() const { return nested_type_; }
+  void set_nested_type(DebugAnnotation_NestedValue_NestedType value) { nested_type_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& dict_keys() const { return dict_keys_; }
+  std::vector<std::string>* mutable_dict_keys() { return &dict_keys_; }
+  int dict_keys_size() const { return static_cast<int>(dict_keys_.size()); }
+  void clear_dict_keys() { dict_keys_.clear(); }
+  void add_dict_keys(std::string value) { dict_keys_.emplace_back(value); }
+  std::string* add_dict_keys() { dict_keys_.emplace_back(); return &dict_keys_.back(); }
+
+  const std::vector<DebugAnnotation_NestedValue>& dict_values() const { return dict_values_; }
+  std::vector<DebugAnnotation_NestedValue>* mutable_dict_values() { return &dict_values_; }
+  int dict_values_size() const;
+  void clear_dict_values();
+  DebugAnnotation_NestedValue* add_dict_values();
+
+  const std::vector<DebugAnnotation_NestedValue>& array_values() const { return array_values_; }
+  std::vector<DebugAnnotation_NestedValue>* mutable_array_values() { return &array_values_; }
+  int array_values_size() const;
+  void clear_array_values();
+  DebugAnnotation_NestedValue* add_array_values();
+
+  bool has_int_value() const { return _has_field_[5]; }
+  int64_t int_value() const { return int_value_; }
+  void set_int_value(int64_t value) { int_value_ = value; _has_field_.set(5); }
+
+  bool has_double_value() const { return _has_field_[6]; }
+  double double_value() const { return double_value_; }
+  void set_double_value(double value) { double_value_ = value; _has_field_.set(6); }
+
+  bool has_bool_value() const { return _has_field_[7]; }
+  bool bool_value() const { return bool_value_; }
+  void set_bool_value(bool value) { bool_value_ = value; _has_field_.set(7); }
+
+  bool has_string_value() const { return _has_field_[8]; }
+  const std::string& string_value() const { return string_value_; }
+  void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(8); }
+
+ private:
+  DebugAnnotation_NestedValue_NestedType nested_type_{};
+  std::vector<std::string> dict_keys_;
+  std::vector<DebugAnnotation_NestedValue> dict_values_;
+  std::vector<DebugAnnotation_NestedValue> array_values_;
+  int64_t int_value_{};
+  double double_value_{};
+  bool bool_value_{};
+  std::string string_value_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/log_message.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class LogMessageBody;
+class LogMessage;
+enum LogMessage_Priority : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum LogMessage_Priority : int {
+  LogMessage_Priority_PRIO_UNSPECIFIED = 0,
+  LogMessage_Priority_PRIO_UNUSED = 1,
+  LogMessage_Priority_PRIO_VERBOSE = 2,
+  LogMessage_Priority_PRIO_DEBUG = 3,
+  LogMessage_Priority_PRIO_INFO = 4,
+  LogMessage_Priority_PRIO_WARN = 5,
+  LogMessage_Priority_PRIO_ERROR = 6,
+  LogMessage_Priority_PRIO_FATAL = 7,
+};
+
+class PERFETTO_EXPORT_COMPONENT LogMessageBody : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kBodyFieldNumber = 2,
+  };
+
+  LogMessageBody();
+  ~LogMessageBody() override;
+  LogMessageBody(LogMessageBody&&) noexcept;
+  LogMessageBody& operator=(LogMessageBody&&);
+  LogMessageBody(const LogMessageBody&);
+  LogMessageBody& operator=(const LogMessageBody&);
+  bool operator==(const LogMessageBody&) const;
+  bool operator!=(const LogMessageBody& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_body() const { return _has_field_[2]; }
+  const std::string& body() const { return body_; }
+  void set_body(const std::string& value) { body_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string body_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT LogMessage : public ::protozero::CppMessageObj {
+ public:
+  using Priority = LogMessage_Priority;
+  static constexpr auto PRIO_UNSPECIFIED = LogMessage_Priority_PRIO_UNSPECIFIED;
+  static constexpr auto PRIO_UNUSED = LogMessage_Priority_PRIO_UNUSED;
+  static constexpr auto PRIO_VERBOSE = LogMessage_Priority_PRIO_VERBOSE;
+  static constexpr auto PRIO_DEBUG = LogMessage_Priority_PRIO_DEBUG;
+  static constexpr auto PRIO_INFO = LogMessage_Priority_PRIO_INFO;
+  static constexpr auto PRIO_WARN = LogMessage_Priority_PRIO_WARN;
+  static constexpr auto PRIO_ERROR = LogMessage_Priority_PRIO_ERROR;
+  static constexpr auto PRIO_FATAL = LogMessage_Priority_PRIO_FATAL;
+  static constexpr auto Priority_MIN = LogMessage_Priority_PRIO_UNSPECIFIED;
+  static constexpr auto Priority_MAX = LogMessage_Priority_PRIO_FATAL;
+  enum FieldNumbers {
+    kSourceLocationIidFieldNumber = 1,
+    kBodyIidFieldNumber = 2,
+    kPrioFieldNumber = 3,
+  };
+
+  LogMessage();
+  ~LogMessage() override;
+  LogMessage(LogMessage&&) noexcept;
+  LogMessage& operator=(LogMessage&&);
+  LogMessage(const LogMessage&);
+  LogMessage& operator=(const LogMessage&);
+  bool operator==(const LogMessage&) const;
+  bool operator!=(const LogMessage& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_source_location_iid() const { return _has_field_[1]; }
+  uint64_t source_location_iid() const { return source_location_iid_; }
+  void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(1); }
+
+  bool has_body_iid() const { return _has_field_[2]; }
+  uint64_t body_iid() const { return body_iid_; }
+  void set_body_iid(uint64_t value) { body_iid_ = value; _has_field_.set(2); }
+
+  bool has_prio() const { return _has_field_[3]; }
+  LogMessage_Priority prio() const { return prio_; }
+  void set_prio(LogMessage_Priority value) { prio_ = value; _has_field_.set(3); }
+
+ private:
+  uint64_t source_location_iid_{};
+  uint64_t body_iid_{};
+  LogMessage_Priority prio_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/process_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ProcessDescriptor;
+enum ProcessDescriptor_ChromeProcessType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ProcessDescriptor_ChromeProcessType : int {
+  ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED = 0,
+  ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER = 1,
+  ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER = 2,
+  ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY = 3,
+  ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE = 4,
+  ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER = 5,
+  ProcessDescriptor_ChromeProcessType_PROCESS_GPU = 6,
+  ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN = 7,
+  ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER = 8,
+};
+
+class PERFETTO_EXPORT_COMPONENT ProcessDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using ChromeProcessType = ProcessDescriptor_ChromeProcessType;
+  static constexpr auto PROCESS_UNSPECIFIED = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
+  static constexpr auto PROCESS_BROWSER = ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER;
+  static constexpr auto PROCESS_RENDERER = ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER;
+  static constexpr auto PROCESS_UTILITY = ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY;
+  static constexpr auto PROCESS_ZYGOTE = ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE;
+  static constexpr auto PROCESS_SANDBOX_HELPER = ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER;
+  static constexpr auto PROCESS_GPU = ProcessDescriptor_ChromeProcessType_PROCESS_GPU;
+  static constexpr auto PROCESS_PPAPI_PLUGIN = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN;
+  static constexpr auto PROCESS_PPAPI_BROKER = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
+  static constexpr auto ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
+  static constexpr auto ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
+  enum FieldNumbers {
+    kPidFieldNumber = 1,
+    kCmdlineFieldNumber = 2,
+    kProcessNameFieldNumber = 6,
+    kProcessPriorityFieldNumber = 5,
+    kStartTimestampNsFieldNumber = 7,
+    kChromeProcessTypeFieldNumber = 4,
+    kLegacySortIndexFieldNumber = 3,
+    kProcessLabelsFieldNumber = 8,
+  };
+
+  ProcessDescriptor();
+  ~ProcessDescriptor() override;
+  ProcessDescriptor(ProcessDescriptor&&) noexcept;
+  ProcessDescriptor& operator=(ProcessDescriptor&&);
+  ProcessDescriptor(const ProcessDescriptor&);
+  ProcessDescriptor& operator=(const ProcessDescriptor&);
+  bool operator==(const ProcessDescriptor&) const;
+  bool operator!=(const ProcessDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_pid() const { return _has_field_[1]; }
+  int32_t pid() const { return pid_; }
+  void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
+
+  const std::vector<std::string>& cmdline() const { return cmdline_; }
+  std::vector<std::string>* mutable_cmdline() { return &cmdline_; }
+  int cmdline_size() const { return static_cast<int>(cmdline_.size()); }
+  void clear_cmdline() { cmdline_.clear(); }
+  void add_cmdline(std::string value) { cmdline_.emplace_back(value); }
+  std::string* add_cmdline() { cmdline_.emplace_back(); return &cmdline_.back(); }
+
+  bool has_process_name() const { return _has_field_[6]; }
+  const std::string& process_name() const { return process_name_; }
+  void set_process_name(const std::string& value) { process_name_ = value; _has_field_.set(6); }
+
+  bool has_process_priority() const { return _has_field_[5]; }
+  int32_t process_priority() const { return process_priority_; }
+  void set_process_priority(int32_t value) { process_priority_ = value; _has_field_.set(5); }
+
+  bool has_start_timestamp_ns() const { return _has_field_[7]; }
+  int64_t start_timestamp_ns() const { return start_timestamp_ns_; }
+  void set_start_timestamp_ns(int64_t value) { start_timestamp_ns_ = value; _has_field_.set(7); }
+
+  bool has_chrome_process_type() const { return _has_field_[4]; }
+  ProcessDescriptor_ChromeProcessType chrome_process_type() const { return chrome_process_type_; }
+  void set_chrome_process_type(ProcessDescriptor_ChromeProcessType value) { chrome_process_type_ = value; _has_field_.set(4); }
+
+  bool has_legacy_sort_index() const { return _has_field_[3]; }
+  int32_t legacy_sort_index() const { return legacy_sort_index_; }
+  void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
+
+  const std::vector<std::string>& process_labels() const { return process_labels_; }
+  std::vector<std::string>* mutable_process_labels() { return &process_labels_; }
+  int process_labels_size() const { return static_cast<int>(process_labels_.size()); }
+  void clear_process_labels() { process_labels_.clear(); }
+  void add_process_labels(std::string value) { process_labels_.emplace_back(value); }
+  std::string* add_process_labels() { process_labels_.emplace_back(); return &process_labels_.back(); }
+
+ private:
+  int32_t pid_{};
+  std::vector<std::string> cmdline_;
+  std::string process_name_{};
+  int32_t process_priority_{};
+  int64_t start_timestamp_ns_{};
+  ProcessDescriptor_ChromeProcessType chrome_process_type_{};
+  int32_t legacy_sort_index_{};
+  std::vector<std::string> process_labels_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/range_of_interest.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_RANGE_OF_INTEREST_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_RANGE_OF_INTEREST_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TrackEventRangeOfInterest;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TrackEventRangeOfInterest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kStartUsFieldNumber = 1,
+  };
+
+  TrackEventRangeOfInterest();
+  ~TrackEventRangeOfInterest() override;
+  TrackEventRangeOfInterest(TrackEventRangeOfInterest&&) noexcept;
+  TrackEventRangeOfInterest& operator=(TrackEventRangeOfInterest&&);
+  TrackEventRangeOfInterest(const TrackEventRangeOfInterest&);
+  TrackEventRangeOfInterest& operator=(const TrackEventRangeOfInterest&);
+  bool operator==(const TrackEventRangeOfInterest&) const;
+  bool operator!=(const TrackEventRangeOfInterest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_start_us() const { return _has_field_[1]; }
+  int64_t start_us() const { return start_us_; }
+  void set_start_us(int64_t value) { start_us_ = value; _has_field_.set(1); }
+
+ private:
+  int64_t start_us_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_RANGE_OF_INTEREST_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/screenshot.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SCREENSHOT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SCREENSHOT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class Screenshot;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT Screenshot : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kJpgImageFieldNumber = 1,
+  };
+
+  Screenshot();
+  ~Screenshot() override;
+  Screenshot(Screenshot&&) noexcept;
+  Screenshot& operator=(Screenshot&&);
+  Screenshot(const Screenshot&);
+  Screenshot& operator=(const Screenshot&);
+  bool operator==(const Screenshot&) const;
+  bool operator!=(const Screenshot& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_jpg_image() const { return _has_field_[1]; }
+  const std::string& jpg_image() const { return jpg_image_; }
+  void set_jpg_image(const std::string& value) { jpg_image_ = value; _has_field_.set(1); }
+  void set_jpg_image(const void* p, size_t s) { jpg_image_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(1); }
+
+ private:
+  std::string jpg_image_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SCREENSHOT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/source_location.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SourceLocation;
+class UnsymbolizedSourceLocation;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT SourceLocation : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kFileNameFieldNumber = 2,
+    kFunctionNameFieldNumber = 3,
+    kLineNumberFieldNumber = 4,
+  };
+
+  SourceLocation();
+  ~SourceLocation() override;
+  SourceLocation(SourceLocation&&) noexcept;
+  SourceLocation& operator=(SourceLocation&&);
+  SourceLocation(const SourceLocation&);
+  SourceLocation& operator=(const SourceLocation&);
+  bool operator==(const SourceLocation&) const;
+  bool operator!=(const SourceLocation& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_file_name() const { return _has_field_[2]; }
+  const std::string& file_name() const { return file_name_; }
+  void set_file_name(const std::string& value) { file_name_ = value; _has_field_.set(2); }
+
+  bool has_function_name() const { return _has_field_[3]; }
+  const std::string& function_name() const { return function_name_; }
+  void set_function_name(const std::string& value) { function_name_ = value; _has_field_.set(3); }
+
+  bool has_line_number() const { return _has_field_[4]; }
+  uint32_t line_number() const { return line_number_; }
+  void set_line_number(uint32_t value) { line_number_ = value; _has_field_.set(4); }
+
+ private:
+  uint64_t iid_{};
+  std::string file_name_{};
+  std::string function_name_{};
+  uint32_t line_number_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UnsymbolizedSourceLocation : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kMappingIdFieldNumber = 2,
+    kRelPcFieldNumber = 3,
+  };
+
+  UnsymbolizedSourceLocation();
+  ~UnsymbolizedSourceLocation() override;
+  UnsymbolizedSourceLocation(UnsymbolizedSourceLocation&&) noexcept;
+  UnsymbolizedSourceLocation& operator=(UnsymbolizedSourceLocation&&);
+  UnsymbolizedSourceLocation(const UnsymbolizedSourceLocation&);
+  UnsymbolizedSourceLocation& operator=(const UnsymbolizedSourceLocation&);
+  bool operator==(const UnsymbolizedSourceLocation&) const;
+  bool operator!=(const UnsymbolizedSourceLocation& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_mapping_id() const { return _has_field_[2]; }
+  uint64_t mapping_id() const { return mapping_id_; }
+  void set_mapping_id(uint64_t value) { mapping_id_ = value; _has_field_.set(2); }
+
+  bool has_rel_pc() const { return _has_field_[3]; }
+  uint64_t rel_pc() const { return rel_pc_; }
+  void set_rel_pc(uint64_t value) { rel_pc_ = value; _has_field_.set(3); }
+
+ private:
+  uint64_t iid_{};
+  uint64_t mapping_id_{};
+  uint64_t rel_pc_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/task_execution.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class TaskExecution;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT TaskExecution : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPostedFromIidFieldNumber = 1,
+  };
+
+  TaskExecution();
+  ~TaskExecution() override;
+  TaskExecution(TaskExecution&&) noexcept;
+  TaskExecution& operator=(TaskExecution&&);
+  TaskExecution(const TaskExecution&);
+  TaskExecution& operator=(const TaskExecution&);
+  bool operator==(const TaskExecution&) const;
+  bool operator!=(const TaskExecution& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_posted_from_iid() const { return _has_field_[1]; }
+  uint64_t posted_from_iid() const { return posted_from_iid_; }
+  void set_posted_from_iid(uint64_t value) { posted_from_iid_ = value; _has_field_.set(1); }
+
+ private:
+  uint64_t posted_from_iid_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class ThreadDescriptor;
+enum ThreadDescriptor_ChromeThreadType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum ThreadDescriptor_ChromeThreadType : int {
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED = 0,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN = 1,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO = 2,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER = 3,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER = 4,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING = 5,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING = 6,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE = 7,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR = 8,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR = 9,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER = 10,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER = 11,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA = 50,
+  ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER = 51,
+};
+
+class PERFETTO_EXPORT_COMPONENT ThreadDescriptor : public ::protozero::CppMessageObj {
+ public:
+  using ChromeThreadType = ThreadDescriptor_ChromeThreadType;
+  static constexpr auto CHROME_THREAD_UNSPECIFIED = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
+  static constexpr auto CHROME_THREAD_MAIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN;
+  static constexpr auto CHROME_THREAD_IO = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO;
+  static constexpr auto CHROME_THREAD_POOL_BG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER;
+  static constexpr auto CHROME_THREAD_POOL_FG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER;
+  static constexpr auto CHROME_THREAD_POOL_FB_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING;
+  static constexpr auto CHROME_THREAD_POOL_BG_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING;
+  static constexpr auto CHROME_THREAD_POOL_SERVICE = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE;
+  static constexpr auto CHROME_THREAD_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR;
+  static constexpr auto CHROME_THREAD_VIZ_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR;
+  static constexpr auto CHROME_THREAD_COMPOSITOR_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER;
+  static constexpr auto CHROME_THREAD_SERVICE_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER;
+  static constexpr auto CHROME_THREAD_MEMORY_INFRA = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA;
+  static constexpr auto CHROME_THREAD_SAMPLING_PROFILER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
+  static constexpr auto ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
+  static constexpr auto ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
+  enum FieldNumbers {
+    kPidFieldNumber = 1,
+    kTidFieldNumber = 2,
+    kThreadNameFieldNumber = 5,
+    kChromeThreadTypeFieldNumber = 4,
+    kReferenceTimestampUsFieldNumber = 6,
+    kReferenceThreadTimeUsFieldNumber = 7,
+    kReferenceThreadInstructionCountFieldNumber = 8,
+    kLegacySortIndexFieldNumber = 3,
+  };
+
+  ThreadDescriptor();
+  ~ThreadDescriptor() override;
+  ThreadDescriptor(ThreadDescriptor&&) noexcept;
+  ThreadDescriptor& operator=(ThreadDescriptor&&);
+  ThreadDescriptor(const ThreadDescriptor&);
+  ThreadDescriptor& operator=(const ThreadDescriptor&);
+  bool operator==(const ThreadDescriptor&) const;
+  bool operator!=(const ThreadDescriptor& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_pid() const { return _has_field_[1]; }
+  int32_t pid() const { return pid_; }
+  void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
+
+  bool has_tid() const { return _has_field_[2]; }
+  int32_t tid() const { return tid_; }
+  void set_tid(int32_t value) { tid_ = value; _has_field_.set(2); }
+
+  bool has_thread_name() const { return _has_field_[5]; }
+  const std::string& thread_name() const { return thread_name_; }
+  void set_thread_name(const std::string& value) { thread_name_ = value; _has_field_.set(5); }
+
+  bool has_chrome_thread_type() const { return _has_field_[4]; }
+  ThreadDescriptor_ChromeThreadType chrome_thread_type() const { return chrome_thread_type_; }
+  void set_chrome_thread_type(ThreadDescriptor_ChromeThreadType value) { chrome_thread_type_ = value; _has_field_.set(4); }
+
+  bool has_reference_timestamp_us() const { return _has_field_[6]; }
+  int64_t reference_timestamp_us() const { return reference_timestamp_us_; }
+  void set_reference_timestamp_us(int64_t value) { reference_timestamp_us_ = value; _has_field_.set(6); }
+
+  bool has_reference_thread_time_us() const { return _has_field_[7]; }
+  int64_t reference_thread_time_us() const { return reference_thread_time_us_; }
+  void set_reference_thread_time_us(int64_t value) { reference_thread_time_us_ = value; _has_field_.set(7); }
+
+  bool has_reference_thread_instruction_count() const { return _has_field_[8]; }
+  int64_t reference_thread_instruction_count() const { return reference_thread_instruction_count_; }
+  void set_reference_thread_instruction_count(int64_t value) { reference_thread_instruction_count_ = value; _has_field_.set(8); }
+
+  bool has_legacy_sort_index() const { return _has_field_[3]; }
+  int32_t legacy_sort_index() const { return legacy_sort_index_; }
+  void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
+
+ private:
+  int32_t pid_{};
+  int32_t tid_{};
+  std::string thread_name_{};
+  ThreadDescriptor_ChromeThreadType chrome_thread_type_{};
+  int64_t reference_timestamp_us_{};
+  int64_t reference_thread_time_us_{};
+  int64_t reference_thread_instruction_count_{};
+  int32_t legacy_sort_index_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_event.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class EventName;
+class EventCategory;
+class TrackEventDefaults;
+class TrackEvent;
+class TrackEvent_LegacyEvent;
+class ChromeMojoEventInfo;
+class ChromeMessagePump;
+class SourceLocation;
+class Screenshot;
+class ChromeActiveProcesses;
+class ChromeContentSettingsEventInfo;
+class ChromeWindowHandleEventInfo;
+class ChromeRendererSchedulerState;
+class ChromeApplicationStateInfo;
+class ChromeFrameReporter;
+class ChromeLatencyInfo;
+class ChromeLatencyInfo_ComponentInfo;
+class ChromeHistogramSample;
+class ChromeLegacyIpc;
+class ChromeKeyedService;
+class ChromeUserEvent;
+class ChromeCompositorSchedulerState;
+class CompositorTimingHistory;
+class BeginFrameSourceState;
+class BeginFrameArgs;
+class BeginFrameObserverState;
+class BeginImplFrameArgs;
+class BeginImplFrameArgs_TimestampsInUs;
+class ChromeCompositorStateMachine;
+class ChromeCompositorStateMachine_MinorState;
+class ChromeCompositorStateMachine_MajorState;
+class LogMessage;
+class TaskExecution;
+class DebugAnnotation;
+class DebugAnnotation_NestedValue;
+enum TrackEvent_Type : int;
+enum TrackEvent_LegacyEvent_FlowDirection : int;
+enum TrackEvent_LegacyEvent_InstantEventScope : int;
+enum ChromeRAILMode : int;
+enum ChromeApplicationStateInfo_ChromeApplicationState : int;
+enum ChromeFrameReporter_State : int;
+enum ChromeFrameReporter_FrameDropReason : int;
+enum ChromeFrameReporter_ScrollState : int;
+enum ChromeFrameReporter_FrameType : int;
+enum ChromeLatencyInfo_Step : int;
+enum ChromeLatencyInfo_LatencyComponentType : int;
+enum ChromeLegacyIpc_MessageClass : int;
+enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int;
+enum ChromeCompositorSchedulerAction : int;
+enum BeginFrameArgs_BeginFrameArgsType : int;
+enum BeginImplFrameArgs_State : int;
+enum ChromeCompositorStateMachine_MinorState_TreePriority : int;
+enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int;
+enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int;
+enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int;
+enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int;
+enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int;
+enum LogMessage_Priority : int;
+enum DebugAnnotation_NestedValue_NestedType : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum TrackEvent_Type : int {
+  TrackEvent_Type_TYPE_UNSPECIFIED = 0,
+  TrackEvent_Type_TYPE_SLICE_BEGIN = 1,
+  TrackEvent_Type_TYPE_SLICE_END = 2,
+  TrackEvent_Type_TYPE_INSTANT = 3,
+  TrackEvent_Type_TYPE_COUNTER = 4,
+};
+enum TrackEvent_LegacyEvent_FlowDirection : int {
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED = 0,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_IN = 1,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT = 2,
+  TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT = 3,
+};
+enum TrackEvent_LegacyEvent_InstantEventScope : int {
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED = 0,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL = 1,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS = 2,
+  TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD = 3,
+};
+
+class PERFETTO_EXPORT_COMPONENT EventName : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  EventName();
+  ~EventName() override;
+  EventName(EventName&&) noexcept;
+  EventName& operator=(EventName&&);
+  EventName(const EventName&);
+  EventName& operator=(const EventName&);
+  bool operator==(const EventName&) const;
+  bool operator!=(const EventName& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT EventCategory : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIidFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  EventCategory();
+  ~EventCategory() override;
+  EventCategory(EventCategory&&) noexcept;
+  EventCategory& operator=(EventCategory&&);
+  EventCategory(const EventCategory&);
+  EventCategory& operator=(const EventCategory&);
+  bool operator==(const EventCategory&) const;
+  bool operator!=(const EventCategory& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_iid() const { return _has_field_[1]; }
+  uint64_t iid() const { return iid_; }
+  void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint64_t iid_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TrackEventDefaults : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTrackUuidFieldNumber = 11,
+    kExtraCounterTrackUuidsFieldNumber = 31,
+    kExtraDoubleCounterTrackUuidsFieldNumber = 45,
+  };
+
+  TrackEventDefaults();
+  ~TrackEventDefaults() override;
+  TrackEventDefaults(TrackEventDefaults&&) noexcept;
+  TrackEventDefaults& operator=(TrackEventDefaults&&);
+  TrackEventDefaults(const TrackEventDefaults&);
+  TrackEventDefaults& operator=(const TrackEventDefaults&);
+  bool operator==(const TrackEventDefaults&) const;
+  bool operator!=(const TrackEventDefaults& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_track_uuid() const { return _has_field_[11]; }
+  uint64_t track_uuid() const { return track_uuid_; }
+  void set_track_uuid(uint64_t value) { track_uuid_ = value; _has_field_.set(11); }
+
+  const std::vector<uint64_t>& extra_counter_track_uuids() const { return extra_counter_track_uuids_; }
+  std::vector<uint64_t>* mutable_extra_counter_track_uuids() { return &extra_counter_track_uuids_; }
+  int extra_counter_track_uuids_size() const { return static_cast<int>(extra_counter_track_uuids_.size()); }
+  void clear_extra_counter_track_uuids() { extra_counter_track_uuids_.clear(); }
+  void add_extra_counter_track_uuids(uint64_t value) { extra_counter_track_uuids_.emplace_back(value); }
+  uint64_t* add_extra_counter_track_uuids() { extra_counter_track_uuids_.emplace_back(); return &extra_counter_track_uuids_.back(); }
+
+  const std::vector<uint64_t>& extra_double_counter_track_uuids() const { return extra_double_counter_track_uuids_; }
+  std::vector<uint64_t>* mutable_extra_double_counter_track_uuids() { return &extra_double_counter_track_uuids_; }
+  int extra_double_counter_track_uuids_size() const { return static_cast<int>(extra_double_counter_track_uuids_.size()); }
+  void clear_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.clear(); }
+  void add_extra_double_counter_track_uuids(uint64_t value) { extra_double_counter_track_uuids_.emplace_back(value); }
+  uint64_t* add_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.emplace_back(); return &extra_double_counter_track_uuids_.back(); }
+
+ private:
+  uint64_t track_uuid_{};
+  std::vector<uint64_t> extra_counter_track_uuids_;
+  std::vector<uint64_t> extra_double_counter_track_uuids_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<46> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TrackEvent : public ::protozero::CppMessageObj {
+ public:
+  using LegacyEvent = TrackEvent_LegacyEvent;
+  using Type = TrackEvent_Type;
+  static constexpr auto TYPE_UNSPECIFIED = TrackEvent_Type_TYPE_UNSPECIFIED;
+  static constexpr auto TYPE_SLICE_BEGIN = TrackEvent_Type_TYPE_SLICE_BEGIN;
+  static constexpr auto TYPE_SLICE_END = TrackEvent_Type_TYPE_SLICE_END;
+  static constexpr auto TYPE_INSTANT = TrackEvent_Type_TYPE_INSTANT;
+  static constexpr auto TYPE_COUNTER = TrackEvent_Type_TYPE_COUNTER;
+  static constexpr auto Type_MIN = TrackEvent_Type_TYPE_UNSPECIFIED;
+  static constexpr auto Type_MAX = TrackEvent_Type_TYPE_COUNTER;
+  enum FieldNumbers {
+    kCategoryIidsFieldNumber = 3,
+    kCategoriesFieldNumber = 22,
+    kNameIidFieldNumber = 10,
+    kNameFieldNumber = 23,
+    kTypeFieldNumber = 9,
+    kTrackUuidFieldNumber = 11,
+    kCounterValueFieldNumber = 30,
+    kDoubleCounterValueFieldNumber = 44,
+    kExtraCounterTrackUuidsFieldNumber = 31,
+    kExtraCounterValuesFieldNumber = 12,
+    kExtraDoubleCounterTrackUuidsFieldNumber = 45,
+    kExtraDoubleCounterValuesFieldNumber = 46,
+    kFlowIdsOldFieldNumber = 36,
+    kFlowIdsFieldNumber = 47,
+    kTerminatingFlowIdsOldFieldNumber = 42,
+    kTerminatingFlowIdsFieldNumber = 48,
+    kDebugAnnotationsFieldNumber = 4,
+    kTaskExecutionFieldNumber = 5,
+    kLogMessageFieldNumber = 21,
+    kCcSchedulerStateFieldNumber = 24,
+    kChromeUserEventFieldNumber = 25,
+    kChromeKeyedServiceFieldNumber = 26,
+    kChromeLegacyIpcFieldNumber = 27,
+    kChromeHistogramSampleFieldNumber = 28,
+    kChromeLatencyInfoFieldNumber = 29,
+    kChromeFrameReporterFieldNumber = 32,
+    kChromeApplicationStateInfoFieldNumber = 39,
+    kChromeRendererSchedulerStateFieldNumber = 40,
+    kChromeWindowHandleEventInfoFieldNumber = 41,
+    kChromeContentSettingsEventInfoFieldNumber = 43,
+    kChromeActiveProcessesFieldNumber = 49,
+    kScreenshotFieldNumber = 50,
+    kSourceLocationFieldNumber = 33,
+    kSourceLocationIidFieldNumber = 34,
+    kChromeMessagePumpFieldNumber = 35,
+    kChromeMojoEventInfoFieldNumber = 38,
+    kTimestampDeltaUsFieldNumber = 1,
+    kTimestampAbsoluteUsFieldNumber = 16,
+    kThreadTimeDeltaUsFieldNumber = 2,
+    kThreadTimeAbsoluteUsFieldNumber = 17,
+    kThreadInstructionCountDeltaFieldNumber = 8,
+    kThreadInstructionCountAbsoluteFieldNumber = 20,
+    kLegacyEventFieldNumber = 6,
+  };
+
+  TrackEvent();
+  ~TrackEvent() override;
+  TrackEvent(TrackEvent&&) noexcept;
+  TrackEvent& operator=(TrackEvent&&);
+  TrackEvent(const TrackEvent&);
+  TrackEvent& operator=(const TrackEvent&);
+  bool operator==(const TrackEvent&) const;
+  bool operator!=(const TrackEvent& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<uint64_t>& category_iids() const { return category_iids_; }
+  std::vector<uint64_t>* mutable_category_iids() { return &category_iids_; }
+  int category_iids_size() const { return static_cast<int>(category_iids_.size()); }
+  void clear_category_iids() { category_iids_.clear(); }
+  void add_category_iids(uint64_t value) { category_iids_.emplace_back(value); }
+  uint64_t* add_category_iids() { category_iids_.emplace_back(); return &category_iids_.back(); }
+
+  const std::vector<std::string>& categories() const { return categories_; }
+  std::vector<std::string>* mutable_categories() { return &categories_; }
+  int categories_size() const { return static_cast<int>(categories_.size()); }
+  void clear_categories() { categories_.clear(); }
+  void add_categories(std::string value) { categories_.emplace_back(value); }
+  std::string* add_categories() { categories_.emplace_back(); return &categories_.back(); }
+
+  bool has_name_iid() const { return _has_field_[10]; }
+  uint64_t name_iid() const { return name_iid_; }
+  void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(10); }
+
+  bool has_name() const { return _has_field_[23]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(23); }
+
+  bool has_type() const { return _has_field_[9]; }
+  TrackEvent_Type type() const { return type_; }
+  void set_type(TrackEvent_Type value) { type_ = value; _has_field_.set(9); }
+
+  bool has_track_uuid() const { return _has_field_[11]; }
+  uint64_t track_uuid() const { return track_uuid_; }
+  void set_track_uuid(uint64_t value) { track_uuid_ = value; _has_field_.set(11); }
+
+  bool has_counter_value() const { return _has_field_[30]; }
+  int64_t counter_value() const { return counter_value_; }
+  void set_counter_value(int64_t value) { counter_value_ = value; _has_field_.set(30); }
+
+  bool has_double_counter_value() const { return _has_field_[44]; }
+  double double_counter_value() const { return double_counter_value_; }
+  void set_double_counter_value(double value) { double_counter_value_ = value; _has_field_.set(44); }
+
+  const std::vector<uint64_t>& extra_counter_track_uuids() const { return extra_counter_track_uuids_; }
+  std::vector<uint64_t>* mutable_extra_counter_track_uuids() { return &extra_counter_track_uuids_; }
+  int extra_counter_track_uuids_size() const { return static_cast<int>(extra_counter_track_uuids_.size()); }
+  void clear_extra_counter_track_uuids() { extra_counter_track_uuids_.clear(); }
+  void add_extra_counter_track_uuids(uint64_t value) { extra_counter_track_uuids_.emplace_back(value); }
+  uint64_t* add_extra_counter_track_uuids() { extra_counter_track_uuids_.emplace_back(); return &extra_counter_track_uuids_.back(); }
+
+  const std::vector<int64_t>& extra_counter_values() const { return extra_counter_values_; }
+  std::vector<int64_t>* mutable_extra_counter_values() { return &extra_counter_values_; }
+  int extra_counter_values_size() const { return static_cast<int>(extra_counter_values_.size()); }
+  void clear_extra_counter_values() { extra_counter_values_.clear(); }
+  void add_extra_counter_values(int64_t value) { extra_counter_values_.emplace_back(value); }
+  int64_t* add_extra_counter_values() { extra_counter_values_.emplace_back(); return &extra_counter_values_.back(); }
+
+  const std::vector<uint64_t>& extra_double_counter_track_uuids() const { return extra_double_counter_track_uuids_; }
+  std::vector<uint64_t>* mutable_extra_double_counter_track_uuids() { return &extra_double_counter_track_uuids_; }
+  int extra_double_counter_track_uuids_size() const { return static_cast<int>(extra_double_counter_track_uuids_.size()); }
+  void clear_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.clear(); }
+  void add_extra_double_counter_track_uuids(uint64_t value) { extra_double_counter_track_uuids_.emplace_back(value); }
+  uint64_t* add_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.emplace_back(); return &extra_double_counter_track_uuids_.back(); }
+
+  const std::vector<double>& extra_double_counter_values() const { return extra_double_counter_values_; }
+  std::vector<double>* mutable_extra_double_counter_values() { return &extra_double_counter_values_; }
+  int extra_double_counter_values_size() const { return static_cast<int>(extra_double_counter_values_.size()); }
+  void clear_extra_double_counter_values() { extra_double_counter_values_.clear(); }
+  void add_extra_double_counter_values(double value) { extra_double_counter_values_.emplace_back(value); }
+  double* add_extra_double_counter_values() { extra_double_counter_values_.emplace_back(); return &extra_double_counter_values_.back(); }
+
+  const std::vector<uint64_t>& flow_ids_old() const { return flow_ids_old_; }
+  std::vector<uint64_t>* mutable_flow_ids_old() { return &flow_ids_old_; }
+  int flow_ids_old_size() const { return static_cast<int>(flow_ids_old_.size()); }
+  void clear_flow_ids_old() { flow_ids_old_.clear(); }
+  void add_flow_ids_old(uint64_t value) { flow_ids_old_.emplace_back(value); }
+  uint64_t* add_flow_ids_old() { flow_ids_old_.emplace_back(); return &flow_ids_old_.back(); }
+
+  const std::vector<uint64_t>& flow_ids() const { return flow_ids_; }
+  std::vector<uint64_t>* mutable_flow_ids() { return &flow_ids_; }
+  int flow_ids_size() const { return static_cast<int>(flow_ids_.size()); }
+  void clear_flow_ids() { flow_ids_.clear(); }
+  void add_flow_ids(uint64_t value) { flow_ids_.emplace_back(value); }
+  uint64_t* add_flow_ids() { flow_ids_.emplace_back(); return &flow_ids_.back(); }
+
+  const std::vector<uint64_t>& terminating_flow_ids_old() const { return terminating_flow_ids_old_; }
+  std::vector<uint64_t>* mutable_terminating_flow_ids_old() { return &terminating_flow_ids_old_; }
+  int terminating_flow_ids_old_size() const { return static_cast<int>(terminating_flow_ids_old_.size()); }
+  void clear_terminating_flow_ids_old() { terminating_flow_ids_old_.clear(); }
+  void add_terminating_flow_ids_old(uint64_t value) { terminating_flow_ids_old_.emplace_back(value); }
+  uint64_t* add_terminating_flow_ids_old() { terminating_flow_ids_old_.emplace_back(); return &terminating_flow_ids_old_.back(); }
+
+  const std::vector<uint64_t>& terminating_flow_ids() const { return terminating_flow_ids_; }
+  std::vector<uint64_t>* mutable_terminating_flow_ids() { return &terminating_flow_ids_; }
+  int terminating_flow_ids_size() const { return static_cast<int>(terminating_flow_ids_.size()); }
+  void clear_terminating_flow_ids() { terminating_flow_ids_.clear(); }
+  void add_terminating_flow_ids(uint64_t value) { terminating_flow_ids_.emplace_back(value); }
+  uint64_t* add_terminating_flow_ids() { terminating_flow_ids_.emplace_back(); return &terminating_flow_ids_.back(); }
+
+  const std::vector<DebugAnnotation>& debug_annotations() const { return debug_annotations_; }
+  std::vector<DebugAnnotation>* mutable_debug_annotations() { return &debug_annotations_; }
+  int debug_annotations_size() const;
+  void clear_debug_annotations();
+  DebugAnnotation* add_debug_annotations();
+
+  bool has_task_execution() const { return _has_field_[5]; }
+  const TaskExecution& task_execution() const { return *task_execution_; }
+  TaskExecution* mutable_task_execution() { _has_field_.set(5); return task_execution_.get(); }
+
+  bool has_log_message() const { return _has_field_[21]; }
+  const LogMessage& log_message() const { return *log_message_; }
+  LogMessage* mutable_log_message() { _has_field_.set(21); return log_message_.get(); }
+
+  bool has_cc_scheduler_state() const { return _has_field_[24]; }
+  const ChromeCompositorSchedulerState& cc_scheduler_state() const { return *cc_scheduler_state_; }
+  ChromeCompositorSchedulerState* mutable_cc_scheduler_state() { _has_field_.set(24); return cc_scheduler_state_.get(); }
+
+  bool has_chrome_user_event() const { return _has_field_[25]; }
+  const ChromeUserEvent& chrome_user_event() const { return *chrome_user_event_; }
+  ChromeUserEvent* mutable_chrome_user_event() { _has_field_.set(25); return chrome_user_event_.get(); }
+
+  bool has_chrome_keyed_service() const { return _has_field_[26]; }
+  const ChromeKeyedService& chrome_keyed_service() const { return *chrome_keyed_service_; }
+  ChromeKeyedService* mutable_chrome_keyed_service() { _has_field_.set(26); return chrome_keyed_service_.get(); }
+
+  bool has_chrome_legacy_ipc() const { return _has_field_[27]; }
+  const ChromeLegacyIpc& chrome_legacy_ipc() const { return *chrome_legacy_ipc_; }
+  ChromeLegacyIpc* mutable_chrome_legacy_ipc() { _has_field_.set(27); return chrome_legacy_ipc_.get(); }
+
+  bool has_chrome_histogram_sample() const { return _has_field_[28]; }
+  const ChromeHistogramSample& chrome_histogram_sample() const { return *chrome_histogram_sample_; }
+  ChromeHistogramSample* mutable_chrome_histogram_sample() { _has_field_.set(28); return chrome_histogram_sample_.get(); }
+
+  bool has_chrome_latency_info() const { return _has_field_[29]; }
+  const ChromeLatencyInfo& chrome_latency_info() const { return *chrome_latency_info_; }
+  ChromeLatencyInfo* mutable_chrome_latency_info() { _has_field_.set(29); return chrome_latency_info_.get(); }
+
+  bool has_chrome_frame_reporter() const { return _has_field_[32]; }
+  const ChromeFrameReporter& chrome_frame_reporter() const { return *chrome_frame_reporter_; }
+  ChromeFrameReporter* mutable_chrome_frame_reporter() { _has_field_.set(32); return chrome_frame_reporter_.get(); }
+
+  bool has_chrome_application_state_info() const { return _has_field_[39]; }
+  const ChromeApplicationStateInfo& chrome_application_state_info() const { return *chrome_application_state_info_; }
+  ChromeApplicationStateInfo* mutable_chrome_application_state_info() { _has_field_.set(39); return chrome_application_state_info_.get(); }
+
+  bool has_chrome_renderer_scheduler_state() const { return _has_field_[40]; }
+  const ChromeRendererSchedulerState& chrome_renderer_scheduler_state() const { return *chrome_renderer_scheduler_state_; }
+  ChromeRendererSchedulerState* mutable_chrome_renderer_scheduler_state() { _has_field_.set(40); return chrome_renderer_scheduler_state_.get(); }
+
+  bool has_chrome_window_handle_event_info() const { return _has_field_[41]; }
+  const ChromeWindowHandleEventInfo& chrome_window_handle_event_info() const { return *chrome_window_handle_event_info_; }
+  ChromeWindowHandleEventInfo* mutable_chrome_window_handle_event_info() { _has_field_.set(41); return chrome_window_handle_event_info_.get(); }
+
+  bool has_chrome_content_settings_event_info() const { return _has_field_[43]; }
+  const ChromeContentSettingsEventInfo& chrome_content_settings_event_info() const { return *chrome_content_settings_event_info_; }
+  ChromeContentSettingsEventInfo* mutable_chrome_content_settings_event_info() { _has_field_.set(43); return chrome_content_settings_event_info_.get(); }
+
+  bool has_chrome_active_processes() const { return _has_field_[49]; }
+  const ChromeActiveProcesses& chrome_active_processes() const { return *chrome_active_processes_; }
+  ChromeActiveProcesses* mutable_chrome_active_processes() { _has_field_.set(49); return chrome_active_processes_.get(); }
+
+  bool has_screenshot() const { return _has_field_[50]; }
+  const Screenshot& screenshot() const { return *screenshot_; }
+  Screenshot* mutable_screenshot() { _has_field_.set(50); return screenshot_.get(); }
+
+  bool has_source_location() const { return _has_field_[33]; }
+  const SourceLocation& source_location() const { return *source_location_; }
+  SourceLocation* mutable_source_location() { _has_field_.set(33); return source_location_.get(); }
+
+  bool has_source_location_iid() const { return _has_field_[34]; }
+  uint64_t source_location_iid() const { return source_location_iid_; }
+  void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(34); }
+
+  bool has_chrome_message_pump() const { return _has_field_[35]; }
+  const ChromeMessagePump& chrome_message_pump() const { return *chrome_message_pump_; }
+  ChromeMessagePump* mutable_chrome_message_pump() { _has_field_.set(35); return chrome_message_pump_.get(); }
+
+  bool has_chrome_mojo_event_info() const { return _has_field_[38]; }
+  const ChromeMojoEventInfo& chrome_mojo_event_info() const { return *chrome_mojo_event_info_; }
+  ChromeMojoEventInfo* mutable_chrome_mojo_event_info() { _has_field_.set(38); return chrome_mojo_event_info_.get(); }
+
+  bool has_timestamp_delta_us() const { return _has_field_[1]; }
+  int64_t timestamp_delta_us() const { return timestamp_delta_us_; }
+  void set_timestamp_delta_us(int64_t value) { timestamp_delta_us_ = value; _has_field_.set(1); }
+
+  bool has_timestamp_absolute_us() const { return _has_field_[16]; }
+  int64_t timestamp_absolute_us() const { return timestamp_absolute_us_; }
+  void set_timestamp_absolute_us(int64_t value) { timestamp_absolute_us_ = value; _has_field_.set(16); }
+
+  bool has_thread_time_delta_us() const { return _has_field_[2]; }
+  int64_t thread_time_delta_us() const { return thread_time_delta_us_; }
+  void set_thread_time_delta_us(int64_t value) { thread_time_delta_us_ = value; _has_field_.set(2); }
+
+  bool has_thread_time_absolute_us() const { return _has_field_[17]; }
+  int64_t thread_time_absolute_us() const { return thread_time_absolute_us_; }
+  void set_thread_time_absolute_us(int64_t value) { thread_time_absolute_us_ = value; _has_field_.set(17); }
+
+  bool has_thread_instruction_count_delta() const { return _has_field_[8]; }
+  int64_t thread_instruction_count_delta() const { return thread_instruction_count_delta_; }
+  void set_thread_instruction_count_delta(int64_t value) { thread_instruction_count_delta_ = value; _has_field_.set(8); }
+
+  bool has_thread_instruction_count_absolute() const { return _has_field_[20]; }
+  int64_t thread_instruction_count_absolute() const { return thread_instruction_count_absolute_; }
+  void set_thread_instruction_count_absolute(int64_t value) { thread_instruction_count_absolute_ = value; _has_field_.set(20); }
+
+  bool has_legacy_event() const { return _has_field_[6]; }
+  const TrackEvent_LegacyEvent& legacy_event() const { return *legacy_event_; }
+  TrackEvent_LegacyEvent* mutable_legacy_event() { _has_field_.set(6); return legacy_event_.get(); }
+
+ private:
+  std::vector<uint64_t> category_iids_;
+  std::vector<std::string> categories_;
+  uint64_t name_iid_{};
+  std::string name_{};
+  TrackEvent_Type type_{};
+  uint64_t track_uuid_{};
+  int64_t counter_value_{};
+  double double_counter_value_{};
+  std::vector<uint64_t> extra_counter_track_uuids_;
+  std::vector<int64_t> extra_counter_values_;
+  std::vector<uint64_t> extra_double_counter_track_uuids_;
+  std::vector<double> extra_double_counter_values_;
+  std::vector<uint64_t> flow_ids_old_;
+  std::vector<uint64_t> flow_ids_;
+  std::vector<uint64_t> terminating_flow_ids_old_;
+  std::vector<uint64_t> terminating_flow_ids_;
+  std::vector<DebugAnnotation> debug_annotations_;
+  ::protozero::CopyablePtr<TaskExecution> task_execution_;
+  ::protozero::CopyablePtr<LogMessage> log_message_;
+  ::protozero::CopyablePtr<ChromeCompositorSchedulerState> cc_scheduler_state_;
+  ::protozero::CopyablePtr<ChromeUserEvent> chrome_user_event_;
+  ::protozero::CopyablePtr<ChromeKeyedService> chrome_keyed_service_;
+  ::protozero::CopyablePtr<ChromeLegacyIpc> chrome_legacy_ipc_;
+  ::protozero::CopyablePtr<ChromeHistogramSample> chrome_histogram_sample_;
+  ::protozero::CopyablePtr<ChromeLatencyInfo> chrome_latency_info_;
+  ::protozero::CopyablePtr<ChromeFrameReporter> chrome_frame_reporter_;
+  ::protozero::CopyablePtr<ChromeApplicationStateInfo> chrome_application_state_info_;
+  ::protozero::CopyablePtr<ChromeRendererSchedulerState> chrome_renderer_scheduler_state_;
+  ::protozero::CopyablePtr<ChromeWindowHandleEventInfo> chrome_window_handle_event_info_;
+  ::protozero::CopyablePtr<ChromeContentSettingsEventInfo> chrome_content_settings_event_info_;
+  ::protozero::CopyablePtr<ChromeActiveProcesses> chrome_active_processes_;
+  ::protozero::CopyablePtr<Screenshot> screenshot_;
+  ::protozero::CopyablePtr<SourceLocation> source_location_;
+  uint64_t source_location_iid_{};
+  ::protozero::CopyablePtr<ChromeMessagePump> chrome_message_pump_;
+  ::protozero::CopyablePtr<ChromeMojoEventInfo> chrome_mojo_event_info_;
+  int64_t timestamp_delta_us_{};
+  int64_t timestamp_absolute_us_{};
+  int64_t thread_time_delta_us_{};
+  int64_t thread_time_absolute_us_{};
+  int64_t thread_instruction_count_delta_{};
+  int64_t thread_instruction_count_absolute_{};
+  ::protozero::CopyablePtr<TrackEvent_LegacyEvent> legacy_event_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<51> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT TrackEvent_LegacyEvent : public ::protozero::CppMessageObj {
+ public:
+  using FlowDirection = TrackEvent_LegacyEvent_FlowDirection;
+  static constexpr auto FLOW_UNSPECIFIED = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
+  static constexpr auto FLOW_IN = TrackEvent_LegacyEvent_FlowDirection_FLOW_IN;
+  static constexpr auto FLOW_OUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT;
+  static constexpr auto FLOW_INOUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
+  static constexpr auto FlowDirection_MIN = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
+  static constexpr auto FlowDirection_MAX = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
+  using InstantEventScope = TrackEvent_LegacyEvent_InstantEventScope;
+  static constexpr auto SCOPE_UNSPECIFIED = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
+  static constexpr auto SCOPE_GLOBAL = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL;
+  static constexpr auto SCOPE_PROCESS = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS;
+  static constexpr auto SCOPE_THREAD = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
+  static constexpr auto InstantEventScope_MIN = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
+  static constexpr auto InstantEventScope_MAX = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
+  enum FieldNumbers {
+    kNameIidFieldNumber = 1,
+    kPhaseFieldNumber = 2,
+    kDurationUsFieldNumber = 3,
+    kThreadDurationUsFieldNumber = 4,
+    kThreadInstructionDeltaFieldNumber = 15,
+    kUnscopedIdFieldNumber = 6,
+    kLocalIdFieldNumber = 10,
+    kGlobalIdFieldNumber = 11,
+    kIdScopeFieldNumber = 7,
+    kUseAsyncTtsFieldNumber = 9,
+    kBindIdFieldNumber = 8,
+    kBindToEnclosingFieldNumber = 12,
+    kFlowDirectionFieldNumber = 13,
+    kInstantEventScopeFieldNumber = 14,
+    kPidOverrideFieldNumber = 18,
+    kTidOverrideFieldNumber = 19,
+  };
+
+  TrackEvent_LegacyEvent();
+  ~TrackEvent_LegacyEvent() override;
+  TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept;
+  TrackEvent_LegacyEvent& operator=(TrackEvent_LegacyEvent&&);
+  TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&);
+  TrackEvent_LegacyEvent& operator=(const TrackEvent_LegacyEvent&);
+  bool operator==(const TrackEvent_LegacyEvent&) const;
+  bool operator!=(const TrackEvent_LegacyEvent& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_name_iid() const { return _has_field_[1]; }
+  uint64_t name_iid() const { return name_iid_; }
+  void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(1); }
+
+  bool has_phase() const { return _has_field_[2]; }
+  int32_t phase() const { return phase_; }
+  void set_phase(int32_t value) { phase_ = value; _has_field_.set(2); }
+
+  bool has_duration_us() const { return _has_field_[3]; }
+  int64_t duration_us() const { return duration_us_; }
+  void set_duration_us(int64_t value) { duration_us_ = value; _has_field_.set(3); }
+
+  bool has_thread_duration_us() const { return _has_field_[4]; }
+  int64_t thread_duration_us() const { return thread_duration_us_; }
+  void set_thread_duration_us(int64_t value) { thread_duration_us_ = value; _has_field_.set(4); }
+
+  bool has_thread_instruction_delta() const { return _has_field_[15]; }
+  int64_t thread_instruction_delta() const { return thread_instruction_delta_; }
+  void set_thread_instruction_delta(int64_t value) { thread_instruction_delta_ = value; _has_field_.set(15); }
+
+  bool has_unscoped_id() const { return _has_field_[6]; }
+  uint64_t unscoped_id() const { return unscoped_id_; }
+  void set_unscoped_id(uint64_t value) { unscoped_id_ = value; _has_field_.set(6); }
+
+  bool has_local_id() const { return _has_field_[10]; }
+  uint64_t local_id() const { return local_id_; }
+  void set_local_id(uint64_t value) { local_id_ = value; _has_field_.set(10); }
+
+  bool has_global_id() const { return _has_field_[11]; }
+  uint64_t global_id() const { return global_id_; }
+  void set_global_id(uint64_t value) { global_id_ = value; _has_field_.set(11); }
+
+  bool has_id_scope() const { return _has_field_[7]; }
+  const std::string& id_scope() const { return id_scope_; }
+  void set_id_scope(const std::string& value) { id_scope_ = value; _has_field_.set(7); }
+
+  bool has_use_async_tts() const { return _has_field_[9]; }
+  bool use_async_tts() const { return use_async_tts_; }
+  void set_use_async_tts(bool value) { use_async_tts_ = value; _has_field_.set(9); }
+
+  bool has_bind_id() const { return _has_field_[8]; }
+  uint64_t bind_id() const { return bind_id_; }
+  void set_bind_id(uint64_t value) { bind_id_ = value; _has_field_.set(8); }
+
+  bool has_bind_to_enclosing() const { return _has_field_[12]; }
+  bool bind_to_enclosing() const { return bind_to_enclosing_; }
+  void set_bind_to_enclosing(bool value) { bind_to_enclosing_ = value; _has_field_.set(12); }
+
+  bool has_flow_direction() const { return _has_field_[13]; }
+  TrackEvent_LegacyEvent_FlowDirection flow_direction() const { return flow_direction_; }
+  void set_flow_direction(TrackEvent_LegacyEvent_FlowDirection value) { flow_direction_ = value; _has_field_.set(13); }
+
+  bool has_instant_event_scope() const { return _has_field_[14]; }
+  TrackEvent_LegacyEvent_InstantEventScope instant_event_scope() const { return instant_event_scope_; }
+  void set_instant_event_scope(TrackEvent_LegacyEvent_InstantEventScope value) { instant_event_scope_ = value; _has_field_.set(14); }
+
+  bool has_pid_override() const { return _has_field_[18]; }
+  int32_t pid_override() const { return pid_override_; }
+  void set_pid_override(int32_t value) { pid_override_ = value; _has_field_.set(18); }
+
+  bool has_tid_override() const { return _has_field_[19]; }
+  int32_t tid_override() const { return tid_override_; }
+  void set_tid_override(int32_t value) { tid_override_ = value; _has_field_.set(19); }
+
+ private:
+  uint64_t name_iid_{};
+  int32_t phase_{};
+  int64_t duration_us_{};
+  int64_t thread_duration_us_{};
+  int64_t thread_instruction_delta_{};
+  uint64_t unscoped_id_{};
+  uint64_t local_id_{};
+  uint64_t global_id_{};
+  std::string id_scope_{};
+  bool use_async_tts_{};
+  uint64_t bind_id_{};
+  bool bind_to_enclosing_{};
+  TrackEvent_LegacyEvent_FlowDirection flow_direction_{};
+  TrackEvent_LegacyEvent_InstantEventScope instant_event_scope_{};
+  int32_t pid_override_{};
+  int32_t tid_override_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<20> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class CloneSessionResponse;
+class CloneSessionRequest;
+class SaveTraceForBugreportResponse;
+class SaveTraceForBugreportRequest;
+class QueryCapabilitiesResponse;
+class TracingServiceCapabilities;
+class QueryCapabilitiesRequest;
+class QueryServiceStateResponse;
+class TracingServiceState;
+class TracingServiceState_TracingSession;
+class TracingServiceState_DataSource;
+class DataSourceDescriptor;
+class TracingServiceState_Producer;
+class QueryServiceStateRequest;
+class ObserveEventsResponse;
+class ObservableEvents;
+class ObservableEvents_CloneTriggerHit;
+class ObservableEvents_DataSourceInstanceStateChange;
+class ObserveEventsRequest;
+class GetTraceStatsResponse;
+class TraceStats;
+class TraceStats_FilterStats;
+class TraceStats_WriterStats;
+class TraceStats_BufferStats;
+class GetTraceStatsRequest;
+class AttachResponse;
+class TraceConfig;
+class TraceConfig_CmdTraceStartDelay;
+class TraceConfig_AndroidReportConfig;
+class TraceConfig_TraceFilter;
+class TraceConfig_TraceFilter_StringFilterChain;
+class TraceConfig_TraceFilter_StringFilterRule;
+class TraceConfig_IncidentReportConfig;
+class TraceConfig_IncrementalStateConfig;
+class TraceConfig_TriggerConfig;
+class TraceConfig_TriggerConfig_Trigger;
+class TraceConfig_GuardrailOverrides;
+class TraceConfig_StatsdMetadata;
+class TraceConfig_ProducerConfig;
+class TraceConfig_BuiltinDataSource;
+class TraceConfig_DataSource;
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+class TraceConfig_BufferConfig;
+class AttachRequest;
+class DetachResponse;
+class DetachRequest;
+class FlushResponse;
+class FlushRequest;
+class FreeBuffersResponse;
+class FreeBuffersRequest;
+class ReadBuffersResponse;
+class ReadBuffersResponse_Slice;
+class ReadBuffersRequest;
+class DisableTracingResponse;
+class DisableTracingRequest;
+class ChangeTraceConfigResponse;
+class ChangeTraceConfigRequest;
+class StartTracingResponse;
+class StartTracingRequest;
+class EnableTracingResponse;
+class EnableTracingRequest;
+enum ObservableEvents_Type : int;
+enum ObservableEvents_DataSourceInstanceState : int;
+enum TraceStats_FinalFlushOutcome : int;
+enum TraceConfig_LockdownModeOperation : int;
+enum TraceConfig_CompressionType : int;
+enum TraceConfig_StatsdLogging : int;
+enum TraceConfig_TraceFilter_StringFilterPolicy : int;
+enum TraceConfig_TriggerConfig_TriggerMode : int;
+enum BuiltinClock : int;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+enum TraceConfig_BufferConfig_FillPolicy : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT CloneSessionResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSuccessFieldNumber = 1,
+    kErrorFieldNumber = 2,
+    kUuidMsbFieldNumber = 3,
+    kUuidLsbFieldNumber = 4,
+  };
+
+  CloneSessionResponse();
+  ~CloneSessionResponse() override;
+  CloneSessionResponse(CloneSessionResponse&&) noexcept;
+  CloneSessionResponse& operator=(CloneSessionResponse&&);
+  CloneSessionResponse(const CloneSessionResponse&);
+  CloneSessionResponse& operator=(const CloneSessionResponse&);
+  bool operator==(const CloneSessionResponse&) const;
+  bool operator!=(const CloneSessionResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_success() const { return _has_field_[1]; }
+  bool success() const { return success_; }
+  void set_success(bool value) { success_ = value; _has_field_.set(1); }
+
+  bool has_error() const { return _has_field_[2]; }
+  const std::string& error() const { return error_; }
+  void set_error(const std::string& value) { error_ = value; _has_field_.set(2); }
+
+  bool has_uuid_msb() const { return _has_field_[3]; }
+  int64_t uuid_msb() const { return uuid_msb_; }
+  void set_uuid_msb(int64_t value) { uuid_msb_ = value; _has_field_.set(3); }
+
+  bool has_uuid_lsb() const { return _has_field_[4]; }
+  int64_t uuid_lsb() const { return uuid_lsb_; }
+  void set_uuid_lsb(int64_t value) { uuid_lsb_ = value; _has_field_.set(4); }
+
+ private:
+  bool success_{};
+  std::string error_{};
+  int64_t uuid_msb_{};
+  int64_t uuid_lsb_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT CloneSessionRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSessionIdFieldNumber = 1,
+  };
+
+  CloneSessionRequest();
+  ~CloneSessionRequest() override;
+  CloneSessionRequest(CloneSessionRequest&&) noexcept;
+  CloneSessionRequest& operator=(CloneSessionRequest&&);
+  CloneSessionRequest(const CloneSessionRequest&);
+  CloneSessionRequest& operator=(const CloneSessionRequest&);
+  bool operator==(const CloneSessionRequest&) const;
+  bool operator!=(const CloneSessionRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_session_id() const { return _has_field_[1]; }
+  uint64_t session_id() const { return session_id_; }
+  void set_session_id(uint64_t value) { session_id_ = value; _has_field_.set(1); }
+
+ private:
+  uint64_t session_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT SaveTraceForBugreportResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSuccessFieldNumber = 1,
+    kMsgFieldNumber = 2,
+  };
+
+  SaveTraceForBugreportResponse();
+  ~SaveTraceForBugreportResponse() override;
+  SaveTraceForBugreportResponse(SaveTraceForBugreportResponse&&) noexcept;
+  SaveTraceForBugreportResponse& operator=(SaveTraceForBugreportResponse&&);
+  SaveTraceForBugreportResponse(const SaveTraceForBugreportResponse&);
+  SaveTraceForBugreportResponse& operator=(const SaveTraceForBugreportResponse&);
+  bool operator==(const SaveTraceForBugreportResponse&) const;
+  bool operator!=(const SaveTraceForBugreportResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_success() const { return _has_field_[1]; }
+  bool success() const { return success_; }
+  void set_success(bool value) { success_ = value; _has_field_.set(1); }
+
+  bool has_msg() const { return _has_field_[2]; }
+  const std::string& msg() const { return msg_; }
+  void set_msg(const std::string& value) { msg_ = value; _has_field_.set(2); }
+
+ private:
+  bool success_{};
+  std::string msg_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT SaveTraceForBugreportRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  SaveTraceForBugreportRequest();
+  ~SaveTraceForBugreportRequest() override;
+  SaveTraceForBugreportRequest(SaveTraceForBugreportRequest&&) noexcept;
+  SaveTraceForBugreportRequest& operator=(SaveTraceForBugreportRequest&&);
+  SaveTraceForBugreportRequest(const SaveTraceForBugreportRequest&);
+  SaveTraceForBugreportRequest& operator=(const SaveTraceForBugreportRequest&);
+  bool operator==(const SaveTraceForBugreportRequest&) const;
+  bool operator!=(const SaveTraceForBugreportRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT QueryCapabilitiesResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kCapabilitiesFieldNumber = 1,
+  };
+
+  QueryCapabilitiesResponse();
+  ~QueryCapabilitiesResponse() override;
+  QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept;
+  QueryCapabilitiesResponse& operator=(QueryCapabilitiesResponse&&);
+  QueryCapabilitiesResponse(const QueryCapabilitiesResponse&);
+  QueryCapabilitiesResponse& operator=(const QueryCapabilitiesResponse&);
+  bool operator==(const QueryCapabilitiesResponse&) const;
+  bool operator!=(const QueryCapabilitiesResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_capabilities() const { return _has_field_[1]; }
+  const TracingServiceCapabilities& capabilities() const { return *capabilities_; }
+  TracingServiceCapabilities* mutable_capabilities() { _has_field_.set(1); return capabilities_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TracingServiceCapabilities> capabilities_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT QueryCapabilitiesRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  QueryCapabilitiesRequest();
+  ~QueryCapabilitiesRequest() override;
+  QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept;
+  QueryCapabilitiesRequest& operator=(QueryCapabilitiesRequest&&);
+  QueryCapabilitiesRequest(const QueryCapabilitiesRequest&);
+  QueryCapabilitiesRequest& operator=(const QueryCapabilitiesRequest&);
+  bool operator==(const QueryCapabilitiesRequest&) const;
+  bool operator!=(const QueryCapabilitiesRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT QueryServiceStateResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kServiceStateFieldNumber = 1,
+  };
+
+  QueryServiceStateResponse();
+  ~QueryServiceStateResponse() override;
+  QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept;
+  QueryServiceStateResponse& operator=(QueryServiceStateResponse&&);
+  QueryServiceStateResponse(const QueryServiceStateResponse&);
+  QueryServiceStateResponse& operator=(const QueryServiceStateResponse&);
+  bool operator==(const QueryServiceStateResponse&) const;
+  bool operator!=(const QueryServiceStateResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_service_state() const { return _has_field_[1]; }
+  const TracingServiceState& service_state() const { return *service_state_; }
+  TracingServiceState* mutable_service_state() { _has_field_.set(1); return service_state_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TracingServiceState> service_state_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT QueryServiceStateRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  QueryServiceStateRequest();
+  ~QueryServiceStateRequest() override;
+  QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept;
+  QueryServiceStateRequest& operator=(QueryServiceStateRequest&&);
+  QueryServiceStateRequest(const QueryServiceStateRequest&);
+  QueryServiceStateRequest& operator=(const QueryServiceStateRequest&);
+  bool operator==(const QueryServiceStateRequest&) const;
+  bool operator!=(const QueryServiceStateRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ObserveEventsResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kEventsFieldNumber = 1,
+  };
+
+  ObserveEventsResponse();
+  ~ObserveEventsResponse() override;
+  ObserveEventsResponse(ObserveEventsResponse&&) noexcept;
+  ObserveEventsResponse& operator=(ObserveEventsResponse&&);
+  ObserveEventsResponse(const ObserveEventsResponse&);
+  ObserveEventsResponse& operator=(const ObserveEventsResponse&);
+  bool operator==(const ObserveEventsResponse&) const;
+  bool operator!=(const ObserveEventsResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_events() const { return _has_field_[1]; }
+  const ObservableEvents& events() const { return *events_; }
+  ObservableEvents* mutable_events() { _has_field_.set(1); return events_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<ObservableEvents> events_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ObserveEventsRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kEventsToObserveFieldNumber = 1,
+  };
+
+  ObserveEventsRequest();
+  ~ObserveEventsRequest() override;
+  ObserveEventsRequest(ObserveEventsRequest&&) noexcept;
+  ObserveEventsRequest& operator=(ObserveEventsRequest&&);
+  ObserveEventsRequest(const ObserveEventsRequest&);
+  ObserveEventsRequest& operator=(const ObserveEventsRequest&);
+  bool operator==(const ObserveEventsRequest&) const;
+  bool operator!=(const ObserveEventsRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ObservableEvents_Type>& events_to_observe() const { return events_to_observe_; }
+  std::vector<ObservableEvents_Type>* mutable_events_to_observe() { return &events_to_observe_; }
+  int events_to_observe_size() const { return static_cast<int>(events_to_observe_.size()); }
+  void clear_events_to_observe() { events_to_observe_.clear(); }
+  void add_events_to_observe(ObservableEvents_Type value) { events_to_observe_.emplace_back(value); }
+  ObservableEvents_Type* add_events_to_observe() { events_to_observe_.emplace_back(); return &events_to_observe_.back(); }
+
+ private:
+  std::vector<ObservableEvents_Type> events_to_observe_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetTraceStatsResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceStatsFieldNumber = 1,
+  };
+
+  GetTraceStatsResponse();
+  ~GetTraceStatsResponse() override;
+  GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept;
+  GetTraceStatsResponse& operator=(GetTraceStatsResponse&&);
+  GetTraceStatsResponse(const GetTraceStatsResponse&);
+  GetTraceStatsResponse& operator=(const GetTraceStatsResponse&);
+  bool operator==(const GetTraceStatsResponse&) const;
+  bool operator!=(const GetTraceStatsResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_stats() const { return _has_field_[1]; }
+  const TraceStats& trace_stats() const { return *trace_stats_; }
+  TraceStats* mutable_trace_stats() { _has_field_.set(1); return trace_stats_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TraceStats> trace_stats_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetTraceStatsRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  GetTraceStatsRequest();
+  ~GetTraceStatsRequest() override;
+  GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept;
+  GetTraceStatsRequest& operator=(GetTraceStatsRequest&&);
+  GetTraceStatsRequest(const GetTraceStatsRequest&);
+  GetTraceStatsRequest& operator=(const GetTraceStatsRequest&);
+  bool operator==(const GetTraceStatsRequest&) const;
+  bool operator!=(const GetTraceStatsRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT AttachResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceConfigFieldNumber = 1,
+  };
+
+  AttachResponse();
+  ~AttachResponse() override;
+  AttachResponse(AttachResponse&&) noexcept;
+  AttachResponse& operator=(AttachResponse&&);
+  AttachResponse(const AttachResponse&);
+  AttachResponse& operator=(const AttachResponse&);
+  bool operator==(const AttachResponse&) const;
+  bool operator!=(const AttachResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_config() const { return _has_field_[1]; }
+  const TraceConfig& trace_config() const { return *trace_config_; }
+  TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TraceConfig> trace_config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT AttachRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kKeyFieldNumber = 1,
+  };
+
+  AttachRequest();
+  ~AttachRequest() override;
+  AttachRequest(AttachRequest&&) noexcept;
+  AttachRequest& operator=(AttachRequest&&);
+  AttachRequest(const AttachRequest&);
+  AttachRequest& operator=(const AttachRequest&);
+  bool operator==(const AttachRequest&) const;
+  bool operator!=(const AttachRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_key() const { return _has_field_[1]; }
+  const std::string& key() const { return key_; }
+  void set_key(const std::string& value) { key_ = value; _has_field_.set(1); }
+
+ private:
+  std::string key_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DetachResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  DetachResponse();
+  ~DetachResponse() override;
+  DetachResponse(DetachResponse&&) noexcept;
+  DetachResponse& operator=(DetachResponse&&);
+  DetachResponse(const DetachResponse&);
+  DetachResponse& operator=(const DetachResponse&);
+  bool operator==(const DetachResponse&) const;
+  bool operator!=(const DetachResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DetachRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kKeyFieldNumber = 1,
+  };
+
+  DetachRequest();
+  ~DetachRequest() override;
+  DetachRequest(DetachRequest&&) noexcept;
+  DetachRequest& operator=(DetachRequest&&);
+  DetachRequest(const DetachRequest&);
+  DetachRequest& operator=(const DetachRequest&);
+  bool operator==(const DetachRequest&) const;
+  bool operator!=(const DetachRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_key() const { return _has_field_[1]; }
+  const std::string& key() const { return key_; }
+  void set_key(const std::string& value) { key_ = value; _has_field_.set(1); }
+
+ private:
+  std::string key_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FlushResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  FlushResponse();
+  ~FlushResponse() override;
+  FlushResponse(FlushResponse&&) noexcept;
+  FlushResponse& operator=(FlushResponse&&);
+  FlushResponse(const FlushResponse&);
+  FlushResponse& operator=(const FlushResponse&);
+  bool operator==(const FlushResponse&) const;
+  bool operator!=(const FlushResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FlushRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTimeoutMsFieldNumber = 1,
+    kFlagsFieldNumber = 2,
+  };
+
+  FlushRequest();
+  ~FlushRequest() override;
+  FlushRequest(FlushRequest&&) noexcept;
+  FlushRequest& operator=(FlushRequest&&);
+  FlushRequest(const FlushRequest&);
+  FlushRequest& operator=(const FlushRequest&);
+  bool operator==(const FlushRequest&) const;
+  bool operator!=(const FlushRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_timeout_ms() const { return _has_field_[1]; }
+  uint32_t timeout_ms() const { return timeout_ms_; }
+  void set_timeout_ms(uint32_t value) { timeout_ms_ = value; _has_field_.set(1); }
+
+  bool has_flags() const { return _has_field_[2]; }
+  uint64_t flags() const { return flags_; }
+  void set_flags(uint64_t value) { flags_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t timeout_ms_{};
+  uint64_t flags_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FreeBuffersResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  FreeBuffersResponse();
+  ~FreeBuffersResponse() override;
+  FreeBuffersResponse(FreeBuffersResponse&&) noexcept;
+  FreeBuffersResponse& operator=(FreeBuffersResponse&&);
+  FreeBuffersResponse(const FreeBuffersResponse&);
+  FreeBuffersResponse& operator=(const FreeBuffersResponse&);
+  bool operator==(const FreeBuffersResponse&) const;
+  bool operator!=(const FreeBuffersResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT FreeBuffersRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kBufferIdsFieldNumber = 1,
+  };
+
+  FreeBuffersRequest();
+  ~FreeBuffersRequest() override;
+  FreeBuffersRequest(FreeBuffersRequest&&) noexcept;
+  FreeBuffersRequest& operator=(FreeBuffersRequest&&);
+  FreeBuffersRequest(const FreeBuffersRequest&);
+  FreeBuffersRequest& operator=(const FreeBuffersRequest&);
+  bool operator==(const FreeBuffersRequest&) const;
+  bool operator!=(const FreeBuffersRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<uint32_t>& buffer_ids() const { return buffer_ids_; }
+  std::vector<uint32_t>* mutable_buffer_ids() { return &buffer_ids_; }
+  int buffer_ids_size() const { return static_cast<int>(buffer_ids_.size()); }
+  void clear_buffer_ids() { buffer_ids_.clear(); }
+  void add_buffer_ids(uint32_t value) { buffer_ids_.emplace_back(value); }
+  uint32_t* add_buffer_ids() { buffer_ids_.emplace_back(); return &buffer_ids_.back(); }
+
+ private:
+  std::vector<uint32_t> buffer_ids_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ReadBuffersResponse : public ::protozero::CppMessageObj {
+ public:
+  using Slice = ReadBuffersResponse_Slice;
+  enum FieldNumbers {
+    kSlicesFieldNumber = 2,
+  };
+
+  ReadBuffersResponse();
+  ~ReadBuffersResponse() override;
+  ReadBuffersResponse(ReadBuffersResponse&&) noexcept;
+  ReadBuffersResponse& operator=(ReadBuffersResponse&&);
+  ReadBuffersResponse(const ReadBuffersResponse&);
+  ReadBuffersResponse& operator=(const ReadBuffersResponse&);
+  bool operator==(const ReadBuffersResponse&) const;
+  bool operator!=(const ReadBuffersResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<ReadBuffersResponse_Slice>& slices() const { return slices_; }
+  std::vector<ReadBuffersResponse_Slice>* mutable_slices() { return &slices_; }
+  int slices_size() const;
+  void clear_slices();
+  ReadBuffersResponse_Slice* add_slices();
+
+ private:
+  std::vector<ReadBuffersResponse_Slice> slices_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ReadBuffersResponse_Slice : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataFieldNumber = 1,
+    kLastSliceForPacketFieldNumber = 2,
+  };
+
+  ReadBuffersResponse_Slice();
+  ~ReadBuffersResponse_Slice() override;
+  ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept;
+  ReadBuffersResponse_Slice& operator=(ReadBuffersResponse_Slice&&);
+  ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&);
+  ReadBuffersResponse_Slice& operator=(const ReadBuffersResponse_Slice&);
+  bool operator==(const ReadBuffersResponse_Slice&) const;
+  bool operator!=(const ReadBuffersResponse_Slice& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data() const { return _has_field_[1]; }
+  const std::string& data() const { return data_; }
+  void set_data(const std::string& value) { data_ = value; _has_field_.set(1); }
+  void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(1); }
+
+  bool has_last_slice_for_packet() const { return _has_field_[2]; }
+  bool last_slice_for_packet() const { return last_slice_for_packet_; }
+  void set_last_slice_for_packet(bool value) { last_slice_for_packet_ = value; _has_field_.set(2); }
+
+ private:
+  std::string data_{};
+  bool last_slice_for_packet_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ReadBuffersRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  ReadBuffersRequest();
+  ~ReadBuffersRequest() override;
+  ReadBuffersRequest(ReadBuffersRequest&&) noexcept;
+  ReadBuffersRequest& operator=(ReadBuffersRequest&&);
+  ReadBuffersRequest(const ReadBuffersRequest&);
+  ReadBuffersRequest& operator=(const ReadBuffersRequest&);
+  bool operator==(const ReadBuffersRequest&) const;
+  bool operator!=(const ReadBuffersRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DisableTracingResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  DisableTracingResponse();
+  ~DisableTracingResponse() override;
+  DisableTracingResponse(DisableTracingResponse&&) noexcept;
+  DisableTracingResponse& operator=(DisableTracingResponse&&);
+  DisableTracingResponse(const DisableTracingResponse&);
+  DisableTracingResponse& operator=(const DisableTracingResponse&);
+  bool operator==(const DisableTracingResponse&) const;
+  bool operator!=(const DisableTracingResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT DisableTracingRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  DisableTracingRequest();
+  ~DisableTracingRequest() override;
+  DisableTracingRequest(DisableTracingRequest&&) noexcept;
+  DisableTracingRequest& operator=(DisableTracingRequest&&);
+  DisableTracingRequest(const DisableTracingRequest&);
+  DisableTracingRequest& operator=(const DisableTracingRequest&);
+  bool operator==(const DisableTracingRequest&) const;
+  bool operator!=(const DisableTracingRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChangeTraceConfigResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  ChangeTraceConfigResponse();
+  ~ChangeTraceConfigResponse() override;
+  ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept;
+  ChangeTraceConfigResponse& operator=(ChangeTraceConfigResponse&&);
+  ChangeTraceConfigResponse(const ChangeTraceConfigResponse&);
+  ChangeTraceConfigResponse& operator=(const ChangeTraceConfigResponse&);
+  bool operator==(const ChangeTraceConfigResponse&) const;
+  bool operator!=(const ChangeTraceConfigResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ChangeTraceConfigRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceConfigFieldNumber = 1,
+  };
+
+  ChangeTraceConfigRequest();
+  ~ChangeTraceConfigRequest() override;
+  ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept;
+  ChangeTraceConfigRequest& operator=(ChangeTraceConfigRequest&&);
+  ChangeTraceConfigRequest(const ChangeTraceConfigRequest&);
+  ChangeTraceConfigRequest& operator=(const ChangeTraceConfigRequest&);
+  bool operator==(const ChangeTraceConfigRequest&) const;
+  bool operator!=(const ChangeTraceConfigRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_config() const { return _has_field_[1]; }
+  const TraceConfig& trace_config() const { return *trace_config_; }
+  TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<TraceConfig> trace_config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT StartTracingResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  StartTracingResponse();
+  ~StartTracingResponse() override;
+  StartTracingResponse(StartTracingResponse&&) noexcept;
+  StartTracingResponse& operator=(StartTracingResponse&&);
+  StartTracingResponse(const StartTracingResponse&);
+  StartTracingResponse& operator=(const StartTracingResponse&);
+  bool operator==(const StartTracingResponse&) const;
+  bool operator!=(const StartTracingResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT StartTracingRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  StartTracingRequest();
+  ~StartTracingRequest() override;
+  StartTracingRequest(StartTracingRequest&&) noexcept;
+  StartTracingRequest& operator=(StartTracingRequest&&);
+  StartTracingRequest(const StartTracingRequest&);
+  StartTracingRequest& operator=(const StartTracingRequest&);
+  bool operator==(const StartTracingRequest&) const;
+  bool operator!=(const StartTracingRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT EnableTracingResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDisabledFieldNumber = 1,
+    kErrorFieldNumber = 3,
+  };
+
+  EnableTracingResponse();
+  ~EnableTracingResponse() override;
+  EnableTracingResponse(EnableTracingResponse&&) noexcept;
+  EnableTracingResponse& operator=(EnableTracingResponse&&);
+  EnableTracingResponse(const EnableTracingResponse&);
+  EnableTracingResponse& operator=(const EnableTracingResponse&);
+  bool operator==(const EnableTracingResponse&) const;
+  bool operator!=(const EnableTracingResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_disabled() const { return _has_field_[1]; }
+  bool disabled() const { return disabled_; }
+  void set_disabled(bool value) { disabled_ = value; _has_field_.set(1); }
+
+  bool has_error() const { return _has_field_[3]; }
+  const std::string& error() const { return error_; }
+  void set_error(const std::string& value) { error_ = value; _has_field_.set(3); }
+
+ private:
+  bool disabled_{};
+  std::string error_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT EnableTracingRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceConfigFieldNumber = 1,
+    kAttachNotificationOnlyFieldNumber = 2,
+  };
+
+  EnableTracingRequest();
+  ~EnableTracingRequest() override;
+  EnableTracingRequest(EnableTracingRequest&&) noexcept;
+  EnableTracingRequest& operator=(EnableTracingRequest&&);
+  EnableTracingRequest(const EnableTracingRequest&);
+  EnableTracingRequest& operator=(const EnableTracingRequest&);
+  bool operator==(const EnableTracingRequest&) const;
+  bool operator!=(const EnableTracingRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_config() const { return _has_field_[1]; }
+  const TraceConfig& trace_config() const { return *trace_config_; }
+  TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
+
+  bool has_attach_notification_only() const { return _has_field_[2]; }
+  bool attach_notification_only() const { return attach_notification_only_; }
+  void set_attach_notification_only(bool value) { attach_notification_only_ = value; _has_field_.set(2); }
+
+ private:
+  ::protozero::CopyablePtr<TraceConfig> trace_config_;
+  bool attach_notification_only_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class SyncResponse;
+class SyncRequest;
+class GetAsyncCommandResponse;
+class GetAsyncCommandResponse_ClearIncrementalState;
+class GetAsyncCommandResponse_Flush;
+class GetAsyncCommandResponse_StopDataSource;
+class GetAsyncCommandResponse_StartDataSource;
+class DataSourceConfig;
+class TestConfig;
+class TestConfig_DummyFields;
+class InterceptorConfig;
+class ConsoleConfig;
+class ChromeConfig;
+class SystemInfoConfig;
+class GetAsyncCommandResponse_SetupDataSource;
+class GetAsyncCommandResponse_SetupTracing;
+class GetAsyncCommandRequest;
+class ActivateTriggersResponse;
+class ActivateTriggersRequest;
+class NotifyDataSourceStoppedResponse;
+class NotifyDataSourceStoppedRequest;
+class NotifyDataSourceStartedResponse;
+class NotifyDataSourceStartedRequest;
+class CommitDataResponse;
+class UnregisterTraceWriterResponse;
+class UnregisterTraceWriterRequest;
+class RegisterTraceWriterResponse;
+class RegisterTraceWriterRequest;
+class UnregisterDataSourceResponse;
+class UnregisterDataSourceRequest;
+class UpdateDataSourceResponse;
+class UpdateDataSourceRequest;
+class DataSourceDescriptor;
+class RegisterDataSourceResponse;
+class RegisterDataSourceRequest;
+class InitializeConnectionResponse;
+class InitializeConnectionRequest;
+enum DataSourceConfig_SessionInitiator : int;
+enum ConsoleConfig_Output : int;
+enum ChromeConfig_ClientPriority : int;
+enum InitializeConnectionRequest_ProducerSMBScrapingMode : int;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+enum InitializeConnectionRequest_ProducerSMBScrapingMode : int {
+  InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED = 0,
+  InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_ENABLED = 1,
+  InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED = 2,
+};
+
+class PERFETTO_EXPORT_COMPONENT SyncResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  SyncResponse();
+  ~SyncResponse() override;
+  SyncResponse(SyncResponse&&) noexcept;
+  SyncResponse& operator=(SyncResponse&&);
+  SyncResponse(const SyncResponse&);
+  SyncResponse& operator=(const SyncResponse&);
+  bool operator==(const SyncResponse&) const;
+  bool operator!=(const SyncResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT SyncRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  SyncRequest();
+  ~SyncRequest() override;
+  SyncRequest(SyncRequest&&) noexcept;
+  SyncRequest& operator=(SyncRequest&&);
+  SyncRequest(const SyncRequest&);
+  SyncRequest& operator=(const SyncRequest&);
+  bool operator==(const SyncRequest&) const;
+  bool operator!=(const SyncRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse : public ::protozero::CppMessageObj {
+ public:
+  using SetupDataSource = GetAsyncCommandResponse_SetupDataSource;
+  using StartDataSource = GetAsyncCommandResponse_StartDataSource;
+  using StopDataSource = GetAsyncCommandResponse_StopDataSource;
+  using SetupTracing = GetAsyncCommandResponse_SetupTracing;
+  using Flush = GetAsyncCommandResponse_Flush;
+  using ClearIncrementalState = GetAsyncCommandResponse_ClearIncrementalState;
+  enum FieldNumbers {
+    kSetupTracingFieldNumber = 3,
+    kSetupDataSourceFieldNumber = 6,
+    kStartDataSourceFieldNumber = 1,
+    kStopDataSourceFieldNumber = 2,
+    kFlushFieldNumber = 5,
+    kClearIncrementalStateFieldNumber = 7,
+  };
+
+  GetAsyncCommandResponse();
+  ~GetAsyncCommandResponse() override;
+  GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept;
+  GetAsyncCommandResponse& operator=(GetAsyncCommandResponse&&);
+  GetAsyncCommandResponse(const GetAsyncCommandResponse&);
+  GetAsyncCommandResponse& operator=(const GetAsyncCommandResponse&);
+  bool operator==(const GetAsyncCommandResponse&) const;
+  bool operator!=(const GetAsyncCommandResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_setup_tracing() const { return _has_field_[3]; }
+  const GetAsyncCommandResponse_SetupTracing& setup_tracing() const { return *setup_tracing_; }
+  GetAsyncCommandResponse_SetupTracing* mutable_setup_tracing() { _has_field_.set(3); return setup_tracing_.get(); }
+
+  bool has_setup_data_source() const { return _has_field_[6]; }
+  const GetAsyncCommandResponse_SetupDataSource& setup_data_source() const { return *setup_data_source_; }
+  GetAsyncCommandResponse_SetupDataSource* mutable_setup_data_source() { _has_field_.set(6); return setup_data_source_.get(); }
+
+  bool has_start_data_source() const { return _has_field_[1]; }
+  const GetAsyncCommandResponse_StartDataSource& start_data_source() const { return *start_data_source_; }
+  GetAsyncCommandResponse_StartDataSource* mutable_start_data_source() { _has_field_.set(1); return start_data_source_.get(); }
+
+  bool has_stop_data_source() const { return _has_field_[2]; }
+  const GetAsyncCommandResponse_StopDataSource& stop_data_source() const { return *stop_data_source_; }
+  GetAsyncCommandResponse_StopDataSource* mutable_stop_data_source() { _has_field_.set(2); return stop_data_source_.get(); }
+
+  bool has_flush() const { return _has_field_[5]; }
+  const GetAsyncCommandResponse_Flush& flush() const { return *flush_; }
+  GetAsyncCommandResponse_Flush* mutable_flush() { _has_field_.set(5); return flush_.get(); }
+
+  bool has_clear_incremental_state() const { return _has_field_[7]; }
+  const GetAsyncCommandResponse_ClearIncrementalState& clear_incremental_state() const { return *clear_incremental_state_; }
+  GetAsyncCommandResponse_ClearIncrementalState* mutable_clear_incremental_state() { _has_field_.set(7); return clear_incremental_state_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_SetupTracing> setup_tracing_;
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_SetupDataSource> setup_data_source_;
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_StartDataSource> start_data_source_;
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_StopDataSource> stop_data_source_;
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_Flush> flush_;
+  ::protozero::CopyablePtr<GetAsyncCommandResponse_ClearIncrementalState> clear_incremental_state_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<8> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_ClearIncrementalState : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceIdsFieldNumber = 1,
+  };
+
+  GetAsyncCommandResponse_ClearIncrementalState();
+  ~GetAsyncCommandResponse_ClearIncrementalState() override;
+  GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept;
+  GetAsyncCommandResponse_ClearIncrementalState& operator=(GetAsyncCommandResponse_ClearIncrementalState&&);
+  GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&);
+  GetAsyncCommandResponse_ClearIncrementalState& operator=(const GetAsyncCommandResponse_ClearIncrementalState&);
+  bool operator==(const GetAsyncCommandResponse_ClearIncrementalState&) const;
+  bool operator!=(const GetAsyncCommandResponse_ClearIncrementalState& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<uint64_t>& data_source_ids() const { return data_source_ids_; }
+  std::vector<uint64_t>* mutable_data_source_ids() { return &data_source_ids_; }
+  int data_source_ids_size() const { return static_cast<int>(data_source_ids_.size()); }
+  void clear_data_source_ids() { data_source_ids_.clear(); }
+  void add_data_source_ids(uint64_t value) { data_source_ids_.emplace_back(value); }
+  uint64_t* add_data_source_ids() { data_source_ids_.emplace_back(); return &data_source_ids_.back(); }
+
+ private:
+  std::vector<uint64_t> data_source_ids_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_Flush : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceIdsFieldNumber = 1,
+    kRequestIdFieldNumber = 2,
+    kFlagsFieldNumber = 3,
+  };
+
+  GetAsyncCommandResponse_Flush();
+  ~GetAsyncCommandResponse_Flush() override;
+  GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept;
+  GetAsyncCommandResponse_Flush& operator=(GetAsyncCommandResponse_Flush&&);
+  GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&);
+  GetAsyncCommandResponse_Flush& operator=(const GetAsyncCommandResponse_Flush&);
+  bool operator==(const GetAsyncCommandResponse_Flush&) const;
+  bool operator!=(const GetAsyncCommandResponse_Flush& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<uint64_t>& data_source_ids() const { return data_source_ids_; }
+  std::vector<uint64_t>* mutable_data_source_ids() { return &data_source_ids_; }
+  int data_source_ids_size() const { return static_cast<int>(data_source_ids_.size()); }
+  void clear_data_source_ids() { data_source_ids_.clear(); }
+  void add_data_source_ids(uint64_t value) { data_source_ids_.emplace_back(value); }
+  uint64_t* add_data_source_ids() { data_source_ids_.emplace_back(); return &data_source_ids_.back(); }
+
+  bool has_request_id() const { return _has_field_[2]; }
+  uint64_t request_id() const { return request_id_; }
+  void set_request_id(uint64_t value) { request_id_ = value; _has_field_.set(2); }
+
+  bool has_flags() const { return _has_field_[3]; }
+  uint64_t flags() const { return flags_; }
+  void set_flags(uint64_t value) { flags_ = value; _has_field_.set(3); }
+
+ private:
+  std::vector<uint64_t> data_source_ids_;
+  uint64_t request_id_{};
+  uint64_t flags_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_StopDataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kInstanceIdFieldNumber = 1,
+  };
+
+  GetAsyncCommandResponse_StopDataSource();
+  ~GetAsyncCommandResponse_StopDataSource() override;
+  GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept;
+  GetAsyncCommandResponse_StopDataSource& operator=(GetAsyncCommandResponse_StopDataSource&&);
+  GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&);
+  GetAsyncCommandResponse_StopDataSource& operator=(const GetAsyncCommandResponse_StopDataSource&);
+  bool operator==(const GetAsyncCommandResponse_StopDataSource&) const;
+  bool operator!=(const GetAsyncCommandResponse_StopDataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_instance_id() const { return _has_field_[1]; }
+  uint64_t instance_id() const { return instance_id_; }
+  void set_instance_id(uint64_t value) { instance_id_ = value; _has_field_.set(1); }
+
+ private:
+  uint64_t instance_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_StartDataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNewInstanceIdFieldNumber = 1,
+    kConfigFieldNumber = 2,
+  };
+
+  GetAsyncCommandResponse_StartDataSource();
+  ~GetAsyncCommandResponse_StartDataSource() override;
+  GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept;
+  GetAsyncCommandResponse_StartDataSource& operator=(GetAsyncCommandResponse_StartDataSource&&);
+  GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&);
+  GetAsyncCommandResponse_StartDataSource& operator=(const GetAsyncCommandResponse_StartDataSource&);
+  bool operator==(const GetAsyncCommandResponse_StartDataSource&) const;
+  bool operator!=(const GetAsyncCommandResponse_StartDataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_new_instance_id() const { return _has_field_[1]; }
+  uint64_t new_instance_id() const { return new_instance_id_; }
+  void set_new_instance_id(uint64_t value) { new_instance_id_ = value; _has_field_.set(1); }
+
+  bool has_config() const { return _has_field_[2]; }
+  const DataSourceConfig& config() const { return *config_; }
+  DataSourceConfig* mutable_config() { _has_field_.set(2); return config_.get(); }
+
+ private:
+  uint64_t new_instance_id_{};
+  ::protozero::CopyablePtr<DataSourceConfig> config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_SetupDataSource : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kNewInstanceIdFieldNumber = 1,
+    kConfigFieldNumber = 2,
+  };
+
+  GetAsyncCommandResponse_SetupDataSource();
+  ~GetAsyncCommandResponse_SetupDataSource() override;
+  GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept;
+  GetAsyncCommandResponse_SetupDataSource& operator=(GetAsyncCommandResponse_SetupDataSource&&);
+  GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&);
+  GetAsyncCommandResponse_SetupDataSource& operator=(const GetAsyncCommandResponse_SetupDataSource&);
+  bool operator==(const GetAsyncCommandResponse_SetupDataSource&) const;
+  bool operator!=(const GetAsyncCommandResponse_SetupDataSource& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_new_instance_id() const { return _has_field_[1]; }
+  uint64_t new_instance_id() const { return new_instance_id_; }
+  void set_new_instance_id(uint64_t value) { new_instance_id_ = value; _has_field_.set(1); }
+
+  bool has_config() const { return _has_field_[2]; }
+  const DataSourceConfig& config() const { return *config_; }
+  DataSourceConfig* mutable_config() { _has_field_.set(2); return config_.get(); }
+
+ private:
+  uint64_t new_instance_id_{};
+  ::protozero::CopyablePtr<DataSourceConfig> config_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandResponse_SetupTracing : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSharedBufferPageSizeKbFieldNumber = 1,
+    kShmKeyWindowsFieldNumber = 2,
+  };
+
+  GetAsyncCommandResponse_SetupTracing();
+  ~GetAsyncCommandResponse_SetupTracing() override;
+  GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept;
+  GetAsyncCommandResponse_SetupTracing& operator=(GetAsyncCommandResponse_SetupTracing&&);
+  GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&);
+  GetAsyncCommandResponse_SetupTracing& operator=(const GetAsyncCommandResponse_SetupTracing&);
+  bool operator==(const GetAsyncCommandResponse_SetupTracing&) const;
+  bool operator!=(const GetAsyncCommandResponse_SetupTracing& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_shared_buffer_page_size_kb() const { return _has_field_[1]; }
+  uint32_t shared_buffer_page_size_kb() const { return shared_buffer_page_size_kb_; }
+  void set_shared_buffer_page_size_kb(uint32_t value) { shared_buffer_page_size_kb_ = value; _has_field_.set(1); }
+
+  bool has_shm_key_windows() const { return _has_field_[2]; }
+  const std::string& shm_key_windows() const { return shm_key_windows_; }
+  void set_shm_key_windows(const std::string& value) { shm_key_windows_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t shared_buffer_page_size_kb_{};
+  std::string shm_key_windows_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT GetAsyncCommandRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  GetAsyncCommandRequest();
+  ~GetAsyncCommandRequest() override;
+  GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept;
+  GetAsyncCommandRequest& operator=(GetAsyncCommandRequest&&);
+  GetAsyncCommandRequest(const GetAsyncCommandRequest&);
+  GetAsyncCommandRequest& operator=(const GetAsyncCommandRequest&);
+  bool operator==(const GetAsyncCommandRequest&) const;
+  bool operator!=(const GetAsyncCommandRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ActivateTriggersResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  ActivateTriggersResponse();
+  ~ActivateTriggersResponse() override;
+  ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept;
+  ActivateTriggersResponse& operator=(ActivateTriggersResponse&&);
+  ActivateTriggersResponse(const ActivateTriggersResponse&);
+  ActivateTriggersResponse& operator=(const ActivateTriggersResponse&);
+  bool operator==(const ActivateTriggersResponse&) const;
+  bool operator!=(const ActivateTriggersResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT ActivateTriggersRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTriggerNamesFieldNumber = 1,
+  };
+
+  ActivateTriggersRequest();
+  ~ActivateTriggersRequest() override;
+  ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept;
+  ActivateTriggersRequest& operator=(ActivateTriggersRequest&&);
+  ActivateTriggersRequest(const ActivateTriggersRequest&);
+  ActivateTriggersRequest& operator=(const ActivateTriggersRequest&);
+  bool operator==(const ActivateTriggersRequest&) const;
+  bool operator!=(const ActivateTriggersRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  const std::vector<std::string>& trigger_names() const { return trigger_names_; }
+  std::vector<std::string>* mutable_trigger_names() { return &trigger_names_; }
+  int trigger_names_size() const { return static_cast<int>(trigger_names_.size()); }
+  void clear_trigger_names() { trigger_names_.clear(); }
+  void add_trigger_names(std::string value) { trigger_names_.emplace_back(value); }
+  std::string* add_trigger_names() { trigger_names_.emplace_back(); return &trigger_names_.back(); }
+
+ private:
+  std::vector<std::string> trigger_names_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT NotifyDataSourceStoppedResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  NotifyDataSourceStoppedResponse();
+  ~NotifyDataSourceStoppedResponse() override;
+  NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept;
+  NotifyDataSourceStoppedResponse& operator=(NotifyDataSourceStoppedResponse&&);
+  NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&);
+  NotifyDataSourceStoppedResponse& operator=(const NotifyDataSourceStoppedResponse&);
+  bool operator==(const NotifyDataSourceStoppedResponse&) const;
+  bool operator!=(const NotifyDataSourceStoppedResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT NotifyDataSourceStoppedRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceIdFieldNumber = 1,
+  };
+
+  NotifyDataSourceStoppedRequest();
+  ~NotifyDataSourceStoppedRequest() override;
+  NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept;
+  NotifyDataSourceStoppedRequest& operator=(NotifyDataSourceStoppedRequest&&);
+  NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&);
+  NotifyDataSourceStoppedRequest& operator=(const NotifyDataSourceStoppedRequest&);
+  bool operator==(const NotifyDataSourceStoppedRequest&) const;
+  bool operator!=(const NotifyDataSourceStoppedRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data_source_id() const { return _has_field_[1]; }
+  uint64_t data_source_id() const { return data_source_id_; }
+  void set_data_source_id(uint64_t value) { data_source_id_ = value; _has_field_.set(1); }
+
+ private:
+  uint64_t data_source_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT NotifyDataSourceStartedResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  NotifyDataSourceStartedResponse();
+  ~NotifyDataSourceStartedResponse() override;
+  NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept;
+  NotifyDataSourceStartedResponse& operator=(NotifyDataSourceStartedResponse&&);
+  NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&);
+  NotifyDataSourceStartedResponse& operator=(const NotifyDataSourceStartedResponse&);
+  bool operator==(const NotifyDataSourceStartedResponse&) const;
+  bool operator!=(const NotifyDataSourceStartedResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT NotifyDataSourceStartedRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceIdFieldNumber = 1,
+  };
+
+  NotifyDataSourceStartedRequest();
+  ~NotifyDataSourceStartedRequest() override;
+  NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept;
+  NotifyDataSourceStartedRequest& operator=(NotifyDataSourceStartedRequest&&);
+  NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&);
+  NotifyDataSourceStartedRequest& operator=(const NotifyDataSourceStartedRequest&);
+  bool operator==(const NotifyDataSourceStartedRequest&) const;
+  bool operator!=(const NotifyDataSourceStartedRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data_source_id() const { return _has_field_[1]; }
+  uint64_t data_source_id() const { return data_source_id_; }
+  void set_data_source_id(uint64_t value) { data_source_id_ = value; _has_field_.set(1); }
+
+ private:
+  uint64_t data_source_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT CommitDataResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  CommitDataResponse();
+  ~CommitDataResponse() override;
+  CommitDataResponse(CommitDataResponse&&) noexcept;
+  CommitDataResponse& operator=(CommitDataResponse&&);
+  CommitDataResponse(const CommitDataResponse&);
+  CommitDataResponse& operator=(const CommitDataResponse&);
+  bool operator==(const CommitDataResponse&) const;
+  bool operator!=(const CommitDataResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UnregisterTraceWriterResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  UnregisterTraceWriterResponse();
+  ~UnregisterTraceWriterResponse() override;
+  UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept;
+  UnregisterTraceWriterResponse& operator=(UnregisterTraceWriterResponse&&);
+  UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&);
+  UnregisterTraceWriterResponse& operator=(const UnregisterTraceWriterResponse&);
+  bool operator==(const UnregisterTraceWriterResponse&) const;
+  bool operator!=(const UnregisterTraceWriterResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UnregisterTraceWriterRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceWriterIdFieldNumber = 1,
+  };
+
+  UnregisterTraceWriterRequest();
+  ~UnregisterTraceWriterRequest() override;
+  UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept;
+  UnregisterTraceWriterRequest& operator=(UnregisterTraceWriterRequest&&);
+  UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&);
+  UnregisterTraceWriterRequest& operator=(const UnregisterTraceWriterRequest&);
+  bool operator==(const UnregisterTraceWriterRequest&) const;
+  bool operator!=(const UnregisterTraceWriterRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_writer_id() const { return _has_field_[1]; }
+  uint32_t trace_writer_id() const { return trace_writer_id_; }
+  void set_trace_writer_id(uint32_t value) { trace_writer_id_ = value; _has_field_.set(1); }
+
+ private:
+  uint32_t trace_writer_id_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT RegisterTraceWriterResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  RegisterTraceWriterResponse();
+  ~RegisterTraceWriterResponse() override;
+  RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept;
+  RegisterTraceWriterResponse& operator=(RegisterTraceWriterResponse&&);
+  RegisterTraceWriterResponse(const RegisterTraceWriterResponse&);
+  RegisterTraceWriterResponse& operator=(const RegisterTraceWriterResponse&);
+  bool operator==(const RegisterTraceWriterResponse&) const;
+  bool operator!=(const RegisterTraceWriterResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT RegisterTraceWriterRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kTraceWriterIdFieldNumber = 1,
+    kTargetBufferFieldNumber = 2,
+  };
+
+  RegisterTraceWriterRequest();
+  ~RegisterTraceWriterRequest() override;
+  RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept;
+  RegisterTraceWriterRequest& operator=(RegisterTraceWriterRequest&&);
+  RegisterTraceWriterRequest(const RegisterTraceWriterRequest&);
+  RegisterTraceWriterRequest& operator=(const RegisterTraceWriterRequest&);
+  bool operator==(const RegisterTraceWriterRequest&) const;
+  bool operator!=(const RegisterTraceWriterRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_trace_writer_id() const { return _has_field_[1]; }
+  uint32_t trace_writer_id() const { return trace_writer_id_; }
+  void set_trace_writer_id(uint32_t value) { trace_writer_id_ = value; _has_field_.set(1); }
+
+  bool has_target_buffer() const { return _has_field_[2]; }
+  uint32_t target_buffer() const { return target_buffer_; }
+  void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t trace_writer_id_{};
+  uint32_t target_buffer_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UnregisterDataSourceResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  UnregisterDataSourceResponse();
+  ~UnregisterDataSourceResponse() override;
+  UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept;
+  UnregisterDataSourceResponse& operator=(UnregisterDataSourceResponse&&);
+  UnregisterDataSourceResponse(const UnregisterDataSourceResponse&);
+  UnregisterDataSourceResponse& operator=(const UnregisterDataSourceResponse&);
+  bool operator==(const UnregisterDataSourceResponse&) const;
+  bool operator!=(const UnregisterDataSourceResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UnregisterDataSourceRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceNameFieldNumber = 1,
+  };
+
+  UnregisterDataSourceRequest();
+  ~UnregisterDataSourceRequest() override;
+  UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept;
+  UnregisterDataSourceRequest& operator=(UnregisterDataSourceRequest&&);
+  UnregisterDataSourceRequest(const UnregisterDataSourceRequest&);
+  UnregisterDataSourceRequest& operator=(const UnregisterDataSourceRequest&);
+  bool operator==(const UnregisterDataSourceRequest&) const;
+  bool operator!=(const UnregisterDataSourceRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data_source_name() const { return _has_field_[1]; }
+  const std::string& data_source_name() const { return data_source_name_; }
+  void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(1); }
+
+ private:
+  std::string data_source_name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UpdateDataSourceResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+  };
+
+  UpdateDataSourceResponse();
+  ~UpdateDataSourceResponse() override;
+  UpdateDataSourceResponse(UpdateDataSourceResponse&&) noexcept;
+  UpdateDataSourceResponse& operator=(UpdateDataSourceResponse&&);
+  UpdateDataSourceResponse(const UpdateDataSourceResponse&);
+  UpdateDataSourceResponse& operator=(const UpdateDataSourceResponse&);
+  bool operator==(const UpdateDataSourceResponse&) const;
+  bool operator!=(const UpdateDataSourceResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+ private:
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT UpdateDataSourceRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceDescriptorFieldNumber = 1,
+  };
+
+  UpdateDataSourceRequest();
+  ~UpdateDataSourceRequest() override;
+  UpdateDataSourceRequest(UpdateDataSourceRequest&&) noexcept;
+  UpdateDataSourceRequest& operator=(UpdateDataSourceRequest&&);
+  UpdateDataSourceRequest(const UpdateDataSourceRequest&);
+  UpdateDataSourceRequest& operator=(const UpdateDataSourceRequest&);
+  bool operator==(const UpdateDataSourceRequest&) const;
+  bool operator!=(const UpdateDataSourceRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data_source_descriptor() const { return _has_field_[1]; }
+  const DataSourceDescriptor& data_source_descriptor() const { return *data_source_descriptor_; }
+  DataSourceDescriptor* mutable_data_source_descriptor() { _has_field_.set(1); return data_source_descriptor_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<DataSourceDescriptor> data_source_descriptor_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT RegisterDataSourceResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kErrorFieldNumber = 1,
+  };
+
+  RegisterDataSourceResponse();
+  ~RegisterDataSourceResponse() override;
+  RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept;
+  RegisterDataSourceResponse& operator=(RegisterDataSourceResponse&&);
+  RegisterDataSourceResponse(const RegisterDataSourceResponse&);
+  RegisterDataSourceResponse& operator=(const RegisterDataSourceResponse&);
+  bool operator==(const RegisterDataSourceResponse&) const;
+  bool operator!=(const RegisterDataSourceResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_error() const { return _has_field_[1]; }
+  const std::string& error() const { return error_; }
+  void set_error(const std::string& value) { error_ = value; _has_field_.set(1); }
+
+ private:
+  std::string error_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT RegisterDataSourceRequest : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kDataSourceDescriptorFieldNumber = 1,
+  };
+
+  RegisterDataSourceRequest();
+  ~RegisterDataSourceRequest() override;
+  RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept;
+  RegisterDataSourceRequest& operator=(RegisterDataSourceRequest&&);
+  RegisterDataSourceRequest(const RegisterDataSourceRequest&);
+  RegisterDataSourceRequest& operator=(const RegisterDataSourceRequest&);
+  bool operator==(const RegisterDataSourceRequest&) const;
+  bool operator!=(const RegisterDataSourceRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_data_source_descriptor() const { return _has_field_[1]; }
+  const DataSourceDescriptor& data_source_descriptor() const { return *data_source_descriptor_; }
+  DataSourceDescriptor* mutable_data_source_descriptor() { _has_field_.set(1); return data_source_descriptor_.get(); }
+
+ private:
+  ::protozero::CopyablePtr<DataSourceDescriptor> data_source_descriptor_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT InitializeConnectionResponse : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kUsingShmemProvidedByProducerFieldNumber = 1,
+    kDirectSmbPatchingSupportedFieldNumber = 2,
+    kUseShmemEmulationFieldNumber = 3,
+  };
+
+  InitializeConnectionResponse();
+  ~InitializeConnectionResponse() override;
+  InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept;
+  InitializeConnectionResponse& operator=(InitializeConnectionResponse&&);
+  InitializeConnectionResponse(const InitializeConnectionResponse&);
+  InitializeConnectionResponse& operator=(const InitializeConnectionResponse&);
+  bool operator==(const InitializeConnectionResponse&) const;
+  bool operator!=(const InitializeConnectionResponse& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_using_shmem_provided_by_producer() const { return _has_field_[1]; }
+  bool using_shmem_provided_by_producer() const { return using_shmem_provided_by_producer_; }
+  void set_using_shmem_provided_by_producer(bool value) { using_shmem_provided_by_producer_ = value; _has_field_.set(1); }
+
+  bool has_direct_smb_patching_supported() const { return _has_field_[2]; }
+  bool direct_smb_patching_supported() const { return direct_smb_patching_supported_; }
+  void set_direct_smb_patching_supported(bool value) { direct_smb_patching_supported_ = value; _has_field_.set(2); }
+
+  bool has_use_shmem_emulation() const { return _has_field_[3]; }
+  bool use_shmem_emulation() const { return use_shmem_emulation_; }
+  void set_use_shmem_emulation(bool value) { use_shmem_emulation_ = value; _has_field_.set(3); }
+
+ private:
+  bool using_shmem_provided_by_producer_{};
+  bool direct_smb_patching_supported_{};
+  bool use_shmem_emulation_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT InitializeConnectionRequest : public ::protozero::CppMessageObj {
+ public:
+  using ProducerSMBScrapingMode = InitializeConnectionRequest_ProducerSMBScrapingMode;
+  static constexpr auto SMB_SCRAPING_UNSPECIFIED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED;
+  static constexpr auto SMB_SCRAPING_ENABLED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_ENABLED;
+  static constexpr auto SMB_SCRAPING_DISABLED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED;
+  static constexpr auto ProducerSMBScrapingMode_MIN = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED;
+  static constexpr auto ProducerSMBScrapingMode_MAX = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED;
+  enum FieldNumbers {
+    kSharedMemoryPageSizeHintBytesFieldNumber = 1,
+    kSharedMemorySizeHintBytesFieldNumber = 2,
+    kProducerNameFieldNumber = 3,
+    kSmbScrapingModeFieldNumber = 4,
+    kProducerProvidedShmemFieldNumber = 6,
+    kSdkVersionFieldNumber = 8,
+    kShmKeyWindowsFieldNumber = 7,
+  };
+
+  InitializeConnectionRequest();
+  ~InitializeConnectionRequest() override;
+  InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept;
+  InitializeConnectionRequest& operator=(InitializeConnectionRequest&&);
+  InitializeConnectionRequest(const InitializeConnectionRequest&);
+  InitializeConnectionRequest& operator=(const InitializeConnectionRequest&);
+  bool operator==(const InitializeConnectionRequest&) const;
+  bool operator!=(const InitializeConnectionRequest& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_shared_memory_page_size_hint_bytes() const { return _has_field_[1]; }
+  uint32_t shared_memory_page_size_hint_bytes() const { return shared_memory_page_size_hint_bytes_; }
+  void set_shared_memory_page_size_hint_bytes(uint32_t value) { shared_memory_page_size_hint_bytes_ = value; _has_field_.set(1); }
+
+  bool has_shared_memory_size_hint_bytes() const { return _has_field_[2]; }
+  uint32_t shared_memory_size_hint_bytes() const { return shared_memory_size_hint_bytes_; }
+  void set_shared_memory_size_hint_bytes(uint32_t value) { shared_memory_size_hint_bytes_ = value; _has_field_.set(2); }
+
+  bool has_producer_name() const { return _has_field_[3]; }
+  const std::string& producer_name() const { return producer_name_; }
+  void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(3); }
+
+  bool has_smb_scraping_mode() const { return _has_field_[4]; }
+  InitializeConnectionRequest_ProducerSMBScrapingMode smb_scraping_mode() const { return smb_scraping_mode_; }
+  void set_smb_scraping_mode(InitializeConnectionRequest_ProducerSMBScrapingMode value) { smb_scraping_mode_ = value; _has_field_.set(4); }
+
+  bool has_producer_provided_shmem() const { return _has_field_[6]; }
+  bool producer_provided_shmem() const { return producer_provided_shmem_; }
+  void set_producer_provided_shmem(bool value) { producer_provided_shmem_ = value; _has_field_.set(6); }
+
+  bool has_sdk_version() const { return _has_field_[8]; }
+  const std::string& sdk_version() const { return sdk_version_; }
+  void set_sdk_version(const std::string& value) { sdk_version_ = value; _has_field_.set(8); }
+
+  bool has_shm_key_windows() const { return _has_field_[7]; }
+  const std::string& shm_key_windows() const { return shm_key_windows_; }
+  void set_shm_key_windows(const std::string& value) { shm_key_windows_ = value; _has_field_.set(7); }
+
+ private:
+  uint32_t shared_memory_page_size_hint_bytes_{};
+  uint32_t shared_memory_size_hint_bytes_{};
+  std::string producer_name_{};
+  InitializeConnectionRequest_ProducerSMBScrapingMode smb_scraping_mode_{};
+  bool producer_provided_shmem_{};
+  std::string sdk_version_{};
+  std::string shm_key_windows_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
+// gen_amalgamated begin header: gen/protos/perfetto/ipc/wire_protocol.gen.h
+// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
+#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
+#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
+
+#include <stdint.h>
+#include <bitset>
+#include <vector>
+#include <string>
+#include <type_traits>
+
+// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+class IPCFrame;
+class IPCFrame_SetPeerIdentity;
+class IPCFrame_RequestError;
+class IPCFrame_InvokeMethodReply;
+class IPCFrame_InvokeMethod;
+class IPCFrame_BindServiceReply;
+class IPCFrame_BindServiceReply_MethodInfo;
+class IPCFrame_BindService;
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+namespace protozero {
+class Message;
+}  // namespace protozero
+
+namespace perfetto {
+namespace protos {
+namespace gen {
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame : public ::protozero::CppMessageObj {
+ public:
+  using BindService = IPCFrame_BindService;
+  using BindServiceReply = IPCFrame_BindServiceReply;
+  using InvokeMethod = IPCFrame_InvokeMethod;
+  using InvokeMethodReply = IPCFrame_InvokeMethodReply;
+  using RequestError = IPCFrame_RequestError;
+  using SetPeerIdentity = IPCFrame_SetPeerIdentity;
+  enum FieldNumbers {
+    kRequestIdFieldNumber = 2,
+    kMsgBindServiceFieldNumber = 3,
+    kMsgBindServiceReplyFieldNumber = 4,
+    kMsgInvokeMethodFieldNumber = 5,
+    kMsgInvokeMethodReplyFieldNumber = 6,
+    kMsgRequestErrorFieldNumber = 7,
+    kSetPeerIdentityFieldNumber = 8,
+    kDataForTestingFieldNumber = 1,
+  };
+
+  IPCFrame();
+  ~IPCFrame() override;
+  IPCFrame(IPCFrame&&) noexcept;
+  IPCFrame& operator=(IPCFrame&&);
+  IPCFrame(const IPCFrame&);
+  IPCFrame& operator=(const IPCFrame&);
+  bool operator==(const IPCFrame&) const;
+  bool operator!=(const IPCFrame& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_request_id() const { return _has_field_[2]; }
+  uint64_t request_id() const { return request_id_; }
+  void set_request_id(uint64_t value) { request_id_ = value; _has_field_.set(2); }
+
+  bool has_msg_bind_service() const { return _has_field_[3]; }
+  const IPCFrame_BindService& msg_bind_service() const { return *msg_bind_service_; }
+  IPCFrame_BindService* mutable_msg_bind_service() { _has_field_.set(3); return msg_bind_service_.get(); }
+
+  bool has_msg_bind_service_reply() const { return _has_field_[4]; }
+  const IPCFrame_BindServiceReply& msg_bind_service_reply() const { return *msg_bind_service_reply_; }
+  IPCFrame_BindServiceReply* mutable_msg_bind_service_reply() { _has_field_.set(4); return msg_bind_service_reply_.get(); }
+
+  bool has_msg_invoke_method() const { return _has_field_[5]; }
+  const IPCFrame_InvokeMethod& msg_invoke_method() const { return *msg_invoke_method_; }
+  IPCFrame_InvokeMethod* mutable_msg_invoke_method() { _has_field_.set(5); return msg_invoke_method_.get(); }
+
+  bool has_msg_invoke_method_reply() const { return _has_field_[6]; }
+  const IPCFrame_InvokeMethodReply& msg_invoke_method_reply() const { return *msg_invoke_method_reply_; }
+  IPCFrame_InvokeMethodReply* mutable_msg_invoke_method_reply() { _has_field_.set(6); return msg_invoke_method_reply_.get(); }
+
+  bool has_msg_request_error() const { return _has_field_[7]; }
+  const IPCFrame_RequestError& msg_request_error() const { return *msg_request_error_; }
+  IPCFrame_RequestError* mutable_msg_request_error() { _has_field_.set(7); return msg_request_error_.get(); }
+
+  bool has_set_peer_identity() const { return _has_field_[8]; }
+  const IPCFrame_SetPeerIdentity& set_peer_identity() const { return *set_peer_identity_; }
+  IPCFrame_SetPeerIdentity* mutable_set_peer_identity() { _has_field_.set(8); return set_peer_identity_.get(); }
+
+  const std::vector<std::string>& data_for_testing() const { return data_for_testing_; }
+  std::vector<std::string>* mutable_data_for_testing() { return &data_for_testing_; }
+  int data_for_testing_size() const { return static_cast<int>(data_for_testing_.size()); }
+  void clear_data_for_testing() { data_for_testing_.clear(); }
+  void add_data_for_testing(std::string value) { data_for_testing_.emplace_back(value); }
+  std::string* add_data_for_testing() { data_for_testing_.emplace_back(); return &data_for_testing_.back(); }
+
+ private:
+  uint64_t request_id_{};
+  ::protozero::CopyablePtr<IPCFrame_BindService> msg_bind_service_;
+  ::protozero::CopyablePtr<IPCFrame_BindServiceReply> msg_bind_service_reply_;
+  ::protozero::CopyablePtr<IPCFrame_InvokeMethod> msg_invoke_method_;
+  ::protozero::CopyablePtr<IPCFrame_InvokeMethodReply> msg_invoke_method_reply_;
+  ::protozero::CopyablePtr<IPCFrame_RequestError> msg_request_error_;
+  ::protozero::CopyablePtr<IPCFrame_SetPeerIdentity> set_peer_identity_;
+  std::vector<std::string> data_for_testing_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<9> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_SetPeerIdentity : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kPidFieldNumber = 1,
+    kUidFieldNumber = 2,
+    kMachineIdHintFieldNumber = 3,
+  };
+
+  IPCFrame_SetPeerIdentity();
+  ~IPCFrame_SetPeerIdentity() override;
+  IPCFrame_SetPeerIdentity(IPCFrame_SetPeerIdentity&&) noexcept;
+  IPCFrame_SetPeerIdentity& operator=(IPCFrame_SetPeerIdentity&&);
+  IPCFrame_SetPeerIdentity(const IPCFrame_SetPeerIdentity&);
+  IPCFrame_SetPeerIdentity& operator=(const IPCFrame_SetPeerIdentity&);
+  bool operator==(const IPCFrame_SetPeerIdentity&) const;
+  bool operator!=(const IPCFrame_SetPeerIdentity& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_pid() const { return _has_field_[1]; }
+  int32_t pid() const { return pid_; }
+  void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
+
+  bool has_uid() const { return _has_field_[2]; }
+  int32_t uid() const { return uid_; }
+  void set_uid(int32_t value) { uid_ = value; _has_field_.set(2); }
+
+  bool has_machine_id_hint() const { return _has_field_[3]; }
+  const std::string& machine_id_hint() const { return machine_id_hint_; }
+  void set_machine_id_hint(const std::string& value) { machine_id_hint_ = value; _has_field_.set(3); }
+
+ private:
+  int32_t pid_{};
+  int32_t uid_{};
+  std::string machine_id_hint_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_RequestError : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kErrorFieldNumber = 1,
+  };
+
+  IPCFrame_RequestError();
+  ~IPCFrame_RequestError() override;
+  IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept;
+  IPCFrame_RequestError& operator=(IPCFrame_RequestError&&);
+  IPCFrame_RequestError(const IPCFrame_RequestError&);
+  IPCFrame_RequestError& operator=(const IPCFrame_RequestError&);
+  bool operator==(const IPCFrame_RequestError&) const;
+  bool operator!=(const IPCFrame_RequestError& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_error() const { return _has_field_[1]; }
+  const std::string& error() const { return error_; }
+  void set_error(const std::string& value) { error_ = value; _has_field_.set(1); }
+
+ private:
+  std::string error_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_InvokeMethodReply : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kSuccessFieldNumber = 1,
+    kHasMoreFieldNumber = 2,
+    kReplyProtoFieldNumber = 3,
+  };
+
+  IPCFrame_InvokeMethodReply();
+  ~IPCFrame_InvokeMethodReply() override;
+  IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept;
+  IPCFrame_InvokeMethodReply& operator=(IPCFrame_InvokeMethodReply&&);
+  IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&);
+  IPCFrame_InvokeMethodReply& operator=(const IPCFrame_InvokeMethodReply&);
+  bool operator==(const IPCFrame_InvokeMethodReply&) const;
+  bool operator!=(const IPCFrame_InvokeMethodReply& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_success() const { return _has_field_[1]; }
+  bool success() const { return success_; }
+  void set_success(bool value) { success_ = value; _has_field_.set(1); }
+
+  bool has_has_more() const { return _has_field_[2]; }
+  bool has_more() const { return has_more_; }
+  void set_has_more(bool value) { has_more_ = value; _has_field_.set(2); }
+
+  bool has_reply_proto() const { return _has_field_[3]; }
+  const std::string& reply_proto() const { return reply_proto_; }
+  void set_reply_proto(const std::string& value) { reply_proto_ = value; _has_field_.set(3); }
+  void set_reply_proto(const void* p, size_t s) { reply_proto_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(3); }
+
+ private:
+  bool success_{};
+  bool has_more_{};
+  std::string reply_proto_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_InvokeMethod : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kServiceIdFieldNumber = 1,
+    kMethodIdFieldNumber = 2,
+    kArgsProtoFieldNumber = 3,
+    kDropReplyFieldNumber = 4,
+  };
+
+  IPCFrame_InvokeMethod();
+  ~IPCFrame_InvokeMethod() override;
+  IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept;
+  IPCFrame_InvokeMethod& operator=(IPCFrame_InvokeMethod&&);
+  IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&);
+  IPCFrame_InvokeMethod& operator=(const IPCFrame_InvokeMethod&);
+  bool operator==(const IPCFrame_InvokeMethod&) const;
+  bool operator!=(const IPCFrame_InvokeMethod& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_service_id() const { return _has_field_[1]; }
+  uint32_t service_id() const { return service_id_; }
+  void set_service_id(uint32_t value) { service_id_ = value; _has_field_.set(1); }
+
+  bool has_method_id() const { return _has_field_[2]; }
+  uint32_t method_id() const { return method_id_; }
+  void set_method_id(uint32_t value) { method_id_ = value; _has_field_.set(2); }
+
+  bool has_args_proto() const { return _has_field_[3]; }
+  const std::string& args_proto() const { return args_proto_; }
+  void set_args_proto(const std::string& value) { args_proto_ = value; _has_field_.set(3); }
+  void set_args_proto(const void* p, size_t s) { args_proto_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(3); }
+
+  bool has_drop_reply() const { return _has_field_[4]; }
+  bool drop_reply() const { return drop_reply_; }
+  void set_drop_reply(bool value) { drop_reply_ = value; _has_field_.set(4); }
+
+ private:
+  uint32_t service_id_{};
+  uint32_t method_id_{};
+  std::string args_proto_{};
+  bool drop_reply_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<5> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_BindServiceReply : public ::protozero::CppMessageObj {
+ public:
+  using MethodInfo = IPCFrame_BindServiceReply_MethodInfo;
+  enum FieldNumbers {
+    kSuccessFieldNumber = 1,
+    kServiceIdFieldNumber = 2,
+    kMethodsFieldNumber = 3,
+  };
+
+  IPCFrame_BindServiceReply();
+  ~IPCFrame_BindServiceReply() override;
+  IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept;
+  IPCFrame_BindServiceReply& operator=(IPCFrame_BindServiceReply&&);
+  IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&);
+  IPCFrame_BindServiceReply& operator=(const IPCFrame_BindServiceReply&);
+  bool operator==(const IPCFrame_BindServiceReply&) const;
+  bool operator!=(const IPCFrame_BindServiceReply& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_success() const { return _has_field_[1]; }
+  bool success() const { return success_; }
+  void set_success(bool value) { success_ = value; _has_field_.set(1); }
+
+  bool has_service_id() const { return _has_field_[2]; }
+  uint32_t service_id() const { return service_id_; }
+  void set_service_id(uint32_t value) { service_id_ = value; _has_field_.set(2); }
+
+  const std::vector<IPCFrame_BindServiceReply_MethodInfo>& methods() const { return methods_; }
+  std::vector<IPCFrame_BindServiceReply_MethodInfo>* mutable_methods() { return &methods_; }
+  int methods_size() const;
+  void clear_methods();
+  IPCFrame_BindServiceReply_MethodInfo* add_methods();
+
+ private:
+  bool success_{};
+  uint32_t service_id_{};
+  std::vector<IPCFrame_BindServiceReply_MethodInfo> methods_;
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<4> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_BindServiceReply_MethodInfo : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kIdFieldNumber = 1,
+    kNameFieldNumber = 2,
+  };
+
+  IPCFrame_BindServiceReply_MethodInfo();
+  ~IPCFrame_BindServiceReply_MethodInfo() override;
+  IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept;
+  IPCFrame_BindServiceReply_MethodInfo& operator=(IPCFrame_BindServiceReply_MethodInfo&&);
+  IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&);
+  IPCFrame_BindServiceReply_MethodInfo& operator=(const IPCFrame_BindServiceReply_MethodInfo&);
+  bool operator==(const IPCFrame_BindServiceReply_MethodInfo&) const;
+  bool operator!=(const IPCFrame_BindServiceReply_MethodInfo& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_id() const { return _has_field_[1]; }
+  uint32_t id() const { return id_; }
+  void set_id(uint32_t value) { id_ = value; _has_field_.set(1); }
+
+  bool has_name() const { return _has_field_[2]; }
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
+
+ private:
+  uint32_t id_{};
+  std::string name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<3> _has_field_{};
+};
+
+
+class PERFETTO_EXPORT_COMPONENT IPCFrame_BindService : public ::protozero::CppMessageObj {
+ public:
+  enum FieldNumbers {
+    kServiceNameFieldNumber = 1,
+  };
+
+  IPCFrame_BindService();
+  ~IPCFrame_BindService() override;
+  IPCFrame_BindService(IPCFrame_BindService&&) noexcept;
+  IPCFrame_BindService& operator=(IPCFrame_BindService&&);
+  IPCFrame_BindService(const IPCFrame_BindService&);
+  IPCFrame_BindService& operator=(const IPCFrame_BindService&);
+  bool operator==(const IPCFrame_BindService&) const;
+  bool operator!=(const IPCFrame_BindService& other) const { return !(*this == other); }
+
+  bool ParseFromArray(const void*, size_t) override;
+  std::string SerializeAsString() const override;
+  std::vector<uint8_t> SerializeAsArray() const override;
+  void Serialize(::protozero::Message*) const;
+
+  bool has_service_name() const { return _has_field_[1]; }
+  const std::string& service_name() const { return service_name_; }
+  void set_service_name(const std::string& value) { service_name_ = value; _has_field_.set(1); }
+
+ private:
+  std::string service_name_{};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+
+  std::bitset<2> _has_field_{};
+};
+
+}  // namespace perfetto
+}  // namespace protos
+}  // namespace gen
+
+#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
+// gen_amalgamated begin header: include/perfetto/protozero/gen_field_helpers.h
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_GEN_FIELD_HELPERS_H_
+#define INCLUDE_PERFETTO_PROTOZERO_GEN_FIELD_HELPERS_H_
+
+// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
+
+namespace protozero {
+namespace internal {
+namespace gen_helpers {
+
+// This file implements some helpers used by the protobuf generated code in the
+// .gen.cc files.
+//
+// The .gen.cc generated protobuf implementation (as opposed to the .pbzero.h
+// implementation) is not zero-copy and is not supposed to be used in fast
+// paths, so most of these helpers are designed to reduce binary size.
+
+void DeserializeString(const protozero::Field& field, std::string* dst);
+
+// Read packed repeated elements (serialized as `wire_type`) from `field` into
+// the `*dst` vector. Returns false if some bytes of `field` could not be
+// interpreted correctly as `wire_type`.
+template <proto_utils::ProtoWireType wire_type, typename CppType>
+bool DeserializePackedRepeated(const protozero::Field& field,
+                               std::vector<CppType>* dst) {
+  bool parse_error = false;
+  for (::protozero::PackedRepeatedFieldIterator<wire_type, CppType> rep(
+           field.data(), field.size(), &parse_error);
+       rep; ++rep) {
+    dst->emplace_back(*rep);
+  }
+  return !parse_error;
+}
+
+extern template bool
+DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, uint64_t>(
+    const protozero::Field& field,
+    std::vector<uint64_t>* dst);
+
+extern template bool
+DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, int64_t>(
+    const protozero::Field& field,
+    std::vector<int64_t>* dst);
+
+extern template bool
+DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, uint32_t>(
+    const protozero::Field& field,
+    std::vector<uint32_t>* dst);
+
+extern template bool
+DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt, int32_t>(
+    const protozero::Field& field,
+    std::vector<int32_t>* dst);
+
+// Serializers for different type of fields
+
+void SerializeTinyVarInt(uint32_t field_id, bool value, Message* msg);
+
+template <typename T>
+void SerializeExtendedVarInt(uint32_t field_id, T value, Message* msg) {
+  msg->AppendVarInt(field_id, value);
+}
+
+extern template void SerializeExtendedVarInt<uint64_t>(uint32_t field_id,
+                                                       uint64_t value,
+                                                       Message* msg);
+
+extern template void SerializeExtendedVarInt<uint32_t>(uint32_t field_id,
+                                                       uint32_t value,
+                                                       Message* msg);
+
+template <typename T>
+void SerializeVarInt(uint32_t field_id, T value, Message* msg) {
+  SerializeExtendedVarInt(
+      field_id, proto_utils::ExtendValueForVarIntSerialization(value), msg);
+}
+
+template <typename T>
+void SerializeSignedVarInt(uint32_t field_id, T value, Message* msg) {
+  SerializeVarInt(field_id, proto_utils::ZigZagEncode(value), msg);
+}
+
+template <typename T>
+void SerializeFixed(uint32_t field_id, T value, Message* msg) {
+  msg->AppendFixed(field_id, value);
+}
+
+extern template void SerializeFixed<double>(uint32_t field_id,
+                                            double value,
+                                            Message* msg);
+
+extern template void SerializeFixed<float>(uint32_t field_id,
+                                           float value,
+                                           Message* msg);
+
+extern template void SerializeFixed<uint64_t>(uint32_t field_id,
+                                              uint64_t value,
+                                              Message* msg);
+
+extern template void SerializeFixed<int64_t>(uint32_t field_id,
+                                             int64_t value,
+                                             Message* msg);
+
+extern template void SerializeFixed<uint32_t>(uint32_t field_id,
+                                              uint32_t value,
+                                              Message* msg);
+
+extern template void SerializeFixed<int32_t>(uint32_t field_id,
+                                             int32_t value,
+                                             Message* msg);
+
+void SerializeString(uint32_t field_id, const std::string& value, Message* msg);
+
+void SerializeUnknownFields(const std::string& unknown_fields, Message* msg);
+
+// Wrapper around HeapBuffered that avoids inlining.
+class MessageSerializer {
+ public:
+  MessageSerializer();
+  ~MessageSerializer();
+
+  Message* get() { return msg_.get(); }
+  std::vector<uint8_t> SerializeAsArray();
+  std::string SerializeAsString();
+
+ private:
+  HeapBuffered<Message> msg_;
+};
+
+// Wrapper about operator==() which reduces the binary size of generated protos.
+// This is needed because std::string's operator== is inlined aggressively (even
+// when optimizing for size). Having this layer of indirection with removes the
+// overhead.
+template <typename T>
+bool EqualsField(const T& a, const T& b) {
+  return a == b;
+}
+extern template bool EqualsField<std::string>(const std::string&,
+                                              const std::string&);
+
+}  // namespace gen_helpers
+}  // namespace internal
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_GEN_FIELD_HELPERS_H_
+// gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_null_delegate.h
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
+#define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
+
+#include <memory>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/base/logging.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace protozero {
+
+class PERFETTO_EXPORT_COMPONENT ScatteredStreamWriterNullDelegate
+    : public ScatteredStreamWriter::Delegate {
+ public:
+  explicit ScatteredStreamWriterNullDelegate(size_t chunk_size);
+  ~ScatteredStreamWriterNullDelegate() override;
+
+  // protozero::ScatteredStreamWriter::Delegate implementation.
+  ContiguousMemoryRange GetNewBuffer() override;
+
+ private:
+  const size_t chunk_size_;
+  std::unique_ptr<uint8_t[]> chunk_;
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
+// gen_amalgamated begin header: include/perfetto/protozero/static_buffer.h
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
+#define INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+// gen_amalgamated expanded: #include "perfetto/base/export.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
+// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
+
+namespace protozero {
+
+class Message;
+
+// A simple implementation of ScatteredStreamWriter::Delegate backed by a
+// fixed-size buffer. It doesn't support expansion. The caller needs to ensure
+// to never write more than the size of the buffer. Will CHECK() otherwise.
+class PERFETTO_EXPORT_COMPONENT StaticBufferDelegate
+    : public ScatteredStreamWriter::Delegate {
+ public:
+  StaticBufferDelegate(uint8_t* buf, size_t len) : range_{buf, buf + len} {}
+  ~StaticBufferDelegate() override;
+
+  // ScatteredStreamWriter::Delegate implementation.
+  ContiguousMemoryRange GetNewBuffer() override;
+
+  ContiguousMemoryRange const range_;
+  bool get_new_buffer_called_once_ = false;
+};
+
+// Helper function to create protozero messages backed by a fixed-size buffer
+// in one line. You can write:
+//   protozero::Static<protozero::MyMessage> msg(buf.data(), buf.size());
+//   msg->set_stuff(...);
+//   size_t bytes_encoded = msg.Finalize();
+template <typename T /* protozero::Message */>
+class StaticBuffered {
+ public:
+  StaticBuffered(void* buf, size_t len)
+      : delegate_(reinterpret_cast<uint8_t*>(buf), len), writer_(&delegate_) {
+    msg_.Reset(&writer_);
+  }
+
+  // This can't be neither copied nor moved because Message hands out pointers
+  // to itself when creating submessages.
+  StaticBuffered(const StaticBuffered&) = delete;
+  StaticBuffered& operator=(const StaticBuffered&) = delete;
+  StaticBuffered(StaticBuffered&&) = delete;
+  StaticBuffered& operator=(StaticBuffered&&) = delete;
+
+  T* get() { return &msg_; }
+  T* operator->() { return &msg_; }
+
+  // The lack of a size() method is deliberate. It's to prevent that one
+  // accidentally calls size() before Finalize().
+
+  // Returns the number of encoded bytes (<= the size passed in the ctor).
+  size_t Finalize() {
+    msg_.Finalize();
+    return static_cast<size_t>(writer_.write_ptr() - delegate_.range_.begin);
+  }
+
+ private:
+  StaticBufferDelegate delegate_;
+  ScatteredStreamWriter writer_;
+  RootMessage<T> msg_;
+};
+
+// Helper function to create stack-based protozero messages in one line.
+// You can write:
+//   protozero::StackBuffered<protozero::MyMessage, 16> msg;
+//   msg->set_stuff(...);
+//   size_t bytes_encoded = msg.Finalize();
+template <typename T /* protozero::Message */, size_t N>
+class StackBuffered : public StaticBuffered<T> {
+ public:
+  StackBuffered() : StaticBuffered<T>(&buf_[0], N) {}
+
+ private:
+  uint8_t buf_[N];  // Deliberately not initialized.
+};
+
+}  // namespace protozero
+
+#endif  // INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
+
